Прерывание и использование UART

Я борюсь за проект, и вот я здесь.

Моя проблема заключается в отправке данных через UART. На самом деле проблема не в этом, потому что мне удается отправлять данные благодаря:

 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;
}

И я получаю хорошо.

Но я хочу использовать прерывание ChangeNotice. Это код, похожий на этот, и он работает:

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();

}

Но когда я делаю и то, и другое, оно отправляет что-то, но не совсем то, что я ищу, оно отправляет (в гекса) 000 224 224 000 224 224 00 224 224 000. И вместо того, чтобы получать байт на байт, я Получаю 14 байтов на 14 байтов.

Итак, я подумал, что UART приносит прерывание, и я попытался отключить его, используя asm("di");или же IEC0bits.U1TXIE=0; или же IEC0bits.U1TXIE=0; но без каких-либо последствий... Так что, если кто-то знает, почему у меня такая проблема, я был бы так счастлив =D

Приветствия.

1 ответ

Решение

Итак, я публикую это для кого-то, у кого может быть та же самая проблема, однажды. Проблема была только в часах. Даже если у вас есть специальный кварц, вам нужно определить системные часы. И, когда ваши системные часы установлены, вы должны определить свои периферийные часы, да еще один. Но будьте осторожны, я думаю, что не все периферийные контакты работают на периферийных часах.

Итак, у меня кварц 48 МГц, и мой код здесь:

  //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 = 4МГц

4*20=80МГц

80/2=40 МГц System_CLOCK=40 МГц

40/8=5 МГц Периферийные часы = 5 МГц

Что касается остального кода, я не могу вам это объяснить, я нашел весь блок, и он работает так, вот так...

Другие вопросы по тегам