viernes, 28 de abril de 2017

Parpadeo de un LED -ATtiny85-

Programa

/* Abril de 2017
Microcontrolador: ATtiny85-20PU
IDE: Arduino 1.8.2

Grabador: Arduino UNO
Programa que produce el parpadeo cíclico de un LED conectado a un ATtiny85.
*/

void setup() {
   pinMode(0, OUTPUT);  // Configura PB0 como salida
}

void loop() {
  digitalWrite(0, HIGH);    // LED encendido
  delay(1000);                     // Espera un segundo

  digitalWrite(0, LOW);     // LED apagado
  delay(1000);
}


➤ Circuito





➤ Observaciones

- En la entrada anterior del blog está explicado el procedimiento para grabar un programa en un ATtiny85.

- Si en los pasos de configuración previos a la grabación del programa se escogiera una frecuencia de reloj incorrecta, la cadencia del parpadeo del LED sería distinta a la pretendida por el código del programa.



- PB0 está en el pin 5 del microcontrolador.

- El circuito funciona con la señal de reloj interna del ATtiny85.



Programación de microcontroladores ATtiny con Arduino


Los ATtiny son unos pequeños microcontroladores que se pueden programar usando una tarjeta Arduino como grabador.

El IDE de Arduino permite escribir programas para los ATtiny, empleando el mismo lenguaje que para las Arduino, aunque con un número de órdenes menor.
 
Material empleado
Las pruebas de todo lo descrito más abajo se realizaron utilizando:
- Una Arduino UNO.
- Un microcontrolador ATtiny85-20PU.
- Un circuito de grabación del microcontrolador (puede ser implementado en una placa de pruebas).
- Arduino IDE 1.8.2. (para Windows).


Procedimiento

1. Configurar Arduino IDE para poder programar microcontroladores ATtiny

1.1. Dentro de Arduino IDE, clicar en Archivo/Preferencias. Aparece una ventana en la que hay que añadir el siguiente enlace:
https://raw.githubusercontent.com/damellis/attiny/ide-1.6.x-boards-manager/package_damellis_attiny_index.json

Para más información, ver este otro enlace.




1.2. Clicando en Herramientas / Placa / Gestor de tarjetas, se accede a una ventana en la que hay que seleccionar el controlador de los microcontroladores ATtiny e instalarlo (usar la última versión disponible).


 1.3. Una vez efectuada la instalación, accediendo a Herramientas / Placa, puede comprobarse que los microcontrolares ATtiny también aparecen en la lista.




2. Grabar un programa en un microcontrolador ATtiny85

2.1. En una Arduino, grabar el programa Ejemplos / 11.Arduino / ArduinoISP.

2.2. Escoger la opción Arduino as ISP en Herramientas / Programador.


2.3. Conectar a la Arduino el circuito de grabación del ATtiny.

  
En la siguiente imagen se puede ver el circuito de grabación implementado en un escudo de Arduino.  



2.4. En Herramientas hay que elegir la siguiente configuración:
- Placa: ATtiny.
- Procesador: ATtiny25/45/85.
- Clock: 1 MHz internal (*).
- Programador: Arduino as ISP (hecho en el paso 2.2).   



(*) Si el circuito integrado del ATtiny nunca ha sido usado, esta opción sería correcta. Mediante la quema del bootloader (Herramientas / Quemar Bootloader), se puede cambiar la frecuencia de reloj del microcontrolador, dependiendo de la que estuviera activada en  Herramientas / Clock justo antes de efectuar la operación.
 
Según la hoja de datos del componente, el ATtiny85-20PU puede trabajar con frecuencias de reloj de hasta 20 MHz.


2.5 El siguiente paso es cargar el programa que se desee en el ATtiny. Lo más fácil es grabar un programa vacío, como el de la figura anterior; aunque si se desea saber si la frecuencia de reloj escogida en Arduino IDE es la correcta, es preferible usar un programa de parpadeo de un LED.

Una vez grabado el programa, si no existe ningún error, tiene que aparecer un mensaje similar al de la figura siguiente.


 

viernes, 7 de abril de 2017

Generación de un retardo -ARM Cortex-M4-

Programa

/* Marzo de 2016
Tarjeta: STM32 Discovery
Microcontrolador: STM32F411VET6U
IDE: IAR Embedded Workbench
Programa que produce el parpadeo cíclico de LED verde (PD12) de la tarjeta
STM32 Discovery cada segundo. El retardo se genera manejando Systick.
*/

#include "stm32f4xx.h"

//--- Función que inicializa el puerto D y configura PD12 ---
void ini_LED_verde(void){
  RCC->AHB1ENR   |= 0x00000008;       // Habilita el reloj para el puerto D
  GPIOD->MODER   |= 0x01000000;       // Configura el pin 12 como salida
  GPIOD->OSPEEDR |= 0x03000000;      // PD12 podrá funcionar a alta velocidad 
}

//--- Función que configura Systick ---
void config_systick_retardo(void) {
  SysTick->CTRL &= ~(SysTick_CTRL_CLKSOURCE_Msk); // La señal de reloj para
                                                                                                       // Systick es AHB / 8
                                                                                                       // ( = 12 MHz, en este caso)
  SysTick->LOAD  = 12000 - 1;        // Systick contará 12000 ciclos de una
señal de reloj de 12 MHz
 }

//--- Función que genera un retardo en milisegundos igual a num_ms ---
void retardo_ms(uint32_t num_ms) {
  SysTick->CTRL |= SysTick_CTRL_ENABLE_Msk;           // Habilita Systick
  while (num_ms != 0) {
    // Espera hasta que el valor del bit COUNTFLAG del registro de control de
Systick sea igual a '1'
    while ((SysTick->CTRL & SysTick_CTRL_COUNTFLAG_Msk) == 0) {}
    --num_ms;
  }
  SysTick->CTRL &= ~(SysTick_CTRL_ENABLE_Msk);    // Deshabilita Systick
}

//--- Función principal del programa ---
void main (void)  {        
  ini_LED_verde();                 
  config_systick_retardo();           
    
  while (1) {
    GPIOD->BSRRL = 0x1000;         // Enciende el LED
    retardo_ms(1000);                         // Retardo de 1 segundo 
    GPIOD->BSRRH = 0x1000;         // Apaga el LED    
    retardo_ms(1000);                         // Retardo de 1 segundo 
   }
}




➤ Observaciones

- No es necesario ningún componente electrónico externo a la tarjeta Discovery, dado que se utiliza el LED verde de la misma.

- El programa accede a los siguientes registros: RCC_AHB1ENR, GPIOD_MODER, GPIOD_OSPEEDR,  STK_CTRLSTK_LOAD. 

- En este programa se genera un retardo mediante el temporizador del sistema, SysTick.

- SysTick es un temporizador pensado para sistemas operativos en tiempo real, pero también puede ser usado como contador descendente estándar. Dispone de: un contador descendente de 24 bits, capacidad de auto-recarga, un sistema de generación de interrupciones cuando el contador llega a 0 y una fuente de señal de reloj programable.


- SysTick cuenta de manera descendente desde el valor de carga hasta 0, recarga ese valor en el registro STK_LOAD en el siguiente flanco de reloj y entonces cuenta descendentemente en los siguientes ciclos de reloj. Es decir, cuenta cíclicamente desde el valor cargado en STK_LOAD hasta 0.

- config_sysTick_retardo(): efectúa una llamada a la función encargada de configurar SysTick.

- retardo_ms(1000): llama a la función que crea el retardo valiéndose de SysTick. En este caso, la función llamada crea un retardo de 1000 milisegundos. 


- SysTick->CTRL &= ~(SysTick_CTRL_CLKSOURCE_Msk): selecciona la fuente de la señal de reloj para SysTick. En este caso, poniendo a ‘0’ el bit CLKSOURCE del registro STK_CTRL (bit 2), se decide que la señal de reloj de SysTick sea AHB / 8, que es la frecuencia a la salida del prescaler AHB dividida entre 8. En la entrada anterior del blog se había elegido una frecuencia para AHB de 96 MHz. La constante SysTick_CTRL_CLKSOURCE_Msk está definida en el archivo core_m4.h, al igual que el resto de constantes relacionadas con SysTick y empleadas en este programa.


- SysTick->LOAD = 12000 – 1: carga el valor ‘11999’ en el registro STK_VAL (bits 23:0, RELOAD). Este valor se carga en el registro STK_VAL cuando el contador está habilitado y alcanza 0. El valor de RELOAD puede ser cualquiera en el rango comprendido entre ‘0x00000001’ y ‘0x00FFFFFF’.


- El valor de RELOAD se calcula según su uso: para generar un temporizador multidisparo con un periodo de N ciclos de reloj del procesador, hay que usar un valor de RELOAD de N-1. Por ejemplo, si se requiere una interrupción de SysTick cada 100 pulsos de reloj, RELOAD tiene que valer 99. 


- Según el apartado 10.1.2 del documento
RM0383 Reference Manual, el valor de calibración está fijado en 10500, lo que da una referencia de la base de tiempos de 1 ms para una frecuencia de reloj de SysTick de 10,5 MHz (HCLK/8, con HCLK ajustado a 84 MHz). En este programa, el valor de RELOAD hace que SysTick cuente 12000 ciclos de una señal de reloj de 12 MHz; para efectuar esta operación es necesario 1 milisegundo de tiempo.

- SysTick->CTRL |= SysTick_CTRL_ENABLE_Msk: habilita el contador, escribiendo un ‘1’ en el bit ENABLE del registro SysTick->CTRL. Cuando este bit está a ‘1’ el contador carga el valor de RELOAD desde el registro STK_LOAD y empieza a contar de manera descendente. Al llegar a 0, pone el bit COUNTFLAG (bit 16) a ‘1’ y opcionalmente activa la petición de excepción, dependiendo del valor de TICKINT, que es el bit 1 del registro STK_CTRL (en este ejemplo no se habilita la petición de excepción). Después de esto, carga el valor de RELOAD otra vez y sigue contando.


- while ((SysTick->CTRL & SysTick_CTRL_COUNTFLAG_Msk) == 0) {}: esta instrucción sirve para esperar hasta que el valor del bit COUNTFLAG del registro STK_CTRL sea igual a ‘1’. El bit COUNTFLAG devuelve un ’1’, si la cuenta del temporizador ha llegado a ‘0’; cuando sucede esto, que es cada milisegundo, se decrementa en una unidad el valor numérico contenido en la variable num_ms.


- SysTick->CTRL &= ~(SysTick_CTRL_ENABLE_Msk): deshabilita el contador, poniendo a ‘0’ el bit ENABLE del registro SysTick_CTRL. Esto es necesario porque mientras este bit esté habilitado el contador seguirá contando de manera cíclica. 



➤ Registros empleados

Las siguientes imágenes representan una parte de los registros utilizados en el programa y en ellas están señalados los bits que éste modifica o consulta. Únicamente aparecen los registros relacionados con la generación del retardo, los demás pueden encontrarse en las primeras entradas del blog.

Para más información, ver los documentos RM0383 Reference Manual y PM0214 Programming manual.