- Preparar el hardware
- Comprensión de los pines GPIO en STM8S103F
- Descripción de los pines y consejos para la selección de GPIO STM8S103F
- Programación de STM8S para entrada y salida GPIO usando SPL
- Carga y prueba del programa
Para los microcontroladores, un programa de LED parpadeante es equivalente al programa "hola mundo". En nuestro tutorial anterior, aprendimos cómo comenzar con la placa de desarrollo STM8S103F3 y cómo configurar el IDE y el compilador para programar nuestros controladores STM8S. También hemos aprendido cómo usar las bibliotecas periféricas estándar y cómo compilar y cargar el código en nuestro microcontrolador. Con todos los conceptos básicos cubiertos, comencemos a escribir código. En este tutorial, aprenderemos cómo realizar funciones GPIO generales en controladores STM8S. La placa ya tiene un LED integrado conectado al pin 5 del puerto B, aprenderemos a hacer parpadear este LED y también agregaremos un LED externo y lo controlaremos con un pulsador. Si es completamente nuevo, se recomienda encarecidamente leer el tutorial anterior antes de continuar.
Preparar el hardware
Antes de sumergirnos en el programa, preparemos las conexiones de hardware. Como se mencionó anteriormente, usaremos dos LED aquí, uno es un LED integrado que parpadeará continuamente y el otro es un LED externo que se alternará con un botón. La idea es aprender toda la funcionalidad GPIO en una configuración simple. El Led integrado ya está conectado a PB5 (pin5 de PORTB), por lo que acabo de conectar un LED a PA3 y un pulsador a PA2, como puede ver en el diagrama a continuación.
Pero, de todos los pines de salida disponibles en nuestro control, ¿por qué seleccioné PA3 para salida y PA2 para entrada? Las preguntas son válidas y lo explicaré más adelante en este artículo. Mi configuración de hardware para este tutorial se muestra a continuación. Como puede ver, también he conectado mi programador ST-link a pines de programación que no solo programarán nuestra placa, sino que también actuarán como fuente de alimentación.
Comprensión de los pines GPIO en STM8S103F
Volviendo a la pregunta, ¿por qué PA2 para entrada y por qué PA3 para salida? Para entender eso, echemos un vistazo más de cerca al pinout del microcontrolador que se muestra a continuación.
Según el diagrama de distribución de pines, tenemos cuatro puertos en nuestro microcontrolador, a saber, PUERTO A, B, C y D indicados por PA, PB, PC y PD respectivamente. Cada pin GPIO también se golpea con alguna otra funcionalidad especial. Por ejemplo, el PB5 (pin 5 del PUERTO B) no solo puede funcionar como pin GPIO sino también como pin SDA para comunicación I2C y como pin de salida del temporizador 1. Entonces, si usamos este pin para propósitos GPIO simples como conectar un LED, entonces no podremos usar I2C y el LED al mismo tiempo. Lamentablemente, el LED integrado está conectado a este pin, por lo que no tenemos muchas opciones aquí, y en este programa, no vamos a usar I2C, por lo que no es un gran problema.
Descripción de los pines y consejos para la selección de GPIO STM8S103F
Hablando sinceramente, no estaría de más usar PA1 como pin de entrada y simplemente funcionaría como pin. Pero lo mencioné deliberadamente para brindarme la oportunidad de mostrarte algunas trampas comunes en las que podrías caer al seleccionar pines GPIO en un nuevo microcontrolador. Lo mejor para evitar las trampas es leer los detalles y la descripción de los pines que se proporcionan en la hoja de datos STM8S103F3P6. Para la descripción del pin del microcontrolador STM8S103F3P6, los detalles que se mencionan en la hoja de datos se muestran debajo de las imágenes.
Los pines de entrada de nuestro microcontrolador pueden ser flotantes o pull-up débil y los pines de salida pueden ser Open Drain o Push-pull. La diferencia entre los pines Open Drain y Push-Pull Output ya se discutió, por lo tanto, no entraremos en detalles de eso. En pocas palabras, un pin de salida de drenaje abierto puede hacer que la salida sea tan baja y no tan alta, mientras que un pin de salida push-pull puede hacer que la salida sea tanto alta como alta.
Aparte de la tabla anterior, también puede notar que un pin de salida puede ser Salida rápida (10 Mhz) o Salida lenta (2 MHz). Esto determina la velocidad GPIO, si desea cambiar sus pines GPIO entre alto y bajo muy rápido, entonces podemos elegir salida rápida.
Algunos pines GPIO en nuestro controlador admiten True Open Drain (T) y High Sink Current (HS) como se menciona en la imagen de arriba. Una diferencia considerable entre Open Drain y True Open Drain es que la salida conectada al drenaje abierto no puede elevarse más que el voltaje de funcionamiento del microcontrolador (Vdd), mientras que un pin de salida de drenaje abierto verdadero se puede tirar más alto que Vdd. Los pines con alta capacidad de fregadero significan que puede absorber más corriente. La fuente y la corriente de disipación de cualquier pin GPIO HS es de 20 mA, mientras que la línea de alimentación puede consumir hasta 100 mA.
Al observar más de cerca la imagen de arriba, notará que casi todos los pines GPIO son del tipo High Sink Current (HS) excepto PB4 y PB5 que son True Open Drain Type (T). Esto significa que estos pines no se pueden hacer altos, no podrán proporcionar 3.3V incluso cuando el pin esté alto. Esta es la razón por la que el led integrado está conectado a 3.3V y conectado a tierra a través de PB5 en lugar de alimentarlo directamente desde el pin GPIO.
Consulte la página 28 en la hoja de datos para obtener una descripción detallada del pin. Como se menciona en la imagen anterior, PA1 se configura automáticamente como un pull-up débil y no se recomienda su uso como pin de salida. De todos modos, se puede usar como un pin de entrada junto con un botón, pero decidí usar PA2 solo para intentar habilitar la extracción desde el programa. Estas son solo algunas cosas básicas que serán útiles cuando escribamos programas mucho más complicados. Por ahora, está bien si muchas cosas rebotaron en tu cabeza, lo analizaremos en otros tutoriales.
Programación de STM8S para entrada y salida GPIO usando SPL
Cree un espacio de trabajo y un nuevo proyecto como discutimos en nuestro primer tutorial. Puede agregar todos los archivos fuente y de encabezado o solo agregar los archivos gpio, config y stm8s. Abra el archivo main.c y comience a escribir su programa.
Asegúrese de haber incluido los archivos de encabezado como se muestra en la imagen de arriba. Abra el archivo main.cy inicie el código. El código main.c completo se puede encontrar en la parte inferior de esta página y también podrá descargar el archivo del proyecto desde allí. La explicación del código es la siguiente, también puede consultar el manual de usuario de SPL o el video vinculado al final de esta página si está confundido acerca de la parte de codificación.
Desinicialización del puerto requerido
Comenzamos nuestro programa Desinicializando los puertos requeridos. Como discutimos anteriormente, cada pin GPIO tendrá muchas otras funciones asociadas además de funcionar como una entrada y salida normal. Si estos pines se han utilizado previamente para otras aplicaciones, entonces deberíamos Desinicializarlos antes de utilizarlos. No es obligatorio, sin embargo, es una buena práctica. Las siguientes dos líneas de código se utilizan para Desinicializar el Puerto A y el Puerto B. Simplemente use la sintaxis GPIO_DeInit (GPIOx); y mencione el nombre del puerto en lugar de x.
GPIO_DeInit (GPIOA); // preparar el puerto A para que funcione GPIO_DeInit (GPIOB); // preparar el puerto B para trabajar
Declaración GPIO de entrada y salida
A continuación, tenemos que declarar qué pines se utilizarán como entrada y cuáles como salida. En nuestro caso se usará como entrada el pin PA2, también declararemos este pin con Pull-up interno para que no tengamos que usar uno externo. La sintaxis es GPIO_Init (GPIOx, GPIO_PIN_y, GPIO_PIN_MODE_z); . Donde x es el nombre del puerto, y es el número de pin y z es el modo de pin GPIO.
// Declarar PA2 como pin de extracción de entrada GPIO_Init (GPIOA, GPIO_PIN_2, GPIO_MODE_IN_PU_IT);
A continuación, tenemos que declarar los pines PA3 y PB5 como salida. Nuevamente, son posibles muchos tipos de declaración de salida, pero usaremos “GPIO_MODE_OUT_PP_LOW_SLOW” lo que significa que lo declararemos como un pin de salida de tipo push-pull con velocidad lenta. Y por defecto, el valor será bajo. La sintaxis será la misma.
GPIO_Init (GPIOA, GPIO_PIN_3, GPIO_MODE_OUT_PP_LOW_SLOW); // Declara PB5 como pin de salida push pull GPIO_Init (GPIOB, GPIO_PIN_5, GPIO_MODE_OUT_PP_LOW_SLOW);
La siguiente instantánea del manual de usuario de SPL menciona todos los modos GPIO posibles (z).
Bucle while infinito
Después de la declaración del pin, necesitamos crear un bucle infinito dentro del cual seguiremos parpadeando el LED para siempre y monitorearemos el estado del botón para alternar el LED. El bucle infinito puede crearse con un while (1) o con un for (;;) . Aquí he usado while (1).
mientras (1) {}
Comprobación del estado del pin de entrada
Tenemos que comprobar el estado del pin de entrada, la sintaxis para hacerlo es GPIO_ReadInputPin (GPIOx, GPIO_PIN_y); donde x es el nombre del puerto e y es el número de pin. Si el pin es alto, obtendremos '1' y si el pin es bajo, obtendremos un '0'. Hemos utilizado un bucle if para comprobar si el pin está alto o bajo.
if (GPIO_ReadInputPin (GPIOA, GPIO_PIN_2)) // si se presiona el botón
Hacer un pin GPIO alto o bajo
Para hacer que un pin GPIO sea Alto o Bajo, podemos usar GPIO_WriteHigh (GPIOx, GPIO_PIN_y); y GPIO_WriteLow (GPIOx, GPIO_PIN_y); respectivamente. Aquí hemos hecho que el LED se encienda si se presiona el botón y se apague si no se presiona el botón.
if (GPIO_ReadInputPin (GPIOA, GPIO_PIN_2)) // si se presiona el botón GPIO_WriteLow (GPIOA, GPIO_PIN_3); // LED ENCENDIDO else GPIO_WriteHigh (GPIOA, GPIO_PIN_3); //LLEVAR AFUERA
Alternar un pin GPIO
Para alternar un pin GPIO, tenemos GPIO_WriteReverse (GPIOx, GPIO_PIN_y); llamar a esta función cambiará el estado del pin de salida. Si el pin es alto, se cambiará a bajo, y si es bajo, se cambiará a alto. Estamos usando esta función para hacer parpadear el LED integrado en PB5.
GPIO_WriteReverse (GPIOB, GPIO_PIN_5);
Función de retardo
A diferencia de Arduino, el compilador cósmico no tiene una función de retardo predefinida. Entonces tenemos que crear uno por nuestra cuenta. Mi función de retardo se da a continuación. El valor doe el retardo será recibido en la variable ms y usaremos dos for loop para mantener o ejecutar el programa. Como _asm ("nop") es una instrucción de ensamblaje que significa sin operación. Esto significa que el controlador entrará en el bucle for sin realizar ninguna operación, creando así un retraso.
demora de vacío (int ms) // Definición de función {int i = 0; int j = 0; para (i = 0; i <= ms; i ++) {para (j = 0; j <120; j ++) // Nop = Fosc / 4 _asm ("nop"); // No realizar ninguna operación // código de ensamblaje}}
Carga y prueba del programa
Ahora que nuestro programa está listo, podemos cargarlo y probarlo. Una vez cargado, mi hardware funcionaba como se esperaba. El LED rojo integrado parpadeaba cada 500 milisegundos y el LED verde externo se encendía cada vez que oprimía el interruptor.
El trabajo completo se puede encontrar en el video vinculado a continuación. Una vez que haya llegado a este punto, puede intentar conectar el interruptor y el LED a diferentes pines y volver a escribir el código para comprender el concepto. También puede jugar con el tiempo de retardo para comprobar si ha entendido los conceptos con claridad.
Si tiene alguna pregunta, déjela en la sección de comentarios a continuación y para otras preguntas técnicas, puede utilizar nuestros foros. Gracias por seguirnos, nos vemos en el próximo tutorial.