Tasa de baudios para microcontrolador 8051

Me gustaría saber si una tasa de baudios de 9600 es tan rápida para una MCU 8051 usando un cristal de 11.0952Mhz. ¿Por qué? He observado cierta inconsistencia en el comportamiento de mi MCU, ya que cuando envío un conjunto de caracteres en busca de un carácter en particular para realizar ciertas operaciones, descubro que mi MCU no realiza la operación requerida. Lo que significa que hubo un extravío a lo largo de la línea durante la recepción. Luego hice una rutina en serie. Envié un "ABC" desde la terminal a la MCU, que debería transmitir a la terminal un incremento de cada carácter enviado, por lo tanto, debería dar "BCD". Pero esto es lo que obtuve constantemente: "BD" falta "C". Lo que significa que la MCU se perdió "B". También envío otro conjunto de personajes y descubrí que la MCU no detecta algunos personajes. Cuál podría ser la causa de esto. ¿Podría ser la tasa de baudios o en mi código? ¿Cómo puedo rectificar esto?

Aquí está el código.

void initUART()
{
  SCON = 0x50;
  TMOD = 0x20;
  TH1 = TL1 =-3;
  TR1 = 1;
}

void sendCHAR()
{
  SBUF = uartBUFF[s];
  while(!TI);
  TI=0;
}

void serial_isr(void) interrupt 4  
{
  if (RI)
  {
    RI = 0;
    tmpBUFF = SBUF;
    charFLAG=1;
  }
}

main()
{
  IE= 0x91;
  initUART();
  while (1)
  {
    if(charFLAG)
    {
      SBUF = (tmpBUFF+1);
      while(!TI);
      TI=0;
      charFLAG = 0;
    }
  }
}

¡Gracias!

¿Puedes publicar tu código fuente/ensamblado?
Por favor, vea el archivo fuente a continuación
¿No puedo ver ninguna fuente? Podrías editarlo en tu pregunta.
void initUART() { SCON = 0x50;TMOD = 0x20; TH1 = TL1 =-3;TR1 = 1; } void enviarCHAR() { SBUF = uartBUFF[s]; mientras(!TI); TI=0; } void serial_isr(void) interrupción 4 { if (RI) {RI = 0; tmpBUFF = SBUF; charFLAG=1;} } principal() { IE= 0x91; inicialUART(); while (1) { if(charFLAG) { SBUF = (tmpBUFF+1); mientras(!TI); TI=0; charBANDERA = 0; } } }

Respuestas (2)

¿Cómo se obtienen los caracteres del registro del búfer del puerto serie? Si simplemente los lee en un bucle como

void main() {       
  char c;
  while (1) {
    c=SBUF;
    do_something(c);
  }
}

Entonces perderá caracteres una vez que el tiempo de ejecución de do_something() se alargue. Tenga en cuenta que esto incluye el tiempo dedicado a las interrupciones. El puerto serie 8051 no tiene fifos de hardware, un carácter será sobrescrito por el siguiente si no fue leído a tiempo.

Nuestra solución fue leer los caracteres en un Ringbuffer durante la interrupción en serie y usar el FIFO en el bucle principal. Funciona (con interrupción de alta prioridad) para 460800 Baud con cristal de 7,3728 MHz en un Silabs 80C51FXXX.

Actualizar

Como ahora vemos el código fuente, el error ahora está claro: esperas en el bucle principal a que se envíe tu personaje. Pero eso significa que espera un "tiempo de carácter" completo sin poder leer su búfer de carácter de interrupción, y otros pocos ciclos para detectar y leer el siguiente. Esto es demasiado largo si el remitente envía los caracteres rápido, como lo hace una PC.

void initUART() { SCON = 0x50;TMOD = 0x20; TH1 = TL1 =-3;TR1 = 1; } void enviarCHAR() { SBUF = uartBUFF[s]; mientras(!TI); TI=0; } void serial_isr(void) interrupción 4 { if (RI) {RI = 0; tmpBUFF = SBUF; charFLAG=1;} } principal() { IE= 0x91; inicialUART(); while (1) { if(charFLAG) { SBUF = (tmpBUFF+1); mientras(!TI); TI=0; charBANDERA = 0; } } }
Mirando el código del póster original, tienes razón, necesita un búfer de anillo. Aquí hay uno que Google lanzó 8052.com/codelib/files/efdUartDriver.zip
Actualicé mi respuesta como pregunta ahora contiene código.
Lo tengo resuelto. Simplemente apliqué las sugerencias de "tubor J" (quien contribuyó anteriormente) y funcionó bien. Solo asegúrese de guardar toda la información cuando la comunicación en serie esté en marcha, en un búfer. Luego, después, haga uso de las variables en el búfer. Esto evita que se pierdan caracteres. ¡Gracias a todos!
Vale la pena señalar que con muchos UART de microcontroladores, es posible que no sea posible enviar un byte por cada byte que llega en un flujo continuo. Si el remitente original envía un flujo de datos absolutamente continuo con exactamente un bit de parada por byte, pero la velocidad de reloj del controlador es un 0,01 % más lenta, eventualmente perderá datos a menos que tenga un medio para enviar datos con solo 0,999 bits de parada en lugar de un bit de parada completa. La diferencia entre 1 bit de parada y 0,999 puede parecer trivial, pero puede sumarse. Si un controlador tuviera un control de velocidad en baudios más preciso...
... uno podría simplemente asegurarse de que el reloj de baudios del controlador fuera un poco (por ejemplo, 0,1%) más rápido que el del dispositivo de envío; esta técnica es utilizada por módems de 1200 baudios (que, si mal no recuerdo, intercambian datos a algo así como 1202 bits/segundo), pero el 8051 no es capaz de hacerlo bien. Uno podría ser capaz de simular tal comportamiento si de vez en cuando deshabilita las interrupciones, establece brevemente la velocidad en baudios del UART un poco más rápido y vuelve a hacerlo más lento, y vuelve a habilitar las interrupciones (de modo que cada operación de este tipo avance los bloques de bits del UART en una fracción de bit). ).

Con un cristal de 11,0952 MHz, la tasa de bits máxima para el 8051 es de 57600 bps, por lo que ese no debería ser el problema. Además, parece que recibes bien algunos caracteres. Es posible que desee verificar las respuestas a su otra pregunta nuevamente si no está seguro acerca de la tasa de bits.

Es posible que se haya perdido que Paul A. publicó la pregunta que vinculó...
¡Sí! Estoy usando una velocidad de transmisión de 9600. Y estoy seguro de la configuración. Y también recibo algunos caracteres, pero parece que faltan algunos. Aparentemente, la tasa de transferencia del carácter es más rápida para que el microcontrolador la reciba mientras aún está procesando un carácter recibido anteriormente.
@reemrevnivek - Sí, me lo perdí :-)