LusoRobótica - Robótica em Português
Sistemas específicos => Arduino / AVR => Tópico iniciado por: Electropepper em 16 de Setembro de 2014, 23:54
-
Estou a tentar imprimir no terminal do PC a string "Hello", a unica coisa que me sai é H ou He outras vezes lixo, e apenas quando o ligo.
Já googlei dezenas de exemplos e passei horas a ler o datasheet, estou completamente encalhado e é provavelmente alguma coisa mesmo á minha frente.
O micro é o atmega328p.
Já agora aqui ficam os fuses lidos pelo avrdude : avrdude: safemode: Fuses OK (H:07, E:D9, L:E2)
Aqui fica o código :
#define F_CPU 1000000UL
#include <avr/io.h>
#include <util/delay.h>
#define UART_BAUDRATE 4800// Set serial baud HERE
#define BAUD_PRESCALE (((F_CPU / (UART_BAUDRATE * 16UL))) - 1)
void setup(void);
void USART_Init(void);
void USART_send( unsigned char data);
int main(void) {
setup();
while (1) {
USART_send('H');
USART_send('e');
USART_send('l');
USART_send('l');
USART_send('o');
USART_send('\n');
_delay_ms(4000);
}
return 0;
}void setup(void) {
DDRC = 0x01;
DDRD = 0x00;
// Set clock to 1 MHZ, also necessary to change F_CPU aproprietly
// to take effect in the delay routines.
CLKPR = 0x80;
CLKPR = 0x03;
USART_Init();
}
void USART_Init(void) {
UBRR0H = (uint8_t)(BAUD_PRESCALE>>8);
UBRR0L = (uint8_t)(BAUD_PRESCALE);
UCSR0C = ((1<<UCSZ00)|(1<<UCSZ01));
UCSR0B = (1<<RXEN0)|(1<<TXEN0);
}
void USART_send( unsigned char data){
while(!(UCSR0A & (1<<UDRE0))){};
UDR0 = data;
}
-
UART com oscilador interno nos atmegas é para esquecer, podes calibrar o oscilador interno, mas dado que isso é algo mais complicado e penso que precisas de um programador ISP reconhecido no avr-studio, mete antes um cristal.
No entanto os teus fuses estão configurados para usar um cristal externo, meter o sinal do clock no pino PB0, com espaço para bootloader de 2K, mas sem estar a fazer o salto para o bootloader no reset, divisão do clock por 8 e brown out a 4.3v, combinação meio estranha, estás a usar um cristal, ou não?
-
A velocidade de um atmega com oscilador interno vai funcionar com a frequência programada nos fusebits, mas infelizmente também vai variar bastante com a tensão de alimentação e precisão do oscilador, sem contar com outros factores menos importantes que o UART tolera.
Seja como for o micro tem de levar cristal ou o sincronismo é mentira e tem de se andar a fazer reset constantemente no micro e no UART do pc cada vez que bloqueia a comunicação.
Existem valores de cristais adequados para a comunicação UART, isto para que a variação seja a mais baixa possível.
-
Não estou a usar cristal, mas com esta configuração como está já pisquei um LED sem problemas, e o unico fuse que toquei foi no low fuse para tirar o divisor por 8 que vem de fábrica, tudo o resto está com veio de fábrica.
-
De certeza que isso não era um atmega já programado com um bootloader?
Porque até acho estranho o micro funcionar assim sem um cristal.
-
Não tem nenhum bootloader, usei o avrdude com o buspirate para o programar por SPI, e este chip tem cristal interno, é so usar o presacler para dividir o clock.
-
Página 28 do datasheet :
Default Clock Source
The device is shipped with internal RC oscillator at 8.0MHz and with the fuse CKDIV8 programmed, resulting in
1.0MHz system clock. The startup time is set to maximum and time-out period enabled. (CKSEL = "0010", SUT
= "10", CKDIV8 = "0"). The default setting ensures that all users can make their desired clock source setting
using any available programming interface.
E foi assim que veio, o unico fuse que toquei foi o tal CKDIV8 que desliguei para ter o chip sempre a arrancar a 8.0MHZ certinhos.
-
Usa isto e vê por ti então..
http://www.engbedded.com/fusecalc/ (http://www.engbedded.com/fusecalc/)
Com low fuse de 07 o CKSEL tem o valor de 0111, full swing crystal.
E não tem um cristal interno, tem um oscilador RC interno com uma variação de +/-10 ou +/-20%
Os valores de fábrica é de low: 0x62, high: D9, extended: FF
-
Por acaso foi esse calculator que usei :D.
De qualquer maneira já aqui tenho na mão um crystal de 3.6864Mhz mais logo já esperimento.
Agora fiquei um pouco confuso com os Low Power Crystal Oscillator e os Full Swing Crystal Oscillator,
não estou a perceber bem a diferença e têm configuração de fuse diferentes.
P.s - Sim oscilador RC interno era isso a que me referia.
-
Isto pode não fazer sentido mas eu vendo esse código e tendo esse problema a primeira coisa que tentava era por delays entre os 'sends'.
-
Que software de terminal estás a usar no PC?
É que a última versão do meu favorito (o Bray++ 1.91b - https://sites.google.com/site/terminalbpp/ ) tem um erro que perde caracteres se tiveres os sidepanel "Dec", "Bin" ou "Hex" ligados.
A ultima versão beta (https://sites.google.com/site/terminalbpp/Terminal20140703.zip?attredirects=0) porta-se melhor.
-
Se estás a dizer que alteraste os fusebits para ter um oscilador interno de 8MHz, então no teu código também devias ter alterado a velocidade na 1ª linha onde está 1MHz.
-
Que software de terminal estás a usar no PC?
É que a última versão do meu favorito (o Bray++ 1.91b - https://sites.google.com/site/terminalbpp/ ) tem um erro que perde caracteres se tiveres os sidepanel "Dec", "Bin" ou "Hex" ligados.
A ultima versão beta (https://sites.google.com/site/terminalbpp/Terminal20140703.zip?attredirects=0) porta-se melhor.
Correcto! Perde bytes e fica lento! se tiver tudo selecionado (Dec, Bin, Hex) e enviar um conjunto de bytes, os bytes são mostrados aos "soluços"
Costumo usar o Hercules; é menos intuitivo que o bray++ mas também gosto bastante.
-
Ok agora com o crystal continua basicamente na mesma, entretanto reparei que tinha o fuse, WDTON e tentei ativalo com o comando :
avrdude -p atmega328p -c buspirate -P /dev/ttyUSB0 -U hfuse:w:0x17:m
Agora estraguei tudo, já não consigo programar mais o chip >:(
Agora quando o tento programar ou alterar os fuses recebo :
avrdude -p atmega328p -c buspirate -P /dev/ttyUSB0 -U hfuse:w:0x07:m -F
Attempting to initiate BusPirate binary mode...
avrdude: initialization failed, rc=-2
avrdude: AVR device initialized and ready to accept instructions
avrdude: Device signature = 0x58246b
avrdude: Expected signature for ATmega328P is 1E 95 0F
avrdude done. Thank you.
E pronto já não sai disto, e insistindo reparo que o Device signature está sempre a mudar.
Voltei á estáca -1. :o
-
Para cristais deves SEMPRE usar full swing cristal oscilator, usa um pouco mais de corrente, o low power é mais indicado para frequencias baixas, tipo 32Khz e por ai assim, tambem se pode usar com os ressonadores cerâmicos.
E porque é que querias activar o watch-dog?
É util, mas para aplicações simples é melhor não usar isso, provavelmente está sempre a fazer resets devido ao watch-dog.
Re-confirma todas as conexões do programador.
-
O WDTON estáva ativado ou pensáva eu que sim, eu queria era desactivalo.
De qualquer maneira já vi e revi as ligações, alem disso isto foi imediato a ter acabado de programar os fuses fui tentar programar a flash e já não deu, não acredito que seja das conecções.
Mais alguma sugestão ?
Entretanto é melhor começar a mandar vir mais um :-\
-
Os fuses não estão escandalosos, dado que agora tens um suposto cristal de 3.7Mhz(aprox), e clockDiv por 8, o micro estará a correr a cerca de 460Khz, baixa a velocidade do ISP para 32 ou 64Khz e deverá funcionar, a velocidade de programação deve ser sempre pelo menos 8 vezes inferior á velocidade a que o micro funciona.
-
Nop, nem sequer vacila.....
-
Oscilador externo ou fuse reset no pior dos caos, por maior que seja o erro a programar os fuses, este método é eficaz ::)
-
;D Finalmente, consegui.
Lá tive que ir comprar desta vez 2 atmega328p por via das duvidas, mudei apenas o lfuse para crystal externo de 16MHZ e com o código anterior tenho a porta série a funcionar bem a 9600bps, tentei a 115200 e não deu mas isso fica para depois.
Entretanto reparei numa coisa que pode ser muito perigosa para novatos, o avrdude quando lê os fuses troca o H pelo E, ou seja mostra o valor do efuse no hfuse. Ok não é o bug mais grave que já encontrei mas ainda me deixou a coçar a cabeça durante uns tempos.
Pelo menos na minha versão 6.0.1 instalada pelos repositórios no ubuntu.
Aqui está o bug report, http://avr.2057.n7.nabble.com/bug-43190-confused-fuse-s-td21186.html (http://avr.2057.n7.nabble.com/bug-43190-confused-fuse-s-td21186.html).
-
Isso explica muita coisa...
-
Então podes usar avr8-burn-o-mat é uma interface grafica, que trabalha com winavr que tiveres instalado.
É a mesma coisa do que ir a linha de comandos.
Agora com o problema descoberto já conseguiste por 1º atmega a trabalhar?
-
Yep, agora funciona na perfeição, depois de usar um crystal externo de 16MHZ.
Mas com isto dos fuses por pouco não "parti" outro chip.
Pelo que li sobre o avr8-burn-o-mat, é apenas um interface gráfico para o avrdude, de qualquer maneira não uso GUIs, VIM e makefile chega-me e sobra. Uso apenas o avrdude com a makefile de maneira que só preciso de escrever o comando, make flash, e o resto é automático.
Entretanto estou a construir isto : http://mightyohm.com/blog/2008/09/arduino-based-avr-high-voltage-programmer/ (http://mightyohm.com/blog/2008/09/arduino-based-avr-high-voltage-programmer/), para ver se recupero o outro chip, depois abro outro tópico para partilhar a experiencia ;).
-
São 50€, mas meu rico Dragon e AvrStudio 6.