LusoRobótica - Robótica em Português
Sistemas específicos => Arduino / AVR => Tópico iniciado por: MAntunes em 02 de Abril de 2018, 21:42
-
Boas malta!
Tenho algumas dev-boards iguais a esta: https://www.ebay.com/itm/Digispark-Kickstarter-ATTINY85-Arduino-General-Micro-USB-Development-Board/351877226756?hash=item51ed846104:m:my8ETikA-fqEa93bidyNkmg e gostava de as programar sem usar o Arduino, ou seja, em linguagem C usando os registos do micro-controlador.
Qual a maneira mais simples de o fazer em Windows? Tudo o que encontro é usando o Arduino.
Cumprimentos,
Miguel
-
Não tenho experiência com os digispark (apesar de ter alguns na gaveta), mas deve ser o mesmo que com quaquer outro AVR, tudo depende do que queres:
Atmel Studio
Platform.io
A IDE de teu gosto (Visual Studio Code/Eclipe/CodeBlocks/Vim :) ) + AVR GCC.
Bareback (editor de texto + AVR GCC command line)
Para carregar o código no digispark, é usar o programa do micronucleus ( bootloader que vem de origem: https://github.com/micronucleus/micronucleus)
-
Brinquei com um digispark destes http://www.ebay.com/itm/232698261306 e não gostei, principalmente porque têm um clock speed marado. Acabei por usar um chip isolado. Mas fiz tudo pelo arduino IDE usando o core do Dr. Azzy, que para o meu caso foi porreiro porque permite fazer PWM em 3 pinos simplesmente com o AnalogWrite sem ter que andar a inventar.
http://drazzy.com/package_drazzy.com_index.json
@jm_araujo. Sem usar o arduino ide onde a programação pode ser feita com o Arduino as ISP como é que se programa o attiny85 ? Avrdude e um programador do estilo do USBASP ?
-
Se vier com o bootloader (como tem os digispark) deve dar para programar diretamente com o utilitário que linkei.
Se for solto ou sem bootloader, com um USBASP, ou com outro arduino qualquer com o sketch "arduinoISP" (que vem nos exemplos) carregado.
Depois é usar o avrdude, ou para quem não quiser mexer na linha de comandos, há a GUI "AVRDudess" que é a que costumo usar. O USBASP é nativo nos suportados, o ArduinoISP funciona como um "stk500v1".
-
No outro dia andei a atualizar o bootloader dos meus Nanos (*) e gostei da experiência de programar com o USBASP via o ICSP. Como agora estou a usar um bootloader que só tem 512 bytes, não vale a pena, mas para quem necessitava dos 2K que o bootloader antigo usava parece ser uma boa solução para programar os .ino sem ter um bootloader.
(*) para quem não reparou, a ultima versão do Arduino IDE deixou "de repente" de falar com os Nanos. Tem que se alterar o tipo do board para um que diz "old bootloader" ou então atualizar o bootloader.
-
Boas malta! Obrigado a todos pela ajuda!
Guiei-me por este link: https://blog.ithasu.org/2014/12/blinking-a-digispark-without-arduino-ide/ e consegui programar o ATtiny85.
Usei AVR-GCC com o Sublime Text e o Micronucleus para enviar o .hex.
Alguém sabe de algum sítio onde possa encontrar exemplos de código para o ATtiny85? Principalmente do que toca a I2C e ao WDT.
-
A datasheet não é assim tão grande ;D
-
O que mesmo que todos os outros atmegas..
Para i2c, pete fleury i2c lib, implementa tanto em software como em hardware, é só escolher o ficheiro e usar.
-
Obrigado!
O módulo I2C do ATtiny85 é diferente do dos ATmega por isso essa biblioteca apenas funcionaria por software.
Encontrei esta app-note que parece interessante: http://www.microchip.com//wwwAppNotes/AppNotes.aspx?appnote=en590897
-
O código do controlador da diffTrike tem rotinas para I2C slave, testado no ATtiny26 mas é suposto funcionar no ATtinyx5 tb. O código base tirei algures da net (já não me lembro da fonte, mas nem deve ser mto difícil descobrir), e depois fiz umas alterações, nomeadamente adicionei um byte de "checksum" e um timeout na espera pelo fim do start-condition.
Esta lib (i2c_slave.c/.h) simula um conjunto de registos I2C, que o master escreve e lê a qualquer momento, sendo que esse processo ocorre "em background" - há uma função que indica se algum registo I2C foi alterado pelo master.
No main.c podes ver como é usada, e o projecto tb usa o watchdog, que deve ser igual no ATtinyx5. Na diffTrike temos um Pi a falar I2C a 500Kbit/s com 2 controladores a correr este código em ATtiny26.
https://github.com/vnevoa/DiffTrike/tree/MarkIV_RasPi_NJAY/Electronics/PowerBridge/sw
-
Boas malta,
Antes de mais obrigado Njay!
Estava a tentar fazer comutar um LED a cada segundo com a interrupção do Timer 1 mas não estava a ter sucesso em acertar com o tempo.
Como se pode ver no Makefile a velocidade do CPU está a 1MHz. Utilizei um prescaler de 8192. No registo de comparação do Timer1 (OCR1A) coloquei 122. Penso estar tudo bem calculado.
Abaixo tenho tanto o código como o Makefile usados.
Há alguma coisa que esteja mal implementada?
Código
#include <avr/io.h>
#include <avr/interrupt.h>
#define PIN_LED PB1
inline void configTimer1(void);
inline void configIO();
int main(void)
{
configIO();
configTimer1();
while(1);
return(0);
}
inline void configTimer1(void)
{
TCCR1 |= (1 << CTC1); //clear timer on compare match
TCCR1 |= (1 << CS13) | (1 << CS12) | (1 << CS11); //8192 prescaler
OCR1A = 122; //compare value
TIMSK |= (1 << OCIE1A); //enable interrupt
sei();
}
inline void configIO(void)
{
DDRB |= (1 << PIN_LED); //PIN_LED as output
}
ISR(TIMER1_COMPA_vect)
{
PORTB ^= (1 << PIN_LED);
}
Makefile
DEVICE = attiny85
CLOCK = 1000000
OBJECTS = main.o
UPLOAD = micronucleus --run
COMPILE = avr-gcc -Wall -Os -DF_CPU=$(CLOCK) -mmcu=$(DEVICE)
all: main.hex
.c.o:
$(COMPILE) -c $< -o $@
flash: all
$(UPLOAD) main.hex
clean:
rm -f main.hex main.elf $(OBJECTS)
main.elf: $(OBJECTS)
$(COMPILE) -o main.elf $(OBJECTS)
main.hex: main.elf
rm -f main.hex
avr-objcopy -j .text -j .data -O ihex main.elf main.hex
avr-size --format=avr --mcu=$(DEVICE) main.elf
-
• Bit 7 – CTC1 : Clear Timer/Counter on Compare Match
When the CTC1 control bit is set (one), Timer/Counter1 is reset to $00 in the CPU clock cycle after a compare
match with OCR1C register value. If the control bit is cleared, Timer/Counter1 continues counting and is unaffected
by a compare match.
Já agora, umas dicas.
Podes usar a macro _BV(x) (BitValue) em vez do shift:
(1 << PIN_LED) = _BV(PIN_LED)
Em vez de um loop infinito a comer energia, podes fazer um loop com sleep (se não estou em erro, sem configurar mais nada, ele fica no modo de sleep mais "leve", que desbloqueia a cada interrupção que ocorra):
while (1) sleep_mode();
Poupas espaço de código se declarares as tuas funções e variáveis globais com "static", e a main podes declarar assim (para uma poupança extra):
int __attribute__((noreturn)) main(void)
O projecto da diffTrike usa quase todos esses truques (o ATtiny26 só tem 2KB de flash de programa, e olha só o que lá coube :)), podes referir-te a ele quando precises de saber.
-
Obrigado por todas as dicas!
Mudei o registo para o que disseste, mas continua tudo na mesma! Tenho o LED a comutar a mais ou menos 60.5ms.
O código é agora o seguinte:
#include <avr/io.h>
#include <avr/interrupt.h>
#define PIN_LED PB1
inline void configTimer1(void);
inline void configIO();
int main(void)
{
configIO();
configTimer1();
while(1);
return(0);
}
inline void configTimer1(void)
{
TCCR1 |= (1 << CTC1); //clear timer on compare match
TCCR1 |= (1 << CS13) | (1 << CS12) | (1 << CS11); //8192 prescaler
OCR1C = 122-1; //compare value
TIMSK |= (1 << OCIE1A); //enable interrupt
sei();
}
inline void configIO(void)
{
DDRB |= (1 << PIN_LED); //PIN_LED as output
}
ISR(TIMER1_COMPA_vect)
{
PORTB ^= (1 << PIN_LED);
}
Como posso ver a que velocidade o microcontrolador está a correr efetivamente?
-
Não precisas de mudar nenhum registo ou fuse no attiny para mudar o clock do mesmo? O compilador trata mesmo disso só alterando um define?
É que 16 (MHz)/1MHz*60.5ms= 990ms , aprox o 1 segundo que tu querias, mas se calhar é só coincidência.
Edit:
Fui espreitar à datasheet. Não vejo no código nenhuma alteração ao Clock Prescaler (CLKPS), e o CKSEL é fuse (se desse para mudar ia ser difícil comunicar com o bootloader).
-
O define do compilador é da responsabilidade do programador, o programador é que tem que saber a frequência do clock. Deve ser 16MHz, porque já vi que isso tem um bootloader com interface USB em software, e não é a 1MHz que o gajo consegue implementar o protocolo.
De qualquer forma... precisas de ir à procura da documentação dessa board ;)
Podes saber a que velocidade está a correr, lendo os "fuse bits" e vendo na datasheet qual é a configuração que está activa no AVR. A ferramenta que usas para programar o chip de certeza que dá para ler/escrever também os fuses (o avr-dude dá). Claro, também podes fazer toogle de um pino e ver com um contador ou osciloscópio, fazendo a conversão adequada.
Não te recomendo mudar o clock (alterando os fuse bits), porque depois perdes a possibilidade de usar o USB, incluindo carregar código (a não ser que o bootloader se reconfigure para 16MHz no arranque... acho que isso é possível no ATtinyx5, mas para ter a certeza só experimentando ou vendo o código).
-
Obrigado novamente a todos!
Pois, fiz mais uns testes e realmente o ATtiny está a correr a 16MHz (mais coisa menos coisa, não me parece que este oscilador seja muito certinho). Tenho que arranjar maneira de ler os fuses e ver o que realmente lá está a correr!
É um pouco mau estar preso ao bootloader nestas placas.
Cumprimentos!
-
Vê o registo
CLKPR – Clock Prescale Register
Mexendo aí, que é um registo volátil, deve dar para mudar o clock para 1 ou pelo menos 2MHz.
Quando não tens um cristal, ressonador ou gerador externo de clock, o gajo está a usar o clock RC interno, e esse tem uma tolerância grande, sim. Pode ser ajustado com o registo
OSCCAL – Oscillator Calibration Register
-
Olá pessoal, caso alguém compre somente a board para ser adicionado o Attiny85:
http://s.click.aliexpress.com/e/UrJIqnYBe (http://s.click.aliexpress.com/e/UrJIqnYBe)
Tem um artigo que explica como proceder:
http://www.hackeduca.com.br/attiny-com-o-bootloader-do-digispark-e-paperduino2/