Los controladores FIFO ASF y el problema USART avr envían y reciben datos a través de la conexión rs232

0

Estoy trabajando para enviar un fotograma de 8 bytes al microcontrolador Xmega128a1 (a través de RS485). El marco se ve así:

{header1,header2,CMD,D1,D2,D3,D4,CRC}

Por ejemplo:

{0x55,0xaa,0xFF,0x59,0xfd,0x64,0x68,0x32}

El microcontrolador tiene que reenviar el marco de nuevo a la PC, si es "correcto". La trama recibida es correcta si el encabezado es {0x55,0xaa}.

Utilicé controladores ASF para USART, TEMPORIZADOR, E / S, CPU y PMIC. También agregué sistemas de bloqueo fifo, gpio, c y IOport.

El puerto serie ISR levanta una bandera cada nuevo byte ( new_byte_resived_flag ). En el bucle while, agrego cada nuevo byte a una matriz de 8 bytes Rx_buf_F0 (que representan el marco recibido). Cuando se completa la trama recibida, establezco un indicador frame_completed_flag en 1. Además, en el bucle while hago una verificación de si la trama es correcta o no. Si lo es, entonces lo envío de vuelta a la PC.

El indicador de muestreo se eleva cada 50 ms para asignar el marco de datos correcto recibido a variables como CMD, datos [i], i = 3,4,5,6.

El problema es: cuando envío un marco al microcontrolador, a veces responde pero no con el marco correcto.

El puerto serie está funcionando bien, pero creo que tengo problemas para usar los buffers y las funciones fifo de la manera correcta. Mi código:

#include <asf.h>
#include <compiler.h>
#include <sysclk.h>
#include <board.h>
#include <gpio.h>
#include "tc.h"
uint8_t sampling_flag =0;
uint8_t i=0;
uint8_t n=0;
uint8_t CRC=0;
uint8_t flag_rx_Frame_F0=0;
uint8_t new_byte_resived_flag=0;
uint8_t frame_completed_flag=0;
uint8_t fram_recived_correct_flag=0;
fifo_desc_t rx_fifo_F0;
uint8_t Rx_buf_F0[8] = {0x48 , 0x75, 0x73, 0x73,  0x61, 0x6d, 0x59, 0x0d};
static void my_callback(void)
    {

        sampling_flag = 1;
    }


uint8_t rx_buffer[32];
ISR(USARTF0_RXC_vect)
{
    //ioport_set_pin_low(LED1_GPIO);
    uint8_t received_byte;
    //while(i<7){
    received_byte = usart_getchar(&USARTF0);
    //Rx_buf_F0[i] = usart_getchar(&USARTF0);   
    fifo_push_uint8(&rx_fifo_F0, received_byte);
    //if(fifo_get_used_size(&fifo_desc) == 0) break;          
    new_byte_resived_flag=1;
    //fifo_push_uint8(&rx_fifo_F0, received_byte);
    usart_clear_rx_complete(&USARTF0);
 }
 uint8_t  CMD;

 uint8_t data[4] = {0x00 , 0x00, 0x00, 0x00};


int main (void)
{
    /* Insert system clock initialization code here (sysclk_init()). */
    board_init();
    sysclk_init();

      /////////////////////////////////////////////////////////////////////////////////////tIMER C0 INIT
     tc_enable(&TCC0);
     tc_set_overflow_interrupt_callback(&TCC0, my_callback);
     tc_set_wgm(&TCC0, TC_WG_NORMAL);
     tc_set_overflow_interrupt_level(&TCC0, TC_INT_LVL_LO);
     tc_write_period(&TCC0, 25000);
     tc_write_clock_source(&TCC0, TC_CLKSEL_DIV64_gc);
//////////////////////////////////////////////////////////////////////////

/////////////////////////////////////////////////////////////////////////////////////USART RS232 MODE INIT
     static usart_rs232_options_t USART_SERIAL_OPTIONS = {
         .baudrate = 38400,
         .charlength = USART_CHSIZE_8BIT_gc,
         .paritytype = USART_PMODE_DISABLED_gc,
        .stopbits = true
     };
/////////////////////////////////////


///////// Initialize usart driver in RS232 mode
      usart_init_rs232(&USARTF0, &USART_SERIAL_OPTIONS);
      sysclk_enable_module(SYSCLK_PORT_F, PR_USART0_bm);
      PORTF.DIRSET = PIN3_bm;
      usart_set_rx_interrupt_level(&USARTF0, USART_INT_LVL_HI);
      fifo_init(&rx_fifo_F0, rx_buffer, 32);

     pmic_init();
     cpu_irq_enable();

     while (1)
     {


     if(new_byte_resived_flag==1)
     {
        new_byte_resived_flag=0;
        i++;
       Rx_buf_F0[i]=fifo_pull_uint8_nocheck(&rx_fifo_F0);
       if(i==7)
       {
          frame_completed_flag=1;
         i=0;
       }
     }


     if (frame_completed_flag==1)
         {
              frame_completed_flag=0;

                if (Rx_buf_F0[0]==0x55 && Rx_buf_F0[1]==0xaa )
                 {

                         for (int j = 0; j < 7; j++)
                         {
                             usart_putchar(&USARTF0, Rx_buf_F0[j]);
                          }
                          fram_recived_correct_flag=1;
                  }

       }

     if (sampling_flag==1)
          {
              sampling_flag=0;
                           if ( fram_recived_correct_flag==1)
          {
               fram_recived_correct_flag=0;

               CMD=Rx_buf_F0[2];
               for(int k=3;k<7;k++)
               data[k]=Rx_buf_F0[k];
               CRC= Rx_buf_F0[7];
               for (int j = 0; j < 7; j++)
                       {
                        Rx_buf_F0[j]='
{header1,header2,CMD,D1,D2,D3,D4,CRC}
'; } } } }//end of while(1) }//end of main
    
pregunta shams alsham

1 respuesta

2

Algunos errores:

  • Las matrices en C comienzan en el índice cero. Escribe en el índice 1 a 8, en lugar de 0 a 7:

    i++;
    Rx_buf_F0[i] = ...
    
  • Debe declarar todas las variables compartidas entre main y ISR volatile para proteger contra optimizaciones incorrectas del compilador. Además, parece que no tienes semáforos para proteger a rx_fifo_F0 . Los accesos a esa variable no serán atómicos, por lo tanto, si no tiene semáforos, obtendrá errores intermitentes en los que de repente aparece basura aleatoria en esa variable.

  • data tiene un tamaño de 4 bytes, pero usted escribe en el índice 3 a 7.

    for(int k=3;k<7;k++)
    data[k]=Rx_buf_F0[k];
    

Podría ser más, pero estos son todos errores graves.

    
respondido por el Lundin

Lea otras preguntas en las etiquetas