- Comunicación serial en STM8S103F3P6
- Pines de comunicación serie en STM8S103F3P6
- Diagrama de circuito para comunicación serie STM8S
- Configuración de STVD para comunicación en serie
- Programación de STM8S para comunicación en serie
- Control de LED desde el monitor en serie
- Vista más profunda de la biblioteca serial STM8S
La programación de un nuevo microcontrolador a menudo lleva más tiempo debido a los nuevos métodos de manejo de registros y al no saber qué bit hace exactamente qué. Lo mismo ocurre con la depuración sin decirlo. Esta es la razón por la que los programadores a menudo usan puntos de interrupción en su código y lo recorren con un depurador. Pero el uso de un depurador puede requerir hardware adicional (la mayoría de las veces caro) y también tiempo adicional. Siendo un fanático de Arduino, una cosa en la que todos estamos de acuerdo es que usar declaraciones de impresión en serie para depurar y comprender nuestro código hace la vida mucho más fácil. ¿Qué podemos replicar lo mismo en STM8 con el compilador cósmico C y las bibliotecas SPL? Bueno, es muy posible, y eso es exactamente lo que vamos a hacer en este tercer tutorial de nuestra serie de tutoriales.También puede consultar la introducción a STM8S (tutorial 1) y el control STM8S GPIO (tutorial 2) si es completamente nuevo aquí. Además, también hemos explorado la posibilidad de programar STM8S con Arduino para principiantes rápidos. Dicho todo esto, entremos en el tutorial.
Comunicación serial en STM8S103F3P6
En la hoja de datos de STM8S103F3P6, podemos ver que nuestro controlador de 8 bits admite la comunicación UART en muchos modos diferentes. El controlador también tiene un pin de salida de reloj para comunicación UART síncrona y también puede admitir SmarCard, IrDA y LIN. Pero no exploraremos nada de eso en este tutorial solo para evitar la complejidad. Aprenderemos a leer y escribir UART simples.
El tutorial también proporciona un archivo de encabezado llamado stm8s103 serial.h con el que puede ejecutar comandos UART simples como Serial begin, Serial read, serial print, etc. Básicamente, podrá imprimir char, int y string en el monitor serial y también leer char del monitor serial. Al final de este tutorial, podrá controlar un LED desde el monitor en serie y obtener información sobre el estado del LED. El archivo de encabezado mencionado anteriormente depende de las bibliotecas SPL, así que asegúrese de haber seguido el tutorial de introducción.
Pines de comunicación serie en STM8S103F3P6
Empecemos por el lado del hardware. Echando un vistazo rápido a los pines del microcontrolador STM8S103F3P6 que se muestran a continuación, podemos ver que los pines 1, 2 y 3 se utilizarán para la comunicación UART.
Entre los tres, el pin 1 es el pin de reloj UART que se utilizará solo durante la comunicación UART síncrona, por lo que no lo necesitaremos aquí. El pin 2 es el pin del transmisor UART y el pin 3 es el pin del receptor UART. Tenga en cuenta que estos pines también se pueden duplicar como un pin analógico o un pin GPIO normal.
Diagrama de circuito para comunicación serie STM8S
El diagrama del circuito es muy simple aquí, necesitamos conectar nuestro ST-LINK 2 para la programación y un convertidor de USB a TTL para leer datos en serie. Tenga en cuenta que nuestro controlador STM8S funciona en un nivel lógico de 3.3V, así que asegúrese de que su convertidor de USB a TTL también admita la lógica de 3.3V. El diagrama de circuito completo se muestra a continuación.
Debe conectar su ST-link en un puerto USB y el convertidor de USB a TTL en otro puerto USB de su computadora portátil, de modo que pueda programar y monitorear datos al mismo tiempo. La conexión UART es simple, simplemente conecte la tierra y el pin Rx / Tx de su microcontrolador STM8S a los pines Tx / Rx del convertidor USB a TTL. Aquí he encendido el controlador con el pin Vcc de ST-Link y he dejado abierto el pin vss del convertidor TTL, también puede hacer esto al revés. Hay muchos tipos de convertidores USB a TTL en el mercado, solo asegúrese de que pueda operar con señales lógicas de 3.3V y simplemente busque los pines Tx, Rx y GND y realice la conexión que se muestra arriba. La configuración de mi hardware se muestra a continuación.
Para crear una forma de comunicación en serie, hemos proporcionado el archivo de encabezado STM8S_Serial.h . Con este archivo de encabezado, puede realizar funciones simples similares a las de Arduino para la comunicación en serie.
Puede encontrar todos los archivos necesarios para este proyecto en nuestra página de Github STM8S103F3_SPL. Si solo necesita este archivo de encabezado en particular, puede descargarlo desde el siguiente enlace.
Descarga STM8S_Serial.h
Configuración de STVD para comunicación en serie
Para trabajar con comunicación en serie, usaremos muchos usando la función de archivo de encabezado STM8S_Serial.h que discutimos anteriormente. Pero la biblioteca tiene otras dependencias, muchas de las cabeceras y archivos C relacionados con SPL UART y Clock. Entonces, a partir de este punto, es mejor incluir todos los archivos de encabezado y C en nuestro proyecto para evitar un error de compilación. Mi entorno de trabajo STVD se ve así.
Asegúrese de haber incluido todos los archivos fuente SPL y el archivo Incluir como hicimos en nuestro primer tutorial. Y también asegúrese de haber agregado el archivo de encabezado stm8s103_serial.h . No hay ningún archivo C para este encabezado.
Programación de STM8S para comunicación en serie
Una vez que la configuración del proyecto STVD esté lista, podemos comenzar a escribir nuestro código en el archivo main.c. El código completo de este tutorial se puede encontrar al final de esta página. La explicación es la siguiente.
El primer paso es incluir los archivos de encabezado requeridos, aquí he agregado el archivo de encabezado principal (stm8s) y el archivo de encabezado stm8s_103_serial que acabamos de descargar.
// Encabezados obligatorios #include "STM8S.h" #include "stm8s103_serial.h" //https://github.com/CircuitDigest/STM8S103F3_SPL/blob/master/stm8s103%20Libraries/stm8s103_Serial.h
A continuación, usamos las macros de diseño para especificar los pines de entrada y salida. Aquí solo controlaremos el LED integrado que está conectado al pin 5 del puerto B, por lo que le damos un nombre como test_LED .
#define test_LED GPIOB, GPIO_PIN_5 // el LED de prueba está conectado a PB5
Continuando dentro de la función principal, definiremos el pin como una salida. Si no está familiarizado con las funciones básicas de GPIO, consulte el tutorial de STM8S GPIO.
// Definiciones de pines // Declarar PB5 como pin de salida push pull GPIO_Init (test_LED, GPIO_MODE_OUT_PP_LOW_SLOW);
Luego, inicializamos nuestros puertos de comunicación en serie a 9600 baudios. Para aquellos que son nuevos, 9600 es la velocidad a la que se transferirán los bits de datos durante la comunicación. Si configura 9600 aquí, también debe configurar lo mismo en el software de monitoreo. Luego también imprimimos una cadena "Enter command" y pasamos a la siguiente línea.
Serial_begin (9600); // Inicializar la comunicación serial a una velocidad de 9600 baudios Serial_print_string ("Ingresar comando"); // imprime una cadena Serial_newline (); // pasar a la siguiente línea
Pasando al ciclo while infinito, usamos la función Serial_available para verificar si hay datos seriales entrantes. Si es así, lo leemos y guardamos en una variable llamada ch y también imprimimos lo mismo usando Serial_print . Luego si el valor recibido es 0 apagaremos el LED y si es 1 encenderemos el LED
if (Serial_available ()) {Serial_print_string ("Ha pulsado:"); ch = Serial_read_char (); Serial_print_char (ch); Serial_newline (); si (ch == '0') GPIO_WriteHigh (test_LED); // LED APAGADO if (ch == '1') GPIO_WriteLow (test_LED); //LLEVADO EN }
Con esto, la programación de este tutorial está completa, simplemente cargue el código que se proporciona al final de esta página y debería poder controlar el LED desde el monitor en serie.
Control de LED desde el monitor en serie
Una vez que haya cargado el código, puede abrir cualquier monitor en serie a velocidades de 9600 baudios. He usado el propio monitor serial Arduino para facilitar su uso. Presione el botón de reinicio y debería ver el mensaje "Ingrese un comando". Luego, si ingresa 1 y presiona enter, el led integrado debe encenderse, de manera similar para 0, debe apagarse.
El trabajo completo se puede encontrar en el video vinculado al final de esta página. Si tiene alguna pregunta, déjela en la sección de comentarios. También puede utilizar nuestros foros para publicar otras preguntas técnicas.
Vista más profunda de la biblioteca serial STM8S
Para aquellas mentes curiosas que quieran saber qué sucede realmente dentro del archivo de encabezado STM8S103F3_Serial, sigan leyendo….
Este archivo de encabezado funciona bien para la programación de nivel principiante, pero si está utilizando una versión diferente del controlador STM8S o busca algunas opciones avanzadas, es posible que desee modificar un poco este encabezado o trabajar directamente con bibliotecas SPL. Escribí este archivo de encabezado como una parte del archivo de encabezado UART1, la explicación de mi archivo de encabezado es la siguiente.
Leer un personaje de Serial Monitor
Esta función ayuda a leer un solo carácter que se ha enviado al microcontrolador desde el monitor en serie.
char Serial_read_char (void) {while (UART1_GetFlagStatus (UART1_FLAG_RXE) == RESET); UART1_ClearFlag (UART1_FLAG_RXNE); return (UART1_ReceiveData8 ()); }
Esperamos hasta que la bandera RXE esté FIJADA para completar la recepción y luego limpiamos la bandera para reconocer la recepción. Finalmente, enviamos los datos de 8 bits recibidos como resultado de esta función.
Impresión de un personaje en Serial Monitor
Esta función transmite un solo carácter desde un microcontrolador al monitor en serie.
void Serial_print_char (valor de carácter) {UART1_SendData8 (valor); while (UART1_GetFlagStatus (UART1_FLAG_TXE) == RESET); // espera a enviar}
La función simplemente escribe el valor de 8 bits y espera hasta que se complete la transmisión verificando UART1_FLAG_TXE en SET
Inicialización de la comunicación en serie
Esta función inicializa la comunicación en serie a la velocidad de transmisión requerida.
void Serial_begin (uint32_t baud_rate) {GPIO_Init (GPIOD, GPIO_PIN_5, GPIO_MODE_OUT_PP_HIGH_FAST); GPIO_Init (GPIOD, GPIO_PIN_6, GPIO_MODE_IN_PU_NO_IT); UART1_DeInit (); // Desinicializar los periféricos UART UART1_Init (baud_rate, UART1_WORDLENGTH_8D, UART1_STOPBITS_1, UART1_PARITY_NO, UART1_SYNCMODE_CLOCK_DISABLE, UART1_MODE_TXRX_ENABLE); // (BaudRate, Wordlegth, StopBits, Parity, SyncMode, Mode) UART1_Cmd (ENABLE); }
Aparte de la velocidad en baudios, hay otros parámetros que deben configurarse para la comunicación en serie, como el número de bits de datos, el número de bits de parada, la paridad, etc. El más común (similar a Arduino) son los datos de 8 bits. con un bit de parada y sin paridad y, por tanto, esa será la configuración predeterminada. Puede cambiarlo si es necesario.
Impresión de un número entero en un monitor en serie
La mayoría de las veces, si usamos un monitor en serie para depurar o monitorear, es posible que queramos imprimir una variable de tipo int en el monitor en serie. Esta función hace exactamente eso
void Serial_print_int (int number) // Función para imprimir el valor int en el monitor serial {char count = 0; char digit = ""; while (number! = 0) // divide el int a char array {digit = number% 10; contar ++; número = número / 10; } while (count! = 0) // imprime la matriz de caracteres en la dirección correcta {UART1_SendData8 (digit + 0x30); while (UART1_GetFlagStatus (UART1_FLAG_TXE) == RESET); // espera el envío de count--; }}
Toma un valor entero y lo convierte en una matriz de caracteres en el primer ciclo while, luego en el segundo ciclo while, enviaremos cada uno de los caracteres de manera similar a nuestra función print char.
Imprimir una nueva línea
Esta es una función simple para imprimir una nueva línea. El valor hexadecimal para hacer eso es "0x0a", simplemente lo estamos enviando usando el comando de transmisión de 8 bits.
void Serial_newline (void) {UART1_SendData8 (0x0a); while (UART1_GetFlagStatus (UART1_FLAG_TXE) == RESET); // espera a enviar}
Imprimir una cadena en un monitor en serie
Otra función útil es la de imprimir cadenas en el monitor en serie.
void Serial_print_string (cadena de caracteres) {. char i = 0; while (cadena! = 0x00) {UART1_SendData8 (cadena); while (UART1_GetFlagStatus (UART1_FLAG_TXE) == RESET); i ++; }}
Nuevamente, esta función también convierte la cadena en una matriz de caracteres y envía cada carácter. Como sabemos, todos los extremos de las cadenas serán nulos. Entonces solo tenemos que seguir atravesando y transmitiendo los caracteres hasta llegar al nulo 0x00.
Comprobando si los datos seriales están disponibles para leer
Esta función comprueba si hay datos en serie en el búfer listos para leer.
bool Serial_available () {if (UART1_GetFlagStatus (UART1_FLAG_RXNE) == TRUE) return TRUE; si no, devuelve FALSO; }
Comprueba el indicador UART1_FLAG_RXNE , si es verdadero, devuelve verdadero y si no lo es, devuelve falso.