
En esta clase se muestra la placa del curso, sus características básicas y los documentos necesarios para el desarrollo del curso.
En esta clase se muestra el hardware adicional que se ha utilizada para la realización del curso. Es opcional pero muy recomendable para poder realizar todos los ejercicios.
Explicación paso a paso para la instalación del STM32CubeIDE en Linux
Explicación paso a paso para la instalación del STM32CubeIDE en Windows
En esta sesión se explica el diagrama interno de los pines del microcontrolador y se ven diferentes posibilidades de configuración (input/output, push-pull/open-drain, pull-up/pull-down... etc). El objetivo es que el alumno entienda en su totalidad el funcionamiento de este periférico para que, en sesiones sucesivas, pueda programar el driver que lo maneje.
Aplicaciones típicas de las resistencias de pull-up y pull-down
Push pull, open drain y aplicaciones típicas
Descripción de los registros de GPIO. Se explica para qué sirve cada uno de ellos y las opciones que presentan.
En esta sesión creamos el proyecto donde iremos desarrollando los drivers e iniciamos nuestra primesa sesión de debug.
En esta sesión controlamos el estado del LED de la placa configurando los registros del GPIO directamente desde el debugger, para obtener una visión general de cómo se controlan los periféricos.
En esta sesión damos un paso más y empezamos a modificar los registros desde código accediendo directamente a sus posiciones de memoria. Se ve como no es muy práctico y la conveniencia del uso de drivers para facilitar el desarrollo.
En esta sesión comenzamos el desarrollo con la creación del include principal stm32f446xx.h, donde empezaremos a definir nuestro primer periférico GPIO.
En esta sesión crearemos la estructura del registro de RCC y añadiremos macros para la activación y desactivación del clock para las GPIOs, así como para el reseteo de los puertos.
En esta sesión creamos el .c y el .h de nuestro driver GPIO y empezamos a definir las estructuras de control y configuración del periférico.
En esta sesión empezamos a crear las APIs de nuestro driver para leer/escribir el estado de los pines y puertos y resetear el GPIO.
En esta sesión comenzamos a escribir la rutina de inicialización del periférico con los parámetros de configuración suministrados por el usuario.
En esta sesión probaremos nuestro driver por primera vez controlando el parpadeo del led.
En esta sesión probaremos nuestro driver para leer el estado del pulsador mediante polling y, en función del estado, controlaremos el LED.
En esta sesión vemos cómo funcionan las interrupciones y hablamos de la vector table y del fichero de startup. También utilizamos el debugger para comprobar los conceptos estudiados.
En esta sesión exploramos el método utilizado para la generación de interrupciones GPIO a través del controlador EXTI. Explicamos el diagrama de bloques de este controlador y los registros a configurar.
En esta sesión se explican los registros del controlador EXTI para entender cómo tenemos que configurarlo en función de nuestras necesidades.
En esta sesión añadimos el controlador EXTI a nuestro driver que utilizaremos para configurar las interrupciones de nuestro GPIO.
En esta sesión incluimos los modos de funcionamiento mediante interrupción y los configuramos en la rutina de inicialización del driver.
En esta sesión hablaremos del controlador NVIC y de cómo habilitar, deshabilitar y configurar las prioridades de nuestras IRQs.
En esta sesión añadimos a nuestro driver las APIs GPIO_NVIC estudiadas en la sesión anterior.
En esta sesión creamos una aplicación que hace uso de la lectura del GPIO mediante interrupciones.
En esta sesión se exploran las diferentes fuentes de reloj de la MCU y cómo configurar tanto el PLL, como el reloj del sistema y de los buses AHB, APB1 y APB2.
Ejercicio de configuración del PLL para asentar conocimientos adquiridos.
En esta sesión listamos las APIs que vamos a desarrollar y empezamos a escribir el driver centrándonos en la configuración del HSE.
Implementamos las APIs para la configuración del LSE y del PLL, y las APIs para la habilitación/deshabilitación del HSI (High Speed Internal), el LSI (Low Speed Internal) y PLL. También creamos las macros de assert para la comprobación de parámetros y expresiones.
En esta sesión implementamos las APIs para la configuración del MCO1 y de la fuente de reloj del sistema. También creamos una API para esperar a la estabilización de los relojes y otra para obtener la fuente de reloj del sistema que hay configurada.
En esta sesión implementamos las APIs para la configuración de los prescalers y, por tanto, las frecuencias, de los buses AHB, APB1 y APB2.
En esta sesión completamos la implementación de nuestro driver con unas APIs de gran utilidad que proporcionarán a la aplicación información sobre la frecuencia de trabajo del sistema y de los buses AHB, APB1 y APB2.
Creamos una aplicación para poner a prueba nuestro nuevo driver, en la que configuramos el reloj del sistema para que corra desde el HSE (8MHz), el HSI (16MHz) y desde el PLL configurado para proporcionar 168MHz.
En cada uno de los casos configuramos el MCO1 para que dé salida al reloj configurado y poder así comprobar con un analizador lógico (en el caso del PLL, un osciloscopio) que la frecuencia es la esperada. También medimos el tiempo requerido para realizar un sencillo cálculo y ver las diferencias de tiempo para cada frecuencia. Por último, obtenemos la frecuencia de trabajo utilizando una de nuestras APIs para comprobar que nos devuelve lo esperado.
En esta sección se ven los diferentes tipos de TImers y se empieza con los más básicos, los Basic Timers, que son la unidad principal de contaje y que se encuentran incluídos en todos los demás.
En esta sección empezamos a escribir el driver que manejará los Timers. Empezamos definiendo las estructuras y las APIs para los Basic Timers.
Empezamos con la implementación de las APIs definidas anteriormente para los Basic Timers.
Acabamos la implementación de los Basic Timers añadiendo las APIs para la configuración y el manejo de sus interrupciones.
Escribimos nuestro primer ejemplo en el que se configura un Basic Timer para que genere un evento de update cada 100ms. En el bucle principal comprobaremos el estado del flag de update y, cuando esté seteado, limpiaremos el flag y haremos un toggle del LED. El resultado será el parpadeo del LED con una frecuencia de 10Hz.
También se incluye como recurso adicional la hoja de cálculo que se explica durante la clase y que es de gran ayuda para la obtención de los valores de configuración de los registros. (Password para eliminar la protección de celdas: 1234)
Ampliamos el ejercicio anterior para utilizar interrupciones en vez de polling.
Empezamos a ver la funcionalidad de lnput Capture, qué es y para qué sirve. Esta funcionalidad está disponible en los timers de propósito general y los avanzados. También se explican los diferentes modos de contaje.
En esta sección creamos la estructura de configuración para la funcionalidad de Input Capture explicada anteriormente y definimos su API de inicialización.
Implementamos la rutina de inicialización de la funcionalidad de Input Capture explicando los registros y bits necesarios para su configuración.
Acabamos la implementación de la parte del driver dedicada a la funcionalidad de Input Capture.
Explicación del siguiente ejercicio sobre la funcionalidad de Input Capture donde utilizaremos un timer hardware de propósito general para leer la frecuencia del reloj LSE (Low Speed External) de 32.768KHz
Primera parte de la implementación del ejercicio de lectura de la frecuencia del reloj LSE (Low Speed External) mediante Input Capture.
Segunda parte de la implementación del ejercicio de lectura de la frecuencia del reloj LSE (Low Speed External) mediante Input Capture.
Demostración de los resultados del ejercicio y de cómo solucionar un problema típico en la atención de interrupciones.
Explicación del funcionamiento del output compare en el que el timer se usa para generar salidas y descripción de los diferentes modos de trabajo. Entre ellos, se muestran los modos para la generación de señales PWM.
Empezamos a definir las APIs de nuestro driver que nos permitirán la inicialización de este modo de funcionamiento. En esta sesión se explica y define la inicialización del canal uno.
Acabamos la API de inicialización del output compare completando el resto de canales.
Utilizamos el modo toggle del output compare para manejar el led por hardware de manera mucho más eficiente.
Demostración del ejercicio.
Ejercicio para la generación por hardware de señales cuadradas mediante el uso de timers.
Completamos el ejercicio anterior para generar cuatro señales cuadradas de frecuencia diferente.
Explicación de señales PWM y de los modos del timer que permiten generarlas.
Modificamos el brillo del led mediante señales PWM.
Ampliamos el uso de señales PWM al control de servos.
Explicación de modos avanzados de maestro y esclavo.
Implementación de las APIs para poder configurar y utilizar los modos maestro/esclavo explicados.
Explicación del funcionamiento del PWM input que nos permite calcular mediante hardware el periodo y el ancho de pulso de la señal PWM.
En esta sesión se muestra cómo conectar todos los elementos para poder realizar el ejercicio.
Implementación del ejercicio para la lectura por hardware del periodo y ancho de pulso de una señal PWM.
Además, se proporcionan funciones de inicialización y manejo de la USART2 para el envío de información al ordenador mediante puerto serie.
Demostración del ejercicio.
Explicación del ejercicio sobre encoders en el que se verá cómo manejarlos por hardware mediante el uso de timers.
Implementación del ejercicio de manejo de encoders por hardware mediante timers.
Demostración del ejercicio de manejo de encoders por hardware mediante timers.
Explicación del funcionamiento y configuración del SYSTICK. Registros y arquitactura.
Implementación del driver de SYSTICK, sus registros, configuración y APIs.
Medición de la frecuencia del SYSTICK con el analizador lógico para comprobar que está bien configurado.
Creamos una función de delay que espera de forma precisa el número de milisegundos que queramos.
En este último ejercicio creamo la variable de ticks del sistema que es una parte fundamental en sistemas basados en tiempo real (RTOS) y que nos permite tener un timestamp básico y medir tiempos. En el ejemplo, utilizaremos esta variable para obtener el número de milisegundos entre pulsaciones sucesivas del botón.
En esta clase se explican las características, el funcionamiento y cómo configurar el Independent Watchdog.
En esta sesión se muestra la implementación del driver para el Independent Watchdog.
En esta sesión se muestra la primera parte del ejercicio sobre IWDG.
En esta sesión se muestra la segunda parte del ejercicio sobre IWDG.
En esta clase se explican las características, el funcionamiento y cómo configurar el Window Watchdog.
En esta sesión se muestra la implementación del driver para el Window Watchdog.
En esta sesión se muestra el uso del WWDG mediante un ejercicio práctico.
Código de descuento: 4A3F55540DB3B5A1EE04
En este curso aprenderás paso a paso y en profundidad a programar drivers en C para manejar diferentes periféricos y crear firmware de calidad. Durante el proceso, aprenderás también a manejar toda la documentación necesaria (reference manuals, datasheets, user guides...), a manejar un analizador lógico y a depurar tu propio código o el de terceros.
A continuación te muestro una explicación más detallada del curso:
La programación se hace desde cero, no se utiliza ningún tipo de código auto generado ni de terceros. Los drivers proporcionados por los fabricantes, como la HAL de ST, intentan ser todo lo generalistas que pueden para abarcar el número máximo de MCUs, esto hace que sean muy poco eficientes y poco aconsejables para proyectos serios y profesionales. En este curso se estudian las particularidades de los cortex-m y se van construyendo los drivers poco a poco desde bajo nivel (escribiendo directamente en los registros) para crear las APIs que ofrecen al usuario el nivel de abstracción necesario para simplificar en gran medida el control de los periféricos en el desarrollo del firmware en capas superiores. Esto te permitirá entender en profundidad cómo funcionan los periféricos internamente, en lugar de usar a ciegas drivers de terceros.
El temario está dividido en cinco módulos, en los que verás:
GPIO: Todo lo relacionado con las entradas y salidas de propósito general. Programarás un driver para configurarlas y controlarlas por completo, incluyendo su uso mediante interrupciones.
RCC: en este módulo aprenderás las diferentes fuentes de reloj de las que dispone la MCU y cómo configurar el clock del sistema. También aprenderemos el uso del PLL para multiplicar la frecuencia de reloj y ajustarla a nuestras necesidades. Sacaremos varias señales de reloj hacia el exterior mediante el pin MCO1 para poder medir la frecuencia configurada y comprobar que nuestro driver funciona correctamente.
TIMERS: este es el módulo más extenso, ya que se estudia al detalle el uso de los diferentes timers con incluye la MCU. Desde los básicos hasta los avanzados, pasando por los de propósito general. No solo estudiamos el uso de los timers como simple temporización, sino que también se explican los usos de Input Capture para la obtención del tiempo entre eventos de entrada y medición de señales, y de Output Compare para la generación de salidas y señales PWM. Hay multitud de ejercicios para afianzar los conceptos de cada uno de los modos. Al final del módulo se incluyen ejercicios avanzados. En uno de ellos se explica el PWM Input mode, para la medición por hardware del periodo y el ciclo de trabajo de una señal PWM. En otro se utiliza el modo Encoder para la obtención y el tratamiento, también por hardware, de las señales entregadas por los encoders.
SYSTICK: en este módulo se estudia el timer del sistema, interno al CortexM4. Aprenderás a configurarlo y a beneficiarte de las ventajas que ofrece y que aprovechan los sistemas de tiempo real RTOS.
WATCHDOG: en este móculo se estudia el uso de los diferentes watchdogs que ofrece la MCU. Primero se explica el Independent Watchdog (IWDG), que es el más común, y luego se ve el Window Watchdog (WWDG), que permite controlar los tiempos de refresco de forma más fina e introduce un tiempo mínimo de espera antes de actualizar el watchdog para evitar el reset. Como siempre, programamos los drivers para ambos y realizamos ejercicios para ver posibles usos y afianzar conocimientos.
En resumen, más de 11h de curso repartidas en 5 módulos de los que acabarás siendo un experto. Después de este curso serás capaz de programar tus propios drivers, entenderás el funcionamiento de periféricos fundamentales, de los cortex-M y tendrás un conocimiento amplio del desarrollo firmware.
IMPORTANTE! No se utilizan generadores de código ni librerías de terceros. Lo hacemos todo desde cero, que es como más se aprende!
Si estás interesado en el mundo de los microcontroladores y el desarrollo firmware, este curso te va a ser de gran ayuda y te va a ahorrar cientos de horas de búsqueda de información por tu cuenta. Además, si, por cualquier motivo, el curso no te convence o no es lo que esperabas, puedes solicitar un reembolso durante los primeros 30 días, y se te devolverá en su totalidad, sin pedir ningún tipo de justificación ni hacer preguntas.
Puedes ver el temario y ver el vídeo de presentación para hacerte una mejor idea de lo que vamos a ver. Y si tienes cualquier duda, no dejes de escribirme y te ayudaré en todo lo que pueda.
Espero verte dentro!
Muchas gracias y un saludo!
Javi