Как отправить несколько данных портов через UART? - PullRequest
1 голос
/ 10 апреля 2019

Я изменил код для приемника, но передатчик почти такой же, поэтому в приемнике я отменил прерывание и вместо этого я читаю данные в цикле, где я каждый раз проверяю состояние RC2IF_bit и проверка выполняется в том же порядке, когда передатчик отправляет данные, чтобы убедиться, какой порт отправляет данные. Проблема в симуляции на протеусе, когда я получаю данные и выводю их на светодиоды, они работают нормально, и данные отправляются правильно, но в середине симуляции, когда я смотрю это, я обнаружил, что они меняют состояния на первый взгляд, например, если я отправляю PORTA = 0X2D Я получаю то же значение и включаю нужные светодиоды, но на секунду они выключаются, затем снова включаются, это проблема в написанном коде.

 /*This is the transmitter code*/
void UART2_TX_init ();      //UART2 transmission initialization function porototype
void SEND_data (int output);     //Send data function prototype


void main()
{
     ANSELA = 0X00;        //Disable analogue function on PORTA
     ANSELE = 0X00;        //Disable analogue function on PORTE
     ANSELF = 0X00;        //Disable analogue function on PORTF
     TRISA = 0XFF;         // SET PORTA AS INPUT (AUTOMATIC BUTTONS)
     TRISB = 0XFF;         //SET PORTB AS INPUT (OFF BUTTONS)
     TRISD = 0XFF;         //SET PORTD AS INPUT (MANUAL BUTTONS)
     TRISE = 0XFF;         //SET PORTE AS INPUT (HIGH BUTTONS)
     TRISF = 0XFF;         //SET PORTF AS INPUT (LOW BUTTONS)
     TRISC = 0XFF;         //SET PORTC AS INPUT (TRIP BUTTONS)
     TRISG0_bit = 0;    //set PORTC pin0 as output for MAX487 DE pin
     PORTG.F0= 1;      //set PORTC pin0 HIGH , set    MAX487 as transmitter.
     UART2_TX_init();      //call UART1 transmission initialization

     while (1)
     {
                SEND_data(PORTA);   //send data of automatic
                delay_ms(10);
               SEND_data(PORTB);    //send data of off
               delay_ms(10);
               SEND_data(PORTD);    //send daata of manual
               delay_ms(10);
               SEND_data(PORTE);   //send data of high
               delay_ms(10);
               SEND_data(PORTF);   //send data of low
               delay_ms(10);
               SEND_data(PORTC);   //send data of TRIP
               delay_ms(10);
    }
}

 /*This function takes the data needed to be send
   as an integer. Wait for the TSR to be empty and
   start the transmission*/

void SEND_data (int output)
{
         while (!TRMT_TX2STA_bit){};    //checks if TSR is empty or not if empty TRMT_BIT is set and write to transmit register
         TX2REG = output;        //write data to be send in the transmission register

}




/*This function initializes the UART2 as an asynchronous
 transmitter at a baud rate of 9600kbps*/

void UART2_TX_init ()
{
    BAUD2CON = 0X08;
    BRGH_TX2STA_bit = 1;
    SP2BRGL = 207;
    SYNC_TX2STA_bit = 0X00;
    SPEN_RC2STA_bit = 0X01;
    TRISG1_bit = 0X01;
    TRISG2_bit = 0X01;
    TXEN_TX2STA_bit = 0X01;

}




/*This is the receiver code*/
void UART2_RX_init ();   // Receiver initialization function prototype
void main()
{

     ANSELA = 0X00;       // Disable analog function on PORTA
     ANSELE = 0X00;       // Disable analog function on PORTE
     ANSELF = 0X00;       // Disable analog function on PORTF
     TRISA = 0X00;        //set PORTA as output
     TRISB = 0X00;        //set PORTB as output
     TRISD = 0X00;        //set PORTD as output
     TRISE = 0X00;        //set PORTE as output
     TRISF = 0X00;        //set PORTF as output
     TRISC = 0X00;        //set PORTF as output
     PORTA = 0x00;        //clear PORTA
     PORTB = 0x00;        //clear PORTB
     PORTD = 0x00;        //clear PORTD
     PORTE = 0x00;        //clear PORTE
     PORTF = 0x00;        //clear PORTF
     PORTC = 0x00;        //clear PORTC
     TRISG0_bit = 0x00;   //set PORTC pin0 as output for MAX487 RE pin
     PORTG.F0 = 0x00;     // set PORTC pin0 as LOW , set MAX487 as receiver
     UART2_RX_init();     //call receiver initialization function
     while (1)
     {
             while (!RC2IF_bit) ;      //check if the RCIF flag is up to tell if there is a new data
             PORTA =~ RC2REG;          //write the new data to the specified port
             while (!RC2IF_bit) ;
             PORTB =~ RC2REG;
             while (!RC2IF_bit) ;
             PORTD =~ RC2REG;
             while (!RC2IF_bit) ;
             PORTE =~ RC2REG;
             while (!RC2IF_bit) ;
             PORTF =~ RC2REG;
             while (!RC2IF_bit) ;
             PORTC =~ RC2REG;
     }


}
/*This function initializes UART2 as an asynchronous
  receiver at a baud rate of 9600kbps with continous
  reception NO INTERRUPT ON RECEIVE*/
void UART2_RX_init ()
{
    BAUD2CON = 0X08;
    BRGH_TX2STA_bit = 1;
    SP2BRGL = 207;
    SYNC_TX2STA_bit = 0X00;
    SPEN_RC2STA_bit = 0X01;
    TRISG1_bit = 0X01;
    TRISG2_bit = 0X01;
    CREN_RC2STA_bit = 0X01;
}

Ответы [ 2 ]

2 голосов
/ 10 апреля 2019

Прежде всего я хочу сказать несколько слов о дизайне протокола.Любой протокол связи, если вы хотите, чтобы он был надежным, должен реализовывать как минимум две вещи: синхронизацию кадров и проверку ошибок.Хорошо, есть несколько специализированных протоколов, которые не используют кадры и представляют данные как непрерывный поток, но это определенно не ваш случай.Поэтому, если вы не хотите возиться со странными ошибками, я настоятельно рекомендую вам реализовать эти вещи.

Теперь о вашем коде.Похоже, GET_data ждет, пока регистр передачи не будет пустым, и записывает в него один байт.Я не вижу в этом ничего плохого.Но ваш приемник выглядит подозрительно.Вы ждете установки флага RCIF и затем читаете 5 раз из регистра ввода RCREG.Но не ноль RCIF означает, что вы получили один байт.Вы не можете ждать RCIF один раз, а затем читать из RCREG несколько раз.Вам следует подождать RCIF до каждого чтения из RCREG.

Я был бы рад привести вам пример рабочего кода, но я не могу придуматьпростое решение, которое будет соответствовать вашей нынешней архитектуре.Я могу привести пример того, как сделать это правильно, но это будет выглядеть совершенно иначе.

1 голос
/ 11 апреля 2019

Некоторые вещи:

  • ISR для получения UART должен быть как можно короче и просто записывать данные в буфер и не содержать никаких процедур задержки.
  • использовать один прерывание для каждого полученного байта.
  • начните свой кадр с начального байта. например, 'S'
  • завершить ваш кадр байтом контрольной суммы.
  • сделать portwrite в вашей основной лупе после того, как вы обнаружите полный кадр в вашем буфере (startbyte + databytes + правильная chechsum)
...