Pregunta

Estoy haciendo que un microcontrolador 8051 se comunique de forma inalámbrica con una computadora. El microcontrolador enviará una cadena a su puerto serie (DB9) y la computadora recibirá esta cadena y la manipulará.

Mi problema es que no sé cómo hacer que el 8051 transmita la cadena solo una vez. Como necesito manipular la cadena en el extremo de la PC, solo se debe recibir una vez. Actualmente, aunque en el código C estoy enviando la cadena una vez, en mi computadora recibo la misma cadena continuamente. Supongo que esto se debe a que lo que esté en el SBUF se transmite continuamente. ¿Hay alguna manera de que pueda enviar mi cadena solo una vez? ¿Hay alguna manera de vaciar el SBUF?

Traté de usar el pin RTS (Solicitud de envío) (7mo pin) en el DB9 porque leí en alguna parte que si negaba el voltaje en ese pin, detendría el flujo de datos al puerto serie. Entonces, lo que hice fue programar mi microcontrolador para enviar la cadena y luego enviar el nivel lógico 0 a un pin de salida que estaba conectado a mi pin DB9 RTS. Sin embargo, eso no funcionó.

¿Alguien tiene alguna sugerencia? Realmente los agradecería.

EDITAR

El software que estoy usando en la PC es X-CTU para módulos Xbee. Este es el código en mi microcontrolador:

include reg51.h 
void SerTx(unsigned char);  
void main(void)  
{  
  TMOD = 0x20;  
  TH1 = 0xFD;  
  SCON = 0x50;  
  TR1 = 1;   

  SerTx('O');  
  SerTx('N');  
  SerTx('L');  
  SerTx('Y'); 

}

void SerTx(unsigned char x)  
{  
  SBUF = x;  
  while(TI==0);   
  TI = 0;   
}  

¿Podría alguien verificar que, de hecho, solo está enviando la cadena una vez?

EDITAR

Parece que Steve, Brookesmoses y Neil dieron en el clavo cuando dijeron que era lo que estaba sucediendo DESPUÉS de mi función principal que estaba causando el problema. Acabo de probar el código sugerido por Steve (más específicamente el for (;;); y definir serTX fuera de main) y funcionó perfectamente. El controlador probablemente se reinicia y, por lo tanto, el mismo código sigue repitiéndose.

¡Muchas gracias por la ayuda! :)

¿Fue útil?

Solución

¿Puede confirmar que el 8051 realmente está enviando los datos solo una vez? Una forma de verificar sería usar un visor para ver qué está sucediendo en el pin TX de UART.

¿Qué software estás usando en la PC? Sugeriría usar un software de comunicaciones simple como HyperTerminal o PuTTY . Si muestran la cadena que se envía a la PC varias veces, entonces es probable que la falla esté en el software que se ejecuta en el 8051.

EDITAR: Para ser honesto, esto suena como el tipo de depuración que los ingenieros tienen que enfrentar regularmente, por lo que es una buena oportunidad para que practiques un buen problema metódico a la antigua. resolviendo.

Si puedo ser muy directo, le sugiero que haga lo siguiente:

  1. Depuración. Pruebe cosas, pero no adivine . Experimentar. Haga pequeños cambios en su código y vea qué sucede. Prueba todo lo que se te ocurra. Busque en la web para obtener más información.
  2. Si eso no produce una solución, regrese aquí y proporciónenos toda la información que necesitamos. Eso incluye partes relevantes del código, detalles completos del hardware que está utilizando e información sobre lo que intentó en el paso 1.

EDITAR: no tengo el representante para editar la pregunta, así que aquí está el código publicado por el OP en el comentario a su pregunta:

#include<reg51.h>

void SerTx(unsigned char);

void main(void)
{
    TMOD = 0x20; TH1 = 0xFD; SCON = 0x50; TR1 = 1;
    SerTx('O'); SerTx('N'); SerTx('L'); SerTx('Y');

    void SerTx(unsigned char x)
        { SBUF = x; while(TI==0); TI = 0; } 
}

Como Neil y Brooksmoses mencionan en sus respuestas, en un sistema embebido, la función principal nunca puede terminar. Por lo tanto, debe colocar su código en un bucle infinito (que puede ser lo que está sucediendo inadvertidamente) o agregar un bucle infinito al final, para que el programa se detenga efectivamente.

Además, la función SerTx debe definirse fuera de main. Esto puede ser sintácticamente correcto, pero mantiene las cosas simples y no declara funciones dentro de otras funciones.

Intente esto (también he agregado algunos comentarios en un intento de hacer que el código sea más fácil de entender):

#include<reg51.h>

void SerTx(unsigned char);

void main(void)
{
    /* Initialise (need to add more explanation as to what
        each line means, perhaps by replacing these "magic
        numbers" with some #defines) */
    TMOD = 0x20;
    TH1  = 0xFD;
    SCON = 0x50;
    TR1  = 1;

    /* Transmit data */
    SerTx('O'); SerTx('N'); SerTx('L'); SerTx('Y');

    /* Stay here forever */
    for(;;) {}

}

void SerTx(unsigned char x)
{
    /* Transmit byte */
    SBUF = x;

    /* Wait for byte to be transmitted */
    while(TI==0) {}

    /* Clear transmit interrupt flag */
    TI = 0;
} 

Otros consejos

El código que publicó no tiene bucle en main (), por lo que debe determinar qué hace el tiempo de ejecución C de su compilador cuando main () regresa después de enviar 'Y'. Dado su problema, imagino que el compilador genera un código para hacer una limpieza y luego reiniciar el micro (tal vez un reinicio de hardware, tal vez solo reinicie el tiempo de ejecución de C). Parece que su programa funciona exactamente como lo escribió, pero ha ignorado lo que sucede antes y después de que se llame a main ().

Si desea que su cadena se envíe una vez y solo una vez, entonces necesita algo como while (1) {} agregado después del envío del último carácter. Pero, entonces su programa no está haciendo nada: solo ejecutará un bucle vacío para siempre. Se necesita un reinicio (como el ciclo de energía) para comenzar de nuevo y enviar la cadena.

Tenga en cuenta que si su micro tiene un temporizador de vigilancia, podría intervenir y forzar un reinicio inesperado. Si esto sucede, su cadena se enviará una vez por cada reinicio de watchdog (que podría ser algo así como una vez por segundo, con la velocidad dependiendo de su hardware).

Además, tener serTx () definido anidado dentro de main () probablemente no sea lo que desea.

Es difícil decir cuál es el problema sin ver el código 8051. Por ejemplo, un error lógico en ese lado podría hacer que los datos se envíen varias veces, o el software 8051 podría estar esperando un ACK que nunca se recibe, etc.

Normalmente, en un código 8051 tiene que enviar explícitamente cada carácter, pero supongo que el tiempo de ejecución de C se encarga de esto.

El uso de RTS / CTS (Solicitud para enviar / Borrar para enviar) es para el control de flujo (es decir, para evitar desbordamientos del búfer: los búferes suelen ser bastante pequeños en estos microcontroladores) y no detener la transmisión por completo.

Haciéndose eco de la respuesta de Neil (en una respuesta, ya que aún no tengo el representante para comentar): en una situación típica de microcontrolador sin un sistema operativo, no está claro de inmediato cuál es la función de salida () que se llama implícitamente al final of main () debería hacer, o más exactamente, no puede hacer lo habitual " finalizar el programa y volver al sistema operativo " ;, porque no hay sistema operativo al que volver.

Además, en una aplicación real, casi nunca desea que el programa se detenga, a menos que apague el sistema. Entonces, una cosa que la implementación de exit () definitivamente no debería hacer es ocupar mucho espacio en el código.

En algunos sistemas en los que he trabajado, exit () no está implementado en absoluto; si no lo va a usar, ¡no desperdicie ni un byte! El resultado es que cuando la ruta de ejecución llega al final de main (), el chip simplemente se desvía hacia una zona de ejecución de lo que sea que esté en el siguiente bit de memoria, y normalmente termina atascado en un bucle o fallar con un código de operación ilegal. Y el resultado habitual de una falla con un código de operación ilegal es ... reiniciar el chip.

Eso parece una teoría plausible de lo que está sucediendo aquí.

Este artículo en particular es para ensamblar, no C, pero puede resultar útil: http://www.8052.com/tutser.phtml

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top