MICROCONTROLADORES
MICROCONTROLADORES
Introducción
Arquitectura
Memoria
I/O Digital
INTRODUCCIÓN
Uso de los microcontroladores
Microondas, Lavarropas, Televisores, ...
Automóviles, aviones, barcos
Teléfonos
Automatización industrial
Pequeños dispositivos ad-hoc
...
INTRODUCCIÓN
INTRODUCCIÓN
Oferta de Microcontroladores
Estructurada por “familias” y “subfamilias”.
Por ejemplo, cada familia tiene el mismo núcleo del
procesador (su código será compatible):
8051,PIC,HC,ARM
O son familias orientadas a la aplicación
O por performance (de diferente tipo)
OFERTA DE MICROCONTROLADORES
OFERTA DE MICROCONTROLADORES
ADVANCED RISC MACHINES
Fundada en 1990 (Antes ACOM)
“The world's leading semiconductor intellectual property
(IP) supplier”
“best MIPS to Watts - best MIPS to $ - smallest CPU die
size”
Los “socios” (hoy mas de 1000) compran las licencias de IP
y fabrican en base a ellas.
Diseñan procesadores y tecnologías relacionadas con ellos,
por ejemplo:
Procesadores
Conectividad para SoC
Procesadores Grficos
Software
Seguridad (para ARMs)
IoT
también fabrican algunas
cosas físicas . . .
OFERTA DE MICROCONTROLADORES
EJEMPLO DE IMPLEMENTADOR
EJEMPLO FAMILIAS DE MCU NXP-ARM
Kit FRDM-KL46Z
ARQUITECTURA
ARQUITECTURA – EJEMPLO - AVR
ARQUITECTURA
IA
ARQUITECTURA: PROCESADOR
ARQUITECTURA
Von Neuman vs. Hardvard
CISC vs. RISC
Tamaño/variedad de las instrucciones
Velocidad: clock; 8/16/32 bits
ARM – CORTEX-M
Cortex-M
Arquitectura de
la Memoria
Arquitectura
ARM
Cortex-M0 Von Neumann ARMv6-M
Cortex-M0+ Von Neumann ARMv6-M
Cortex-M1 Von Neumann ARMv6-M
Cortex-M3 Harvard ARMv7-M
Cortex-M4 Harvard ARMv7E-M
Cortex-M7 Harvard ARMv7E-M
MEMORIA
Registros (memoria de corto plazo):
Pequeña (relativamente)
Almacenamiento temporario p/CPU
Memoria de datos
Relativamente Grande
Almacena datos mientras el MCU funciona
También puede haber una memoria relativamente pequeña para almacenar datos en forma permanente (calibraciones)
Memoria de programa
Relativamente Grande
De preferencia, mantiene el programa incluso con el MCU apagado.
MEMEORIAS
MEMORIA: TIPO FÍSICOS
MEMORIA
S/DRAM: sin limite de escrituras
EEPROM: 100.000 ciclos de borrado
Flash: 10.000 ciclos de borrado
MEMORIA: DIRECCIONAMIENTO
Separado:
Cada tipo físico se direcciona por separado (por ejemplo, usando diferentes registros índices)
Hay direcciones repetidas
Contínuo:
Se accede siempre igual y la logica interna accede a la memoria que corresponde
No hay direcciones repetidas
MEMORIA: DIRECCIONAMIENTO
Separado
MEMORIA: DIRECCIONAMIENTO
Continuo
ENTRADA/SALIDA DIGITAL
ENTRADA/SALIDA DIGITAL
DIGITAL I/O
Implementadas por pines de conexión directa al exterior:
Se agrupan en “ports” de a 8 (32) pines.
En general, los pines se pueden configurar como entrada o salida
La lógica puede ser positiva o negativa.
Los pines pueden tener (generalmente tienen) otras funciones alternativas.
DIGITAL I/O •pin 1 del port B •Módulo de Interrupción 1 - entrada 5 •Pin Tx de puerto serie
•Conversor AD canal 5
DIGITAL I/O
Los pines se controlan mediante 2 o 3 registros, como mínimo. Conceptual y funcionalmente: Data Direction Register (DDR): hay uno por cada puerto y
cada bit determina la dirección de un pin.
Port Register (PORT): uno por cada puerto y cada bit controla el estado del puerto (si es de salida)
Port Input Register (PIN): uno por cada puerto y cada bit da el estado de su respectivo pin
La forma de nombrar los registros cambia con el fabricante
DIGITAL I/O
PORT Register: de preferencia debe
escribirse con operaciones de escritura de
bit, si estan disponibles
Caso contrario usar : Read-Modify-Write
con cuidado.
DIGITAL OUTPUT
Apenas el DDR setea un pin como salida, el MCU
excita el pin de acuerdo al contenido del registro
PORT correspondiente.
Cuidado con los cortocircuitos
Orden de seteo de DDR y PORT
DIGITAL INPUT
Pueden existir en los pines resistencias de pull-
up/down: puede (debe) programarse su
conexión/desconexión mediante algun registro al
efecto.
DIGITAL I/O (del manual de referencia del un MCU NXP-HS08 de 8 bits)
Registros para el port B (solo dos registros)
(del manual de referencia del MCU)
DIGITAL I/O Archivo header
correspondiente a un NXP-HS08
DIGITAL I/O
(del manual de referencia del MCU)
NXP - KL46Z
Registros para el port B (seis registros)
DIGITAL I/O Archivo header correspondiente a
un NXP-KL46Z
DIGITAL I/O
GPIOB_PDDR =0x0080; // initialize PTB7 as output
// mejor: GPIOB_PDDR | = (1 << 7);
GPIOB_PCOR= 0xFFFF; // initialize PTB7 to 0
// mejor: GPIOB_PCOR | = (1<<7)
GPIOB_PTOR |= (1 << 7); // invert the output (¿Por qué el ‘OR’ está de mas en estos dos últimos casos?)
0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0
Ejemplo:
bit 7 bit 0
NXP KL46Z
DIGITAL I/O: OTROS REGISTROS RELACIONADOS
Pin Control Register n (PORTx_PCRn):
define Interrupt Status Flag and Clear -Interrupt configuration - Pin function (multiplexer) - Driver strength - Filter control - Slew rate – Pull up/down resistor
System Integration Module => System Clock Gating Control Registers:
habilita el uso del clock en los puertos
FREESCALE KL46Z
KIT FRDM-KL46Z
KIT FRDM-KL46Z MCU: MKL46Z256VLLZ4
Dual role USB interface with mini-B USB connector
4 digit segment LCD module
Capacitive touch slider
Ambient light sensor
MMA8451Q accelerometer
MAG3110 Magnetometer
2 user LEDs
2 user push buttons
Flexible power supply options – USB, coin cell battery, external source
Battery-ready, power-measurement access points
Easy access to MCU I/O via Arduino ™ R3 compatible I/O connectors
Programmable OpenSDA debug interface with multiple applications available
including:
Mass storage device flash programming interface
P&E Debug interface provides run-control debugging and compatibility with IDE tools
CMSIS-DAP interface: new ARM standard for embedded debug interface
KIT FRDM-KL46Z
PROGRAMACIÓN DEL MCU: VÍA OPENSDA
KL46Z PC
PRIMER PROGRAMA: GPIO => USAR LEDS Y PULSADORES DEL KIT
1. Ver esquemático del kit: identificar pines
2. Ver manual de referencia del MCU
1. Identificar pines y puertos conectados con los leds y pulsadores
2. Ver necesidades de inicialización
1. Module Multiplexer (PINOUT - Pin Control Register)
2. System Clock Gating Control
3. Cargar la aplicación DEBUG-APP_Pemicro_vXXX.SDA como
aplicación a ejecutar por OpenSDA.
4. Correr Eclipse/Codewarrior
5. Hacer un programa mínimo
6. Debugging
MAQUINAS DE ESTADO FINITO EN C/C++
(MEF/FSM)
Maquina de estado finito:
d
e
c
b
Inicialización
Evento/señal/Condición
a
Estado 1
Estado 2 Estado 3
MAQUINAS DE ESTADO FINITO EN C/C++
(MEF/FSM)
Formalmente:
d
e
c
b
Inicialización
Evento/señal/Condición
a
Estado 1
Estado 2 Estado 3
tupla ⟨ E, Σ, A ⊆ E×Σ×E,sk ⟩, donde
E = {E1, E2 , ,..., En} es un conjunto finito de nodos.
Σ : es un alfabeto finito de etiquetas.
A : es un conjunto finito de aristas etiquetadas que unen nodos.
sk ∈ S: es el estado inicial.
⟨ S = {1,2,3},
Σ = {a, b, c},
A ={(1,b,2),(2,c,1),(2,d,3),(3,e,2),(3,a,1)},
sk =1 ⟩
MAQUINAS DE ESTADO FINITO EN C/C++
(MEF/FSM)
Implementación de la máquina de
estados
Inspección del hardware (interno u
externo)para detectar eventos
Implementación de la máquina de
estados
Interrupción hardware (interno u externo)
Handler
Polling Interrupciones
Uso de :
MAQUINAS DE ESTADO FINITO EN C/C++
(MEF/FSM)
Tipos de implementación en C y C++
Con instrucciones “switch” anidadas
Basadas en una matriz estado-transición
Similar a la anterior pero con punteros a funciones
Multi-thread FSM
Uso de estados extendidos
Todas las opciones anteriores orientadas a objeto en
C++
MEF CON SWITCH ANIDADOS
Un nivel de decisión superior (SWITCH externo) referido al estado de
la máquina
Un nivel de decisión inferior (SWITCH interno) referido a las señales,
eventos o condiciones que tienen significancia en ese estado
Con pocas señales el switch interno suele reemplazarse con por IF(s)
A veces se invierte la jerarquía (modelo por eventos => Petri)
Los estados suelen ser enumeraciones
Implementado:
Directamente en el main (totalmente o como una parte de él)
Haciendo uso de una función (“dispatcher”), donde se implementa
MEF CON SWITCH ANIDADOS Modelo:
Proximo_Estado= Estado_Actual; switch ( Estado_Actual) { case EST_1: //aqui van acciones dentro del estado 1 switch (evento ) { //solo eventos que cambian este estado case EVEN_1: Proximo_estado = EST_x; // aquí pueden ir acciones asociadas al evento para este cambio de estado break; case EVEN_4: Proximo_estado = EST_y; // aquí pueden ir acciones asociadas el evento para este cambio de estado break;
. . . } break;
(continua en la siguiente diapositiva)
MEF CON SWITCH ANIDADOS (viene de la anterior diapositiva)
case EST_n: //aqui van acciones dentro del estado n switch (evento ) { //solo eventos que cambian este estado case EVEN_3: Proximo_estado = EST_x; // aquí pueden ir acciones asociadas al evento para este cambio de estado break;
. . . } break; } if (Estado_actual!=Proximo_estado){ // solo en caso de utilidad particular //aciones para todo cambio de estado funcion_salida(Estado_actual); // solo en caso de utilidad particular funcion_entrada(Próximo_estado); // solo en caso de utilidad particular Estado_actual=Proximo_estado; }
MEF CON SWITCH ANIDADOS
Simple
Poco uso de RAM
Tiempo de respuesta variable (aumenta con el numero de casos)
Implementación no jerárquica
El código no es reusable
Compleja cuando los estados y las señales aumentan
MEF CON SWITCH ANIDADOS
void dispatch(unsigned const evento) { switch(estado) { case EST_1: ProcesarEst1(evento); break; case STATE_2: ProcesarEst2(evento); break; ... }
Una variante (de muchas):
ALTERNATIVA: MATRIZ DE TRANSICIONES Señal 1 Señal 2 Señal 3 Señal4
Estado X Accion X(), Estado_Y
Estado Y AccionY(), Estado_A
Estado A Accion A(), Estado_Q Accion B(), Estado_A AccionC (), Estado_A
Estado Q Accion Q(), Estado_X
Representación directa de la MEF
Tiempo de respuesta constante y mas rápido
Mayor posibilidad de reusar el código con menos cambios
Pero la tabla puede ser muy grande y con desperdicios de celdas (pero puede
mandarse a la flash/rom)
Se puede pasar a un esquema mas económico usando un par de vectores
La inicialización puede ser complicada
(Curiosidad: si las acciones son la misma en toda la línea=> Moore; si pueden variar=>Mealy)
EJEMPLO:
int func_S1(void); int func_S2(void); int func_S3(void); enum codigo_estados { S1, S2, S3}; enum codigo_eventos {a, b, c, d, e, nada}; struct transicion { int (*funcion_estado)(void); enum codigo_estados proximo; }; struct transicion tabla_estado_evento [3][6]={ {{func_S1,S1},{func_S1,S2},{func_S1,S1},{func_S1,S1},{func_S1,S1},{func_S1,S1}}, {{func_S2,S2},{func_S2,S2},{func_S2,S1},{func_S2,S3},{func_S2,S2},{func_S2,S2}}, {{func_S3,S1},{func_S3,S3},{func_S3,S3},{func_S3,S3},{func_S3,S2},{func_S3,S3}} };
d
e
c
b
Inicialización
Evento/señal/Condición
a
Estado 1
Estado 2 Estado 3
EJEMPLO: void dispatcher(enum codigo_estados, enum codigo_eventos); enum codigo_estados estado_actual=S1; enum codigo_eventos evento_actual=nada; main() { int (* accion)(void); for (;;) { dispatcher(estado_actual,evento_actual); } return 0; } void dispatcher(enum codigo_estados, enum codigo_eventos){ int (*funcion)(void); funcion=tabla_estado_evento[estado_actual][evento_actual].funcion_estado; funcion(); estado_actual=tabla_estado_evento[estado_actual][evento_actual].proximo; }
MAQUINAS DE ESTADO FINITO EN C/C++
(MEF/FSM)
Ejemplo: los leds titilan alternativamente sólo cuando está el pulsador accionado
Tiempo X
Tiempo X
PulsadorLiberado
Pulsadorapretado
Inicialización
PulsadorLiberado
Leds Apagados
Led Verde Encendido – Rojo Apagado
Led Rojo Encendido – Verde Apagado