Inicio Crónica 2: ATTiny10: Referencia Rápida
Entrada
Cancelar

Crónica 2: ATTiny10: Referencia Rápida

Esta es una guía de referencia para comenzar a desarrollar rápidamente con el microcontrolador Attiny10 de Atmel. El fin de la guía es recopilar y resumir los recursos que he encontrado para configurar el entorno de desarrollo, programar y utilizar algunas funciones del Attiny10. Iré actualizando la guía conforme vaya implementando y utilizando las funciones. Todas las referencias con su descripción se encuentran al final del documento.

Hoja de Datos del Attiny10:

El recurso principal es la hoja de datos del microcontrolador 1 allí se encuentran las descripciones principales de los registros que se deben modificar para acceder a las distintas funciones, y una explicación (muy técnica) de todos los sistemas del integrado. Si se quiere modificar algo de esta guía es indispensable la hoja de datos.

Configurar PlatformIO IDE para el attiny10:

El IDE (¿o complemento?) que yo prefiero usar para desarrollar en Arduino, Espressif y demás es PlatformIO con Visual Studio Code, entonces esta guía está enfocada a configurar PlatformIO para programar el Attiny.

Instalar la plataforma de Atmel AVR en PlatformIO:

El primer paso para configurar PlatformIO es ir a la página de inicio y entrar en “Platforms” a la izquierda de la página de inicio, seleccionar “Embedded” en la parte de arriba, y buscar “Atmel AVR” en la barra “Filter platforms by name…”. Luego, cuando aparece la plataforma, dar click en el nombre. En la página de la plataforma dan una breve descripción, y luego se puede elegir la versión a instalar. Personalmente, la única versión que me ha funcionado es la 3.0.0 .

PlatformioAtmelAVRInstall Procedimiento para Instalar la Plataforma Atmel AVR en PlatformIO.

Incluir el Attiny10 en la librería Atmel AVR:

La plataforma Atmel AVR no trae por defecto el attiny10 en su base de datos, entonces hay que añadirlo manualmente creando un archivo json en una carpeta llamada “boards” en la carpeta donde esté instalado PlatformIO. En mi caso, en Linux esta carpeta es ~/.platformio. Dentro de esta carpeta es donde va el archivo attiny10.json. Desde la terminal el proceso se ve así:

1
2
3
4
mkdir ~/.platformio/boards
nano ~/.platformio/boards/attiny10.json

El contenido del archivo debe ser2:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16

{
  "build": {
    "f_cpu": "1000000L",
    "mcu": "attiny10"
  },
  "name": "ATtiny10",
  "upload": {
    "maximum_ram_size": 32,
    "maximum_size": 1024,
    "protocol": "usbasp"
  },
  "url": "http://www.atmel.com/devices/ATTINY10.aspx",
  "vendor": "Atmel"
}

En el explorador de archivos se aprecia luego el archivo en la carpeta que le corresponde:

attiny10jsonpng Archivo “attiny10.json” en la Carpeta “~/.platformio/boards”.

Después de crear el archivo json se debe reiniciar Visual Studio Code, o abrir una nueva ventana desde el menú contextual en la parte superior, para que los cambios tengan efecto.

Crear un proyecto con el attiny10:

Ahora, al haber añadido el archivo del microcontrolador, PlatformIO deja crear un proyecto con el attiny seleccionado como plataforma. Para continuar con la guía es necesario crear un proyecto. Es útil que el primer proyecto sea una plantilla para tener de referencia luego. Para crear un proyecto, en la página de inicio de PlatformIO hay que dar click abajo de “Quick Access” donde dice “+ New Project”, esto abre el menú de creación de proyecto, luego en el menú, se escribe el nombre del proyecto en el espacio “Name”, y en “Board” se busca por “attiny10”. Finalmente se da click en “Finish” y PlatfomIO se encarga de crear las carpetas y archivos del proyecto.

PlatformioAtmelAVRInstall Procedimiento para Crear un Nuevo Proyecto con el Attiny10 en PlatformIO.

Configurar PlatformIO para programar el attiny10:

Ahora la guía va a dar un salto un poco brusco, pero este paso tiene que ver con la configuración de PlatformIO. Para programar el attiny10 hay 2 métodos oficiales: uno es usar el adaptador oficial de atmel (Atmel AVRISP MKII), y el otro es usar una placa que usa un chip de arduino programado para sacar las conexiones y que tiene el firmware necesario para programar el attiny (USBASP AVR Programmer). Yo no voy a usar ninguna. El AVRISP es caro, y el USBASP genérico generalmente tiene una versión desactualizada del firmware, entonces no puede programar el attiny10, se deben comprar 2, y usar uno para actualizarle el firmware al otro, y poder programar el attiny. Existe otro método no oficial que utiliza una placa genérica con un FTDI, generalmente un FT232RL. Para este método hay que conectar el integrado de una manera específica3 4, hacer unos cambios dentro de PlatformIO, y descargar ciertas librerías, esta sección se centra en esta segunda parte.

Para utilizar la placa FTDI para programar el attiny10 primero se debe crear una definición en el archivo avrdude.conf. Este es el archivo que le dice a la librería que envía el firmware desde la computadora al microcontrolador (avrdude) cómo tengo conectado el chip, y con qué placa y método quiero programarlo. La definición de este archivo se encuentra en github5. Se puede copiar a un editor de texto, o descargar este archivo, pero es importante tenerlo completo. Después de copiarlo, o descargarlo, hay que agregarle una nueva definición 3 listando la placa que se va a usar para programar el attiny, y a qué pin de la FTDI está conectado cuál pin del attiny. Este archivo se puede guardar en la carpeta del proyecto. Esa definición queda así3:

1
2
3
4
5
6
7
8
9
10
11
12
# FTDI attiny10:
programmer 
  id	= "dasaftdi";
  desc	= "FTDI serial port banging, reset=rts sck=dtr mosi=txd miso=cts";
  type	= "serbb";
  reset	= ~7;
  sck	= ~4;
  mosi	= ~3;
  miso	= ~8;
;

La descripción se debe colocar en medio de las demás definiciones que empiezan como “programmer….” no importa el orden, pero debe estar junto a las demás definiciones. En esta imagen se muestra el archivo avrdude.conf ya modificado:

AVRDUDE.CONF Captura del Archivo avrdude.conf ya Modificado.

Ahora, el último paso de la configuración de PlatformIO para programar el attiny es modificar el archivo platformio.ini. Cuando se abre el proyecto, en el panel izquierdo se listan todos los archivos del proyecto, incluido uno con el nombre platformio.ini. Este archivo describe la configuración del ambiente y del proyecto para que el microcontrolador se pueda comunicar con la computadora. Hay que agregar en ese archivo todos los cambios que se han hecho en los archivos anteriores. Al final el archivo debe de quedar así:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
; PlatformIO Project Configuration File
;
;   Build options: build flags, source filter
;   Upload options: custom upload port, speed and extra flags
;   Library options: dependencies, extra library storages
;   Advanced options: extra scripting
;
; Please visit documentation for the other options and examples
; https://docs.platformio.org/page/projectconf.html

[env:attiny10]
platform = atmelavr
board = attiny10
upload_protocol = custom
upload_port = /dev/ttyUSB0
upload_flags =
  -C
  /ruta/al/archivo/avrdude.conf
  -p
  t10
  -c
  dasaftdi
  -P
  $UPLOAD_PORT
upload_command = avrdude $UPLOAD_FLAGS -U flash:w:$SOURCE:i -v

Lo único que se debe modificar es en la línea “upload_flags” , debajo de “-C”, es la ruta donde se guardó el archivo avrdude.conf, y después en la línea “upload_port”, se indica la ruta al puerto donde está conectada la placa FTDI. En linux la ruta siempre será algo como /dev/ttyUSBX donde X representa el número de puerto USB al que está conectada la placa, generalmente es 0, 1, 2…. En Windows la ruta es COMX donde X es el puerto USB donde está conectada la placa. X también empieza en 0, 1, 2….

Conectar el attiny10 a la placa FTDI para programarlo:

Según las definiciones que se hicieron en los pasos anteriores, las conexiones para el attiny10 con la placa FTDI son:

Pin attiny10Pin FTDI
TPIDATACTS
TPICLKDTR
RESETRST
TPIDATATXD a través de R=1KΩ
GNDGND
+5V+5V

Las conexiones se pueden ver en este diagrama:

DiagramaFTDI-ATTINY10 Diagrama de Conexiones Entre el attiny10 y la Placa FTDI

Es importante destacar que el attiny10 sólo se puede programar con 5V. (con el AVRISP se puede programar con 12V en un caso MUY especial.)

Bloques de código para usar las funciones principales:

El attiny10 tiene ciertas funciones que están disponibles solo en ciertos pines. Los tres pines principales son PB0, PB1, y PB2. El pin PB3 (RESET) no puede manejar mucha corriente como salida digital, entonces es mejor sólo usarlo como entrada digital o analógica. Las funciones son accesibles a través de registros. Hay que redefinir estos registros para poder usar las funciones, el generador de señales, o el adc por ejemplo.

Pinoutattiny Registros Asignados a Cada Pin del Attiny10.

Estructura del archivo de código principal main.cpp:

Este es el archivo principal y esencial donde se ubica la función main para ejecutar en el attiny. El archivo debe llamarse “main.cpp” y debe estar en la carpeta “src” dentro de la carpeta del proyecto de PlatformIO.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#include <avr/io.h>
#include <stdlib.h>

int main{

  //Código para ejecutar 1 vez. 

  while(true){
    // Loop principal.
  }

  return 0;
}

Pines digitales: entrada y salida.

Para definir cuál pin debe ser entrada y cuál salida, se debe redefinir el registro DDRB. Esto es importante si se quiere escribir o leer del pin digitalmente, o analógicamente. Para las funciones de PWM, y ADC se debe configurar correctamente. Los primeros 4 bits corresponden a cada uno de los pines del attiny: el DDRB0 al PB0, el DDRB1 al PB1, el DDRB2 al PB2, y el DDRB3 al PB3. Escribir un 1 en el bit correspondiente cambia el pin a modo salida. Por defecto, todos los pines se inician como entradas. Entonces para cambiar la dirección del pin PB1 a salida, por ejemplo, escribiría esto en la función main de mi main.cpp:

1
2
3
4
5
6
7
8
int main(){

  DDRB = 0b0010; // Definir pin PB1 como salida. 

  return 0;
}

El prefijo 0b le indica al compilador que estoy entregándole un byte. Puedo omitir los 4 últimos bits del byte porque no representan nada.

DDRB[0:7] Registro de 8 bits:

Bit 7Bit 6Bit 5Bit 4Bit 3Bit 2Bit 1Bit 0
xxxxDDRB3DDRB2DDRB1DDRB0

Cambiar cualquier DDRB[0:3] a 1 cambia el sentido del pin correspondiente PB[0:3] a salida.

Leer Pin Digital:

En cualquier momento el registro PINB contiene todos los estados digitales de los 4 pines del attiny. Para leer el estado de un pin digital puedo pasarle a otra variable el valor del registro, y accesarla desde ahí.

PINB[0:7] Regsitro de 8 bits:

Bit 7Bit 6Bit 5Bit 4Bit 3Bit 2Bit 1Bit 0
xxxxPINB3PINB2PINB1PINB0

Escribir al pin Digital:

Para escribir en cualquiera de los pines digitales simplemente hay que modificar el registro PORTB. Hay que notar que al modificar el registro se escribe a todas las salidas digitales a la vez.

PORTB[0:7] Registro de 8 bits:

Bit 7Bit 6Bit 5Bit 4Bit 3Bit 2Bit 1Bit 0
xxxxPORTB3PORTB2PORTB1PORTB0

Aquí un ejemplo adaptado de (6):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
#include <avr/io.h>
#include <stdlib.h>
#include <util/delay.h>

#define OUTPUT 1
#define INPUT 0

void pinMode(uint8_t pin, bool mode){
    if(mode){
        DDRB = DDRB | 1 << pin;
    }else{
        DDRB = DDRB | 0 << pin;
    }
}

int main(){

    pinMode(1, OUTPUT); // Definir pin PB1 como salida. 

    PORTB = 0b0010; // Escribir un 1 al pin PB1, y un 0 al resto.

    _delay_ms(500); // Esperar 0.5s 

    PORTB = 0b0000; // Escribir un 0 a todos los pines; 

    uint8_t digitalRead = PINB; // Leer el estado digital de todos los pines. 


return 0;
}


PWM.

Hay varios tipos de PWM disponibles en el attiny10:

  • FastPWM: para frecuancias altas.
  • Phase Correct PWM: PWM de fase exacta.
  • Phase and Frequency Correct PWM: PWM de frecuencia y fase exactas.

La configuración de los timers que manejan el pwm se hace mediante un registro de 16 bits. Primero se modifica el byte inferior y luego el byte superior. El byte inferior es TCCR0A y el superior es TCCR0B. Para cambiar el ancho del pulso se requiere configurar TCCR0A y TCCR0B en alguno de los modos de PWM y en alguna de las resoluciones. Ya configurado, el ancho de pulso se cambia modificando el registro OCR0A, u OCR0B dependiendo de cuál pin se esté utilizando como salida

wavegenModes1 Modos de Generación de Ondas y PWM en el attiny10 (1) desde la hoja de datos.

wavegenModes1 Modos de Generación de Ondas y PWM en el attiny10 (1) desde la hoja de datos.

wavegenModes1 Descripción del Registro TCCR0A del attiny10 desde la hoja de datos.

wavegenModes1 Descripción del Registro TCCR0B del attiny10 desde la hoja de datos.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
#include <avr/io.h>
#include <stdlib.h>
#include <util/delay.h>

int main(){

    TCCR0A = 2<<COM0B0 | 3<<WGM00; // PWM 10 bits, pin PB1
    TCCR0B = 0<<WGM02 | 1<<CS00;   // Prescaler 1 
    DDRB = 0b0010;                 // Definir PB1 como salida
    
    OCR0B = 10;

    while (true)
    {
        if(OCR0A < 250){
            OCR0B += 1;
        }else{
            OCR0B = 0;
        }
        _delay_ms(10);
    }
    


}

ADC.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
#include <avr/io.h>
#include <stdlib.h>
#include <util/delay.h>

int main(){

    TCCR0A = 2<<COM0B0 | 1<<WGM00; // 10-bit PWM on OC0B (PB1), non-inverting mode
    TCCR0B = 1<<WGM02 | 1<<CS00;   // Divide clock by 1
    DDRB = 0b0010;                 // Make PB0 an output
    
    ADMUX = 1<<MUX1;               // ADC2 (PB2)
    ADCSRA = 1<<ADEN | 3<<ADPS0;   // Enable ADC, 125kHz clock
    

    while (true){
        
        ADCSRA = ADCSRA | 1<<ADSC;     // Start
        while (ADCSRA & 1<<ADSC);      // Wait while conversion in progress
        int temp = ADCL;               // Copy result to temp
        if(temp < 50){
            OCR0B = 0;
        }else if(temp < 250){
            OCR0B = temp;
        }

    }
    



}

Referencias:

Esta entrada está licenciada bajo CC BY 4.0 por el autor.
Etiquetas populares