2020/06/08

Primer programa en un ATtiny85 bare y luego ArduinoIDE con SoftUART

Bare pues es el chip sólito que voy a poner en mi propio circuito, no sé si hay manera de hacerlo utilizando ArduinoIDE como he hecho con un ATMega328p en otro ejercicio.

Como siempre, podría buscar todo en Internet y como siempre lo evitaré.

Compilación


Me voy a apoyar en un Makefile que tenía para ATMega328p, para compilar:

$(GCCPATH)/avr-gcc -mmcu=attiny85 -Wall -std=gnu99 -Os -o blink.elf blink.c && \
$(GCCPATH)/avr-objcopy -j .text -j .data -O ihex blink.elf blink.hex

Para la elección de mcu, es attiny85, sale de la documentación de gcc.

Para el blinky tendría que elegir el pin, ok, por default son GPIO:


ATtiny85 pinout

Este sería un blinky en PB0, el pin 5:

#define F_CPU 1000000UL
#include <avr/io.h>
#include <util/delay.h>

int main (void) {
    DDRB |= 0x00111111;
    while(1) {
        PORTB ^= 0x00000001;
        _delay_ms(500);
    }
}

Nos falta ver si funciona, para ello falta la...

Programación


Este es el comando para programar el chip:

BURNER=usbasp
AVRDEVICE=???
FUSES=???
avrdude -p $(AVRDEVICE) -c $(BURNER) -e -F -U flash:w:blink.hex -U $(FUSES) -C /etc/avrdude.conf

Falta definir AVRDEVICE y FUSES, por ahora voy a probar sin los FUSES.


Nuevamente, la documentación nos dice que es t85 y parece funcionar ok:


~ $ make burn
avrdude -p t85 -c usbasp -e -F -U flash:w:blink.hex  -C /etc/avrdude.conf
avrdude: warning: cannot set sck period. please check for usbasp firmware update.
avrdude: AVR device initialized and ready to accept instructions

Reading | ################################################## | 100% 0.01s

avrdude: Device signature = 0x1e930b (probably t85)
avrdude: erasing chip
avrdude: warning: cannot set sck period. please check for usbasp firmware update.
avrdude: reading input file "blink.hex"
avrdude: input file blink.hex auto detected as Intel Hex
avrdude: writing flash (86 bytes):

Writing | ################################################## | 100% 0.09s

avrdude: 86 bytes of flash written
avrdude: verifying flash memory against blink.hex:
avrdude: load data flash data from input file blink.hex:
avrdude: input file blink.hex auto detected as Intel Hex
avrdude: input file blink.hex contains 86 bytes
avrdude: reading on-chip flash data:

Reading | ################################################## | 100% 0.06s

avrdude: verifying ...
avrdude: 86 bytes of flash verified
avrdude: safemode: Fuses OK (E:FF, H:DF, L:62)

avrdude done.  Thank you.

Lo ponemos en el protoboard y...

Funciona, pero es muy básico, tendría que pasar al siguiente nivel, que es por ejemplo leer el sensor interno de temperatura y enviarlo por el puerto serial... salvo que ATtiny85 no tiene puerto serial, hay que implementarlo por software.

Al llegar a este punto se abren varias posibilidades:

Continuando con bare metal, implementar yo la SoftUART


Mmh, me mata, esto es un desvío dentro de otro proyecto.

Buscar una librería apta para bare metal


Parece que todo el mundo desarrolla para el entorno de ArduinoIDE, lo mejorcito que hallé sólo transmite.


Incorporar a mi bare metal librerías de arduino.


Lo primero es pasar de c a c++, no hay problema, que use avr-c++ en lugar de avr-gcc y que quitar -std=gnu99:


$(GCCPATH)/avr-c++ -mmcu=attiny85 -Wall -Os -o blink.elf blink.c && \
$(GCCPATH)/avr-objcopy -j .text -j .data -O ihex blink.elf blink.hex

El problema es cuando ponés el primer #include <>, no es un buen camino. Además, no entiende al ATtiny85.

Usar ATtiny85 desde ArduinoIDE


Para esto tuve que recurrir a Internet, reproduzco:

Primero agregás de dónde bajar las descripciones de los boards:

Arduino -> Preferences -> Additional Board Managers URLs

Agregar con coma adelante si ya tenés algo:

https://raw.githubusercontent.com/damellis/attiny/ide-1.6.x-boards-manager/package_damellis_attiny_index.json


Luego agregás una nueva descripción:

Tools-> Board-->Boards Manager -> filtrar con attiny

Seleccionar e instalar Attiny de David. A Mellis

Finalmente, en tu proyecto elegís ATiny85, NO olvides elegir procesador ATtiny85 pues viene como ATtiny25 que no le entra nada. No toqué el clock por ahora.

El programa del ejemplo del tutorial y lo modifiqué pensando en lo que voy a necesitar, el serial y tres pines (dos termómetros y un PWM, tema aparte.

#include <SoftwareSerial.h>

const byte rx = 0;
const byte tx = 1;
char data;

SoftwareSerial swSerial(rx, tx);
void setup() {  
  pinMode(rx,INPUT);
  pinMode(tx,OUTPUT);
  DDRB |= B00011100;
  delay(5000);
  swSerial.begin(9600);
  swSerial.println("BEGIN");
  PORTB &= B11100011;
 delay(1000);
  PORTB |= B00000100;
  swSerial.println("led 0");
  delay(1000); 
  PORTB |= B00001000;
  swSerial.println("led 1");
  delay(1000); 
  PORTB |= B00010000;
  swSerial.println("led 2");
  delay(1000);

  swSerial.println("limpiando");
  PORTB &= B11100011;
  delay(1000);
}

void loop() {
  if(swSerial.available() > 0){
    data = swSerial.read();

    switch (data) {
      case '5':
         PORTB &= B11000011;
         swSerial.println("limpiando");
      break;

      case '0':
         PORTB |= B00000100;
         swSerial.println("led 0");
      break;
      case '1':
         PORTB |= B00001000;
         swSerial.println("led 1");
      break;
      case '2': 
         PORTB |= B00010000;
         swSerial.println("led 2");
      break;

      default:
        swSerial.println("mi no entender");
      break;
    }
  }
}
El reset va a 5v, lo puse con una resistencia para poder activarlo cortando a GND. Entiendo que si quisiera usar el reset como GPIO, se me dificultaría volver a programarlo, veremos...

No hay comentarios:

Publicar un comentario