Search code examples
interruptpicuartmicrochippic32

Interrupting and using UART


I'm struggling on a project so, here I am.

My problem is sending data via UART. In fact, it's not that the problem because I succeed in sending data thanks to :

 int x=1;
#define var 00000001
        void InitUART()
        {
        mPORTFClearBits(BIT_8);
        TRISFbits.TRISF8=0;        // RF8 output==>TX1
        TRISFbits.TRISF1=1;        // RF1 input==>RX1
        U1STA = 0x1400; // Enable Tx(inv) and Rx
        //U1BRG = 8332; // value = (80000000 / BAUD) - 1 = 9600
        U1MODE = 0x8008; // Enable UART with 1 stop bit, no parity and BRGH
        OpenUART1(UART_EN | UART_BRGH_FOUR, UART_RX_ENABLE | UART_TX_ENABLE,U1BRG(UART1_BAUD) );
        }

int main(void) {

    InitUART;
 while (1)
      {
 x|=var;

              x=x<<1; //=> 0000 0010

               x=x<<1; //=> 0000 0101
               x|=var;

               x=x<<1; //=> 0000 1011
               x|=var;



              x=x<<1; //=> 0001 0110

              x=x<<1; //=> 0010 1101
              x|=var;

              x=x<<1; //=> 0101 1010

              x=x<<1; //=> 1011 0100

                //uart_send_data((BYTE*)x,8);

            U1TXREG=x;
}

And I'm receiving well.

But, Iwant to use a ChangeNotice interrupt. It's code liek this and it works:

void InitISR()
{
        SYSTEMConfig(SYS_FREQ, SYS_CFG_WAIT_STATES | SYS_CFG_PCACHE);
        PORTSetPinsDigitalIn(IOPORT_B, BIT_2);          //RB2 as input for CN4 operation
        mPORTBClearBits(BIT_2);
        mCNOpen(CONFIG, PINS, PULLUPS);
       // mCNClearIntFlag();                            // clear interrupt flag
        temp=mPORTBRead();                              // clear port mismatch
        ConfigIntCN(INTERRUPT);                         // enable CN interrupt
        INTEnableSystemMultiVectoredInt();
        TRISEbits.TRISE0= 1;                //E0 input   // SCL EST BRANCHE EN E0/D0
        TRISEbits.TRISE1= 1;                //E1 input   // SDA EST BRANCHE EN E1/D1
        TRISEbits.TRISE2= 0;                //D2 output
        TRISEbits.TRISE3=0;
        LATEbits.LATE2=0;
        LATEbits.LATE3=0;

}

void __ISR(_CHANGE_NOTICE_VECTOR,ipl6) ChangeNotification_Handler(void)
{   
            LATEbits.LATE2=0; //To know
            LATEbits.LATE2=1; // that interrupt
            LATEbits.LATE2=0; // is working

        if ((mPORTEReadBits(BIT_0))!=0) //Check if clock is high==> sending data
        {
            nbr++;
            SDA=mPORTEReadBits(BIT_1);

                           if (SDA==0)       // data =0?
                          {
                                i=i<<1;
                          }
                    else                // data !=0 ==> 1
                          {
                                i=i<<1;
                                i|=var;
                          }              }
     else
    {
             if (nbr==8) // 8bits=>1byte
            {

                 U1TXREG = i;
                    nbr=0;

            }
             else
             {
             }

    }

    temp=mPORTBReadBits(BIT_2);
    mCNClearIntFlag();

}

But, when I'm doing both, it's sending something, but not at all what I'm looking for, it's sending (in hexa) 000 224 224 000 224 224 00 224 224 000. And instead of receiving byte per byte, I'm receiving 14 bytes per 14 bytes.

So, I though that the UART was bringing interrupt and I tried to disable it by using asm("di");or IEC0bits.U1TXIE=0; or IEC0bits.U1TXIE=0; but without any effects... So, if someone knows why I have this problem, I would be so happy =D

Cheers.


Solution

  • So, I'm posting it for someone who may have the same problem, one day. The problem was just the clock. Even if you have a special quartz, you need to define your system clock. AND, when your system clock is set, you have to define your peripheral clock, yes another one. But be carefull, not all peripheral pins work on the peripheral clock I think.

    So, I have a 48Mhz quartz and my code is here:

      //48Mhz
    //I want SYS_CLOKC=40Mhz
        #pragma config UPLLEN   = OFF   // USB PLL Enabled, OFF si quartz 48 MHz
        #pragma config FPLLIDIV = DIV_12 // PLL Input Divider, il faut obtenir 
                                         //      entre 4 et 5 MHz
        #pragma config FPLLMUL  = MUL_20        // PLL Multiplier
        #pragma config FPLLODIV = DIV_2         // PLL Output Divider
    
    
        // périphérique clock 5Mhz = SYSCLK/FPBDIV
        #pragma config FPBDIV   = DIV_8         // Peripheral Clock divisor
    
    
        // oscillateur : Primary Osc w/PLL (XT+,HS+,EC+PLL)
        #pragma config POSCMOD  = HS            // Primary Oscillator
        #pragma config FNOSC    = PRIPLL        // Oscillator Selection
        #pragma config FWDTEN   = OFF           // Watchdog Timer
        #pragma config CP       = OFF           // Code Protect
    

    48/12=4Mhz

    4*20=80Mhz

    80/2=40Mhz System_CLOCK=40Mhz

    40/8=5Mz Peripheral clock=5Mhz

    For the rest of the code, I can't explain it to you, I found the whole block and it works like this so...