Compartir tecnología

Comunicación serie UART para principiantes de 51 microcontroladores

2024-07-12

한어Русский языкEnglishFrançaisIndonesianSanskrit日本語DeutschPortuguêsΕλληνικάespañolItalianoSuomalainenLatina

Publicaciones de blog de otros blogueros de CSDN (para uso personal) Notas de estudio integradas 9-51 Microcontrolador UART Serial Communication_51uart Serial Communication-CSDN Blog

Las publicaciones de blog escritas por otros bloggers de CSDN son bastante buenas. Si desea obtener información sobre el puerto serie UART del microcontrolador 51, puede hacer clic y echar un vistazo:

El nombre completo de UART es Receptor/Transmisor Asíncrono Universal, que es un receptor y transmisor asíncrono universal.

Comunicación asíncronaSignifica que el intervalo de tiempo entre dos caracteres (8 bits) en la comunicación no es fijo, pero el intervalo de tiempo entre bits dentro de un carácter esestable

La comunicación en serie UART es la tecnología de comunicación más utilizada para microcontroladores. Generalmente se usa para la comunicación entre microcontroladores y computadoras y entre microcontroladores.

La comunicación se puede dividir en tipos básicos.comunicación paralelaycomunicación serial, En la comunicación paralela, cada bit de datos se transmite al mismo tiempo y la comunicación se puede realizar en bytes. Sin embargo, múltiples líneas de comunicación ocupan muchos recursos y son costosas. Por ejemplo, P0 = 0xFF usado antes; asigna valores a los 8 puertos IO de P0 al mismo tiempo y emite señales al mismo tiempo, similar a 8 carriles que pueden pasar 8 automóviles al mismo tiempo. Esta forma es paralela. Se acostumbra llamar P0, P1, P2 y P3 a los cuatro conjuntos de buses paralelos del microcontrolador 51.

La comunicación en serie es como un carril, sólo puede pasar un coche a la vez.Si se va a transmitir un byte de datos como 0xFF, suponiendo que un automóvil extraiga datos de 1 bit, entonces se necesitarán más de 8 automóviles.mismo intervalo de tiempoCruce el mismo carril en secuencia.

La diferencia entre comunicación síncrona y comunicación asincrónica:

1. La comunicación síncrona requiere que la frecuencia de reloj del extremo receptor sea consistente con la frecuencia de reloj del extremo emisor, y el extremo emisor envía un flujo de bits continuo. La comunicación asincrónica no requiere sincronización entre el reloj del extremo receptor y el reloj del extremo emisor; Después de que el extremo emisor envía un byte, puede pasar por cualquier intervalo de tiempo largo antes de enviar el siguiente byte.

2. La comunicación síncrona tiene una alta eficiencia, mientras que la comunicación asincrónica tiene baja eficiencia.

3. La comunicación sincrónica es más complicada y el error permitido en los relojes de ambas partes es pequeño. La comunicación asincrónica es simple y los relojes de ambas partes pueden permitir un cierto error.

4. La comunicación síncrona solo es adecuada para punto a multipunto y la comunicación asíncrona se puede utilizar para punto a punto.

El microcontrolador STC89C52 tiene dos pines utilizados específicamente para la comunicación serie UART, uno es P3^0 y el otro es P3^1. También tienen otros nombres llamados RXD (Recibir datos) y TXD (Transmitir datos) respectivamente. ellos se llama interfaz serie. Como se muestra en la imagen:

Comunicación entre microcontrolador y microcontrolador:

En la figura, GND representa la tierra de referencia de la fuente de alimentación del sistema del microcontrolador. TXD se denomina pin de transmisión en serie y RXD es el pin de recepción en serie.

Para comunicarse entre dos microcontroladores, en primer lugar, la referencia de alimentación debe ser la misma, por lo que los GND de los dos microcontroladores deben estar conectados entre sí.Luego, el pin TXD de la MCU 1 se conecta al pin RXD de la MCU 2. La función es que la MCU 1 envía información a la MCU 2. (Este proceso se divide en dos partes. MCU 1enviar señalProceso con Microcontrolador 2recibir señalProceso) De la misma manera, el pin TXD del microcontrolador 2 se conecta al pin RXD del microcontrolador 1.

Este diagrama esquemático refleja el proceso de dos microcontroladores que se envían y reciben información entre sí.

Cuando el microcontrolador 1 quiere enviar datos al microcontrolador 2, por ejemplo, envía 1 datos 0xE4, expresados ​​en forma binaria:

0b1110 0100, el microcontrolador 1 enfrenta varios problemas antes de que comience la transmisión:

Supongamos que primero transmito el bit más bajo de 0, luego necesito configurar el puerto TXD del microcontrolador 1 en un nivel bajo.

Los microcontroladores son generalmente de nivel TTL o CMOS. Para estándares de nivel TTL/CMOS:

Cualquier valor superior a 2,0 voltios es un nivel alto, algo inferior a 0,0 voltios es un nivel bajo y cualquier valor intermedio no es ni un nivel alto ni un nivel bajo. La lógica intermedia será confusa y puede ser juzgada por el dispositivo. un nivel alto, también puede considerarse como un nivel bajo. Por lo tanto, trate de no operar el circuito en esta área. Estar en esta zona puede hacer que su producto sea impredecible. Por lo tanto, al desarrollar productos, es necesario verificar la hoja de datos del dispositivo y el voltaje durante el funcionamiento del circuito para asegurarse de que tenga un voltaje adecuado.

1. Nivel TTL:

Nivel alto de salida >2,4 V, nivel bajo de salida <0,4 V. A temperatura ambiente, el nivel alto de salida general es de 3,5 V y el nivel bajo de salida es de 0,2 V. Nivel mínimo de entrada alto y bajo: nivel alto de entrada >=2,0 V, nivel bajo de entrada <=0,8 V, margen de ruido es de 0,4 V.

2. Nivel CMOS:

1nivel lógico El voltaje está cerca del voltaje de suministro y el nivel lógico 0 está cerca de 0 V. Y tiene una amplia tolerancia al ruido.

Entonces aquí viene la pregunta:

Cuando no se transmite ni recibe información, el puerto de transmisión (TXD) del microcontrolador 1 estará en un nivel alto o bajo, o el voltaje del puerto estará entre estos. El voltaje del puerto de recepción (RXD) de la MCU 2 sigue el voltaje del puerto de transmisión de la MCU 1. ¿Cómo configurar la señal de que la MCU 1 está a punto de comenzar a transmitir información, es decir, cómo sabe la MCU 2 que la MCU 1 le ha transmitido información? Por tanto, existe la necesidad de estandarizar los estándares de comunicación.

Paso 1: Se estipula que cuando no se produce la comunicación, el voltaje de los puertos TXD y RXD del microcontrolador se mantiene alto.

Paso 2: estandarice el método de transmisión de datos como se muestra a continuación

Puede ver que define 1 bit de inicio, 1 bit de parada y 1 byte de datos a transmitir, lo que da un total de 8 bits.datos de diez dígitos

La transmisión de datos 0xE4 mencionada anteriormente en realidad transmite 0 1110 0100 1. La transmisión de 1 byte de datos desde la MCU 1 a la MCU 2 en realidad transmite datos de 10 bits. Este conjunto de 10 bits se denomina trama de datos en serie completa.

Con el bit de inicio y el bit de parada, el puerto RXD del microcontrolador 2 comienza a prepararse para recibir datos cuando detecta un nivel bajo. De la misma manera, si el microcontrolador 1 quiere enviar 1 byte de datos, primero debe enviar un bit de inicio 0 (dígale al microcontrolador 2 que lo prepare para recibir) y luego envíe un bit de parada 1 (dígale al microcontrolador 2 un byte de transferencia de datos completada).Y al transmitir datos, esPrimero bajo, luego altoOrden

Paso 3: Debe establecer de manera uniforme el tiempo necesario para transmitir 1 bit de datos. La velocidad de este tiempo se expresa mediante la velocidad en baudios (baudios). Una velocidad en baudios de 1 significa transmitir 1 bit de datos en 1 segundo, y una velocidad en baudios de 9600 significa transmitir 9600 bits de datos en 1 segundo.

Luego obtenemos el resultado de transmitir 1 bit.duración=1/baudios., entonces se puede encontrar que el tiempo para transmitir 1 trama de datos completa es10/baudios,El intervalo de tiempo entre marcos de datos es arbitrario.

Cuando MCU 1 y MCU 2 transmiten señales, sus velocidades en baudios deben configurarse para que sean consistentes para lograr una comunicación correcta.

Interfaz de comunicación RS232

En los primeros años de las computadoras de escritorio, generalmente había una interfaz en serie de 9 pines. Esta interfaz en serie se llama interfaz RS-232, que está relacionada con la comunicación UART. Sin embargo, las computadoras portátiles modernas ya no tienen esta interfaz en serie de 9 pines. Por lo que la comunicación con microcontroladores tiende cada vez más a utilizar puertos serie virtuales USB.

La lógica de nivel utilizada por RS232 es lógica negativa, que es diferente de los niveles lógicos TTL/CMOS.

Por lo tanto, el puerto serie RS232 de 9 pines de la computadora no se puede conectar directamente al microcontrolador. Se requiere un chip de conversión de nivel MAX232 para completar la siguiente figura:

Descripción del pin RS232:

1. Detección de portador DCD (Detección de portador de datos) 2. Recibir datos RXD 3. Enviar datos TXD

4. El terminal de datos está listo para DTR (Terminal de datos listo) 5. Señal a tierra 6. Datos listos DSR (Conjunto de datos listo)

7. Solicitud de envío de RTS (Peticion para enviar) 8. Borrar y enviar CTS(Listo para enviar) 9. Aviso de timbre RI(El sonar)

Como se muestra en la figura anterior, en el cableado del puerto serie de RS232, la comunicación se puede completar siempre que los pines 2, 3 y 5 estén conectados a los pines MAX232 correspondientes.

Comunicación USB a serie

  Con el desarrollo de la tecnología, la comunicación por puerto serie RS-232 se utiliza ampliamente en la industria. Sin embargo, en la aplicación de tecnología comercial, la tecnología USB a UART ha reemplazado lentamente al puerto serie RS232.

Entonces, ¿cómo realizar la comunicación entre el microcontrolador y la computadora como se muestra en la figura?

Esta es la placa de desarrollo en este caso que utiliza el chip de puerto serie CH340T para lograr esta función.

El puerto TXD del microcontrolador utiliza una tapa de puente para conectarse al USB-TX y está conectado al puerto RXD del pin 4 del CH340 al mismo tiempo.

El puerto del microcontrolador RXD utiliza una tapa de puente para conectarse al USB-RX y está conectado al tercer pin TXD del CH340.

Puede ver que hay un diodo 4148 en serie entre USB-RX y el tercer pin TXD del CH340, porque el microcontrolador STC89C52 necesita un arranque en frío al descargar el programa. Simplemente haga clic en descargar primero y luego encienda.

así llamadoInicio fresco Se refiere al proceso de inicio del microcontrolador desde el apagado hasta el encendido, mientras que el arranque en caliente significa que el microcontrolador siempre está encendido; La diferencia entre arranque en frío y arranque en caliente es: durante el arranque en frío, los valores en la RAM interna del microcontrolador son cantidades aleatorias, mientras que durante el arranque en caliente, los valores en la RAM interna del microcontrolador no cambiarán y permanecerá igual que antes del inicio.

En el momento del encendido, el microcontrolador primero detectará si es necesario descargar el programa. Aunque el VCC del microcontrolador está controlado por el interruptor, debido a que el pin 3 del CH340T es un pin de salida, si no existe tal. diodo, el microcontrolador posterior del interruptor fallará cuando la alimentación esté apagada. El pin 3 de CH340T está conectado al pin P3.0 (RXD) del microcontrolador. La corriente fluirá hacia el circuito de la etapa posterior a través de este pin y cargará el condensador de. la etapa posterior, lo que resulta en un cierto voltaje en la etapa posterior. Este voltaje, aunque el valor es solo de aproximadamente 2 ~ 3 V, puede afectar el arranque en frío normal. Después de agregar un diodo, por un lado no afecta la comunicación, por otro lado puede eliminar este efecto adverso.

Aprendí del manual del microcontrolador que P3.0 es un puerto IO casi bidireccional.

La parte de la caja roja es el puerto IO casi bidireccional. , cuando el bit de salida interno tiene un nivel bajo, a través de la puerta NOT, la base del transistor está en un nivel alto, el transistor se enciende (el voltaje en ambos extremos del CE es casi el mismo en conducción saturada) y el IO El puerto del microcontrolador emite un nivel bajo, independientemente de si el interruptor de llave está presionado o levantado, el puerto IO permanece bajo. Es decir, no está controlado por señales externas.

Cuando la salida interna es de nivel alto, después de pasar por la puerta NOT, la base del transistor es extremadamente baja y el transistor no conduce (la resistencia en ambos extremos de CE es muy grande y la resistencia R es insignificante en comparación con it). En este momento, la salida del puerto IO es alta. Cuando se presiona el botón, el puerto IO está conectado a tierra y el puerto IO genera un nivel bajo.

De esto se puede ver que sólo cuandoLa salida del puerto IO es de alto nivel.cuando,La salida del puerto IO está controlada por el circuito externo.

Por lo tanto, sabemos que la salida interna de P3.0 siempre es alta cuando se usa como puerto RXD.El puerto P3.1TXD sirve como transmisor y suNivel de salida internaSe puede cambiar hacia arriba o hacia abajo según sea necesario.

Y: para niveles TTL

Terminal de salida: nivel alto >=2,4 V, nivel bajo <=0,4 V;

Extremo receptor: nivel alto >=2,0 V, nivel bajo <=0,8 V.

Para nivel COMS

Terminal de salida: nivel alto = Vcc, nivel bajo = GND (Vcc es el voltaje de la fuente de alimentación);

Extremo receptor: nivel alto >=0.7Vcc, nivel bajo <=0.2Vcc.

Todavía hay cierta diferencia de voltaje entre el nivel lógico de su extremo receptor y el nivel lógico del extremo de salida. Esto puede deberse a la interferencia de caída de voltaje generada durante la transmisión de la señal o a la existencia de un circuito de protección, por lo que agregar un diodo no será suficiente. causarlo. El voltaje transmitido está en un área lógica confusa.

Utilice el puerto IO para simular la comunicación serie UART

Programa superior:

  1. # include<reg52.h>
  2. sbit PIN_RXD = P3^0; //接受引脚定义
  3. sbit PIN_TXD = P3^1; //发送引脚定义
  4. bit RxdorTxd = 0; //指示当前状态为接受还是发送
  5. bit RxdEnd = 0; //接受结束标志
  6. bit TxdEnd = 0; //发送结束标志
  7. unsigned char RxdBuf = 0; //接收缓冲区
  8. unsigned char TxdBuf = 0; //发送缓冲器
  9. void ConfigUART(unsigned int baud);
  10. void StartTXD(unsigned char dat);
  11. void StartRXD();
  12. void main()
  13. {
  14. EA = 1; //打开总中断
  15. ConfigUART(9600); //配置波特率为9600
  16. while(1)
  17. {
  18. while(PIN_RXD); //等待接收引脚出现低电平,即起始位
  19. StartRXD(); //启动接收
  20. while(!RxdEnd); //等待接受完成
  21. StartTXD(RxdBuf +1);//接受到的整数+1后,发送回去
  22. while(!TxdEnd); //等待发送结束
  23. }
  24. }
  25. /* 串口配置函数,baud-通信波特率 */
  26. void ConfigUART(unsigned int baud)
  27. {
  28. TMOD &= 0xF0; //清零T0的控制位
  29. TMOD |= 0x02; //配置T0为模式2
  30. TH0 = 256 - (11059200/12)/baud; //计数T0的重载值
  31. }
  32. /* 启动串行接受 */
  33. void StartRXD()
  34. {
  35. TL0 = 256 - ((256-TH0) >> 1);//接受启动时T0定时为半个波特率周期
  36. ET0 = 1; //使能T0中断
  37. TR0 = 1; //启动T0
  38. RxdEnd = 0; //清零接受结束标志
  39. RxdorTxd = 0; //设置当前状态为接受 1位发送
  40. }
  41. /* 启动串行发送,dat-待发送字节数据 */
  42. void StartTXD(unsigned char dat)
  43. {
  44. TxdBuf = dat; //待发送数据保存到发送缓冲器
  45. TL0 = TH0; //T0计算初值为重载值
  46. ET0 = 1; //使能T0中断
  47. TR0 = 1; //启动T0
  48. PIN_TXD = 0; //发送起始位
  49. TxdEnd = 0; //清零发送结束标志
  50. RxdorTxd = 1; //设置当前状态为发送
  51. }
  52. /*T0中断服务函数,处理串行发送和接收 */
  53. void interruptTimer0() interrupt 1
  54. {
  55. static unsigned char cnt = 0;
  56. if(RxdorTxd)
  57. {
  58. cnt++;
  59. if(cnt <= 8) //低位在先一次发送8bit数据位
  60. {
  61. PIN_TXD = TxdBuf & 0x01;
  62. TxdBuf >>= 1;
  63. }
  64. else if(cnt == 9) //发送停止位
  65. {
  66. PIN_TXD = 1;
  67. }
  68. else //发送结束
  69. {
  70. cnt = 0; //复位bit计数器
  71. TR0 = 0; //关闭T0
  72. TxdEnd = 1; //置发送结束标志
  73. }
  74. }
  75. else //串行接收处理
  76. {
  77. if(cnt == 0) // 处理起始位
  78. {
  79. if(!PIN_RXD) //起始位为0时,清零接收缓冲器,准备接受数据位
  80. {
  81. RxdBuf = 0;
  82. cnt++;
  83. }
  84. else //起始位为1(不为0)时,中止接收
  85. {
  86. TR0 = 0; //关闭T0
  87. }
  88. }
  89. else if(cnt <= 8) //处理8位数据位
  90. {
  91. RxdBuf >>= 1; //低位在先,所以将之前接收的位向右移
  92. if(PIN_RXD) //接收脚为1时,缓冲器最高位置1
  93. { //而为0时不处理即仍保持位移后的0
  94. RxdBuf |= 0x80;
  95. }
  96. cnt++;
  97. }
  98. else //停止位处理
  99. {
  100. cnt = 0; //复位bit计数器
  101. TR0 = 0; //关闭T0
  102. if(PIN_RXD) //停止位为1时,方认为数据有效
  103. {
  104. RxdEnd = 1; //置接收结束标志
  105. }
  106. }
  107. }
  108. }

Mapa de lógica de trabajo

Este programa utiliza el temporizador 0 para simular la comunicación serie UART. Tenga en cuenta que esto es solo una.Programa de simulación. Este programa implementa la comunicación entre la computadora y el microcontrolador. El resultado de su comunicación es transmitir los datos transmitidos por la computadora al microcontrolador, y el microcontrolador agrega 1 a los datos y los envía de regreso a la computadora. Utilice el asistente de depuración del puerto serie que viene con STC-ISP para demostrar este resultado.

Primero, asegúrese de que los puertos sean los mismos. Las imágenes de arriba son todas COM3, la velocidad en baudios es 9600, el bit de verificación es NO, el bit de datos es 8 y el bit de parada es 1. (Lo que se configura aquí es el de la computadora. parámetros del puerto serie)

Mire el resultado: la comunicación normal es posibleEl temporizador 0 simula la comunicación en serie_bilibili_bilibili

Explique brevemente la lógica de funcionamiento de este programa: porEnviar móduloPor ejemplo, envíe 0xAA =1010 1010 comenzando desde el bit más bajo

Eso es TxdBuf = 1010 1010Mira el programa

  1. if(RxdorTxd)
  2. {
  3. cnt++;
  4. if(cnt <= 8) //低位在先一次发送8bit数据位
  5. {
  6. PIN_TXD = TxdBuf & 0x01;
  7. TxdBuf >>= 1;
  8. }
  9. else if(cnt == 9) //发送停止位
  10. {
  11. PIN_TXD = 1;
  12. }
  13. else //发送结束
  14. {
  15. cnt = 0; //复位bit计数器
  16. TR0 = 0; //关闭T0
  17. TxdEnd = 1; //置发送结束标志
  18. }
  19. }

primeroIngrese la interrupción cnt = 1

PIN_TXD = TxdBuf & 0x01, es decir, el resultado del AND de 1010 1010 0000 0001 es asignar el bit más bajo de 0xAA al puerto de envío para habilitar el nivel correspondiente. Se puede ver que el voltaje que ingresa al puerto TXD de interrupción por primera vez es de nivel bajo y este proceso continuará hasta que ocurra la segunda interrupción.

Luego TxdBuff se desplaza un bit hacia la derecha, es decir, TxdBuf = 0101 0101

Entoncesla segunda vezinterrumpir

cont = 2

PIN_TXD = 1 Esta vez el nivel del puerto de envío es alto

TxdBuf = 0010 1010

Luego la tercera y cuarta veces hastaoctava vez

cont = 8

El nivel establecido por PIN_TXD = 1 es nivel alto, que es el bit 1 más alto de los datos transmitidos.

En este momento TxdBuf = 0x00

Despuésnovena vezIngresar la interrupción. El noveno ingresar a la interrupción significa que los bits de datos acaban de enviarse y es hora de prepararse para enviar el bit de parada.

Por lo tanto, PIN_TXD = 1, el puerto de envío se asigna directamente al nivel alto.

La última décima interrupción representa que también se ha enviado el bit de parada.Por lo tanto, a cnt reset se le asigna un valor de 0, a TR0 se le asigna un valor de 0, el temporizador 0 se apaga, TXDEnd = 1, el indicador de fin de transmisión se establece en 1 y se completa la transmisión de una trama de datos completa.

Despuésmódulo receptor: Enviamos 0xAA anteriormente Para esta función, su valor es el resultado de sumar 1 a los datos recibidos, por lo que los datos recibidos son: 0xA9 =1010 1001.

  1. void StartRXD()
  2. {
  3. TL0 = 256 - ((256-TH0) >> 1);//接受启动时T0定时为半个波特率周期
  4. ET0 = 1; //使能T0中断
  5. TR0 = 1; //启动T0
  6. RxdEnd = 0; //清零接受结束标志
  7. RxdorTxd = 0; //设置当前状态为0接收 1为发送
  8. }
  1. else //串行接收处理
  2. {
  3. if(cnt == 0) // 处理起始位
  4. {
  5. if(!PIN_RXD) //起始位为0时,清零接收缓冲器,准备接受数据位
  6. {
  7. RxdBuf = 0;
  8. cnt++;
  9. }
  10. else //起始位为1(不为0)时,中止接收
  11. {
  12. TR0 = 0; //关闭T0
  13. }
  14. }
  15. else if(cnt <= 8) //处理8位数据位
  16. {
  17. RxdBuf >>= 1; //低位在先,所以将之前接收的位向右移
  18. if(PIN_RXD) //接收脚为1时,缓冲器最高位置1
  19. { //而为0时不处理即仍保持位移后的0
  20. RxdBuf |= 0x80;
  21. }
  22. cnt++;
  23. }
  24. else //停止位处理
  25. {
  26. cnt = 0; //复位bit计数器
  27. TR0 = 0; //关闭T0
  28. if(PIN_RXD) //停止位为1时,方认为数据有效
  29. {
  30. RxdEnd = 1; //置接收结束标志
  31. }
  32. }
  33. }

Se puede ver que los procesos de envío y recepción son en realidad similares. Para la recepción de datos, marqué la primera interrupción comenzando desde la 0ª vez, principalmente para cooperar con cnt para una fácil comprensión.

Como se muestra en la figura, puede ver que el tiempo que lleva ingresar la interrupción por décima vez es la mitad del tiempo de interrupción preestablecido. Esto se debe a que al confirmar si una señal de nivel es 0 o 1, si el nivel es lo más temprano. El tiempo de muestreo puede producir errores o interferencias, por lo que el punto de muestreo generalmente se establece en el punto medio del tiempo de transmisión de la señal y el nivel de señal allí se considera la señal transmitida en este período de tiempo. Por lo tanto, el módulo receptor solo necesita establecer su tiempo de interrupción a la mitad del original cuando recibe el bit de inicio por primera vez, para garantizar que todos los puntos de recolección de señales posteriores estén en el punto central.

Veamos cómo se configura el programa: TL0 = 256 - ((256-TH0) &gt;&gt; 1); //Aceptamos que el tiempo T0 es la mitad del período de velocidad en baudios al iniciar.

256-TH0 es el tiempo de interrupción preestablecido. Mencionamos anteriormente que queremos que el tiempo de interrupción sea la mitad del anterior. La operación del programa es desplazarlo hacia la derecha en 1 bit. Desplazarlo a la derecha en 1 es 0000 0100 = 4. Se puede ver que la operación de desplazarlo a la derecha en 1 bit es cambiar el número a la mitad del valor original. De la misma manera, el resultado de desplazarse 1 bit a la izquierda es 0001 0000 = 16, lo que significa multiplicar el número original por 2.

Iniciar análisis del proceso del programa.

Cuando RxdorTxd es 0, ingrese la función else, es decir0ª vez Al ingresar a la interrupción, el punto de inicio del módulo receptor en el dominio del tiempo es el punto medio del bit de inicio. Primero determine si el voltaje del puerto es realmente bajo y, de lo contrario, apague la interrupción. ¿Por qué hacer esto?

Debido a que se trata de un módulo receptor, el voltaje de RXD no está controlado por el microcontrolador. En este caso, está controlado por la computadora que controla el voltaje del terminal TXD del CH340T. El voltaje del RXD del microcontrolador sigue el extremo CH340TXD. Para el extremo receptor, la información recibida puede sufrir interferencias y debe confirmarse nuevamente.

En caso afirmativo, cnt++, entonces cnt=1. RxdBuf = 0; borra el búfer de recepción a 0

Después1er(en realidad la segunda vez)De segunda categoría Ingrese la interrupción cnt = 1 e ingrese la función else if () para transferir datos al búfer paso a paso. El proceso posterior no se describirá en detalle si los lectores interesados ​​pueden realizarlo por sí mismos de acuerdo con la lógica del programa. Vea si los datos realmente se pueden almacenar en la variable del búfer primero en bits bajos y luego en bits altos. Debido a la publicación de blog anterior, la función utiliza el método de desplazamiento a la izquierda para almacenar primero los bits altos de los datos. Este enfoque complementa bastante otra forma de trabajar.

En este punto, el programa utiliza el temporizador 0 para simular la comunicación serie UART.

Tres tipos básicos de comunicación.

Comunicación simplex: solo una parte puede enviar información a la otra parte y la otra parte no puede devolver información, como controles remotos de TV, transmisiones de radio, etc.

Comunicación semidúplex: los datos se pueden transmitir entre dos partes y solo una de las partes puede enviarlos a la otra al mismo tiempo. Por ejemplo, un walkie-talkie es una comunicación semidúplex típica. El programa de simulación de puerto serie anterior también puede entenderse como comunicación semidúplex.

Comunicación full-duplex: se pueden enviar datos al mismo tiempo que se reciben datos, y las dos cosas se realizan simultáneamente, como por ejemplo nuestra comunicación telefónica.

La comunicación en serie de simulación de puerto IO básicamente muestra la esencia de la comunicación en serie, pero el programa del microcontrolador necesita detectar y escanear constantemente los datos recibidos por el puerto IO del microcontrolador, lo que ocupa gran parte del tiempo de ejecución del microcontrolador. Por lo tanto, hay un módulo UART dentro del microcontrolador 51, que puede recibir datos automáticamente y notificarle después de recibirlos. Para usarlo correctamente, debe configurar correctamente el registro de función especial.

Registro de control serie SCON

Este caso solo introduce el modo 1, es decir, configurar SM1 = 1 y SM0 = 0 es el modo 1. Este modo es el formato de trama de datos utilizado en la comunicación serie simulada anterior: 1 bit de inicio, 8 bits de datos y 1 bit de parada.

La comunicación en serie analógica utiliza el temporizador 0 para expresar la velocidad en baudios. El transmisor de velocidad en baudios del módulo UART STC89C52 solo puede ser generado por el temporizador T1 o el temporizador T2, pero no por el temporizador T0. Esto es completamente diferente del concepto de comunicación analógica.

Cuando se utiliza el temporizador T2, se requieren registros de configuración adicionales. De forma predeterminada, se utiliza el temporizador T1.

Código de programa:

  1. # include<reg52.h>
  2. void ConfigUART(unsigned int baud);
  3. void main()
  4. {
  5. EA = 1;
  6. ConfigUART(9600); //配置波特率为9600
  7. while(1);
  8. }
  9. /* 串口配置函数,baud-通信波特率 */
  10. void ConfigUART(unsigned int baud)
  11. {
  12. SCON = 0x50; //0x50= 0101 0000 配置串口为模式1
  13. TMOD &= 0x0F; //清零T1的控制位
  14. TMOD |= 0x20; //0x20 = 0010 0000 配置T1的为模式2自动重载模式
  15. TH1 = 256 - (11059200/12/32)/baud; //计算T1的重载值
  16. TL1 = TH1; //设置初值
  17. ET1 = 0; //禁止T1中断
  18. ES = 1; //启动串口中断
  19. TR1 = 1; //启动T1定时器
  20. }
  21. /*UART中断服务函数 */
  22. void interruptUART() interrupt 4
  23. {
  24. if(RI) //接收到字节
  25. {
  26. RI = 0; //软件清0接收中断标志
  27. SBUF = SBUF+1;//接收的数据+1,左边是发送SBUF,右边是接收SBUF
  28. }
  29. if(TI)
  30. {
  31. TI = 0; //软件清0发送中断标志位
  32. }
  33. }

Echa un vistazo al vídeo de los resultados:Viene con módulo de comunicación serial_bilibili_bilibili

Puede ver que la comunicación normal es posible sin ningún problema, y ​​luego explicaré brevemente el contenido relevante del programa:

La fórmula de cálculo para el valor de recarga del temporizador T1 es:

TH1 = TL1 = 256 - valor del oscilador de cristal/12/2/16/velocidad en baudios, entonces su

Tiempo del intervalo de interrupción = valor del oscilador de cristal/12/2/16/velocidad en baudios = valor del oscilador de cristal/12*(1/velocidad en baudios)*(1/32)

El valor del oscilador de cristal/12 significa el número de ciclos de la máquina en 1 segundo, (1/velocidad en baudios) significa el tiempo necesario para transmitir 1 bit de datos

Valor del oscilador de cristal/12* (1/velocidad de baudios) significa cuántos procesadores de máquina se necesitan para transmitir 1 bit de datos

De la misma manera, el valor del oscilador de cristal/12*(1/velocidad de baudios)*(1/32) el tiempo de esta interrupción = 1/32 del tiempo para transmitir 1 bit de datos

Es decir, la transferencia de 1 bit de datos se divide en 32 intervalos de tiempo.

El resultado calculado es 3, es decir, el intervalo de interrupción = 3 ciclos de máquina. Este tiempo es muy corto.

Debido a que el método de muestreo de señal del módulo de puerto serie es recolectar una sola señal 16 veces y extraer los niveles de señal de la séptima, octava y novena veces, si dos de las tres veces son niveles altos, se considera que los datos son altos. ser 1. Si el nivel es 0 dos veces, este bit se considera 0. De esta manera, si los datos se leen incorrectamente debido a interferencias inesperadas, aún se puede garantizar la exactitud de los datos finales.

La siguiente imagen es de la publicación de blog recomendada principalmente para facilitar la explicación.: Fórmula de cálculo de la velocidad en baudios

SMOD está controlado por el registro de potencia PCON. De forma predeterminada, SMOD es 0. Sustituirlo en la fórmula anterior es la fórmula de solución del valor inicial anterior.

TH1 = TL1 = 256 - valor del oscilador de cristal/12/2/16/velocidad en baudios

Cuando el registro se establece en 1 PCON |= 0x80, es decir, SMOD se establece en 1, la velocidad en baudios se puede duplicar, como se muestra en la fórmula anterior.

En este momento, el valor inicial de T1 se convierte en: TH1 = TL1 = 256 - valor del oscilador de cristal/12/16/velocidad de baudios

Una cosa que hay que señalar aquí es que: Si desea utilizar el registro PCON para controlar que la velocidad de onda se duplique, su fórmula de valor inicial aún debe escribirse como

TH1 = TL1 = 256 - el valor del oscilador de cristal/12/2/16/velocidad en baudios es solo

El valor de recarga actual es TH1=256 - (11059200/12/32)/baud =256-(11059200/12/16)/(2*buad) baudios*2=4800*2=9600, 9600 es el baudio del programa actual tasa

Si su empresa de recarga de valor inicial escribe TH1 = TL1 = 256 - valor del oscilador de cristal/12/16/velocidad en baudios, entonces su velocidad en baudios actual sigue siendo 4800, no 9600.Utiliza el software de comunicación en serie para configurar la velocidad de comunicación en baudios en 9600 y transmiteEl resultado es incorrecto

Ver el vídeo:Velocidad de baudios related_bilibili_bilibili

Podemos ver que el intervalo de tiempo para la velocidad en baudios de 9600 es de solo 3 ciclos de máquina, y el intervalo de tiempo de 14400 es de 2 ciclos de máquina. Se puede observar que si su velocidad en baudios es mayor, su intervalo de tiempo puede ser inferior a 1 ciclo de máquina. Por lo tanto, hay otro modo de trabajo, es decir, ConfigUART (9600) después de que el bit más alto de PCON se establece en 1, su velocidad de baudios actual es 19200, pero su intervalo de tiempo es el intervalo de tiempo de la velocidad de baudios original de 9600; 3 ciclos de máquina.

Debe recordarse que todavía existen muchas diferencias en el trabajo de la comunicación en serie simulada del temporizador 0 y el módulo de comunicación en serie. El módulo de comunicación en serie completa una entrada y una salida, y solo ingresa dos interrupciones en la comunicación en serie. Una vez en respuesta a que RI se establezca en 1, una vez en respuesta a que TI se establezca en 1 y luego se borre mediante software. Ya no preste atención al proceso de transmisión, céntrese solo en si la transmisión se completa y envíe una señal cuando se complete la transmisión.

El circuito de envío y recepción de comunicación en serie tiene físicamente dos registros SBUF idénticos, y sus direcciones también son 0x99, pero uno se usa para enviar el búfer y el otro para recibir el búfer. Esto significa que hay dos habitaciones y los números de las casas de las dos habitaciones son los mismos. A una de ellas se le permite entrar pero a la otra no se le permite salir pero no entrar. De esta manera, se puede lograr la comunicación full-duplex de UART sin interferencias entre sí. Pero, lógicamente, solo se opera SBUF cada vez, y el microcontrolador elige automáticamente si recibir o enviar SBUF en función de si realiza una operación de "lectura" o "escritura" en él.

Pasos básicos del programa de comunicación serial:

1. Configure el puerto serie en modo 1.

2. Configure el temporizador T1 en el modo 2, que es el modo de reinstalación automática.

3. Calcule los valores iniciales de TH1 y TL1 en función de la velocidad en baudios. Si es necesario, puede utilizar PCON para duplicar la velocidad en baudios.

4. Abra el registro de control del temporizador TR1 y deje que funcione el temporizador.Nota: Cuando se utiliza la interrupción del puerto serie, la interrupción del temporizador 1 ya no se puede habilitar, a menos que esté utilizando la interrupción del puerto serie del temporizador 2.