Dankeschön .
Hallo Kater,
Da ich eher ein praktischer Mensch bin, habe ich das eben auf meinem Dragon ausprobiert, die Wette hättest Du gewonnen, egal welche Werte man in die Register reinschreibt, nach einem Watchdog Reset sind sie wieder auf 0
Gruß Sebastian
Linus TorvaldSoftware is like s e x: its better when its free.
Dankeschön .
Hallo!
Ich brauche mal nochmal Hilfe. Ich habe versucht über RS232 vom PC auf den Controller eine 1 zu senden und dann soll eine LED ausgehen. Das habe ich per Interrupt versucht, doch es funbktioniert leider nicht.
Kann einer mal den Quelltext anschauen und sagen was ich falsch gemacht habe?
Danke!
#include <avr/io.h>
#include <avr/interrupt.h>
#define USART_RXC_vect _VECTOR(14)
#define F_CPU 1000000UL
#define BAUD 9600UL
#define UBRR_BAUD ((F_CPU/(16L*BAUD))-1)
uint8_t buffer;
void uart_init(void)
{
UBRRH = (uint8_t) (UBRR_BAUD>>;
UBRRL = (uint8_t) (UBRR_BAUD & 0xFF);
UCSRB = (1<<TXEN) | (1<<RXEN);
UCSRC = (1<<URSEL)|(1<<UCSZ1)|(1<<UCSZ0);
}
ISR(USART_RXC_vect)
{
UCSRB = (1<<RXEN)|(1<<TXEN)|(1<<RXCIE);
while (!(UCSRA & (1<<RXC)))
buffer = UDR;
}
void led_init(void)
{
if(buffer==0x31)
PORTA=0x01;
else
PORTA=0x00;
}
int main(void)
{
sei();
DDRA = 0xff;
led_init();
uart_init();
}
Hallo booty,
eigentlich steht alles in dem Link, den ich Dir gepostet habe drin, aber egal, ich erkläre es nochmal
1. Problem:
Das ist unnötig, kann eventuell schaden, lass das weg, das ist Aufgabe von Compiler (Präprozessor) den Vektor richtig zuzuordnen.Code:#define USART_RXC_vect _VECTOR(14)
2. Problem:
buffer muß als volatile deklariert werden, warum, sehe link obenCode:uint8_t buffer;
3. ProblemCode:volatile uint8_t buffer;
Ja, hier mußt Du noch den Interrupt einschalten, sonst wird er nie ausgeführt, alsoCode:UCSRB = (1<<TXEN) | (1<<RXEN);
4. Problem, der Interrupt sollte etwa so aussehen:Code:UCSRB = (1<<TXEN) | (1<<RXEN)|(1<<RXCIE);
Du brauchst hier keine flags mehr setzen, oder auf irgendwas warten.Code:ISR(USART_RXC_vect) { buffer = UDR; }
5. Problem, es fehlt wieder die Endlosschleife, mach das etwa so:
So dann schaumal...Code:int main(void) { DDRA = 0xff; uart_init(); sei(); for(;;){ led_init(); } return 0; }
Anmerkung noch Du kannst auch anstatt von 0x31 '1' schreiben, ist vielleicht einfacher zu lesen(wenn man die ASCII Werte nicht im Kopf hat.
Viel Erfolg
@kater,
Kein Problem, der Dragon hat sich auch gefreut mal ein paar Bytes schaufeln zu dürfen, außerdem wollte ich es auch wissen...
Gruß Sebastian
Linus TorvaldSoftware is like s e x: its better when its free.
Danke für deine schnelle Hilfe!!!!!!!!
Hallo!
Ich habe alles geändert, so wie es beschrieben ist, doch es funktioniert immer noch nicht. Hat einer noch ne Idee?
Danke!
Hier noch mal der geänderte Quellcode:
#include <avr/io.h>
#include <avr/interrupt.h>
#define F_CPU 1000000UL
#define BAUD 9600UL
#define UBRR_BAUD ((F_CPU/(16L*BAUD))-1)
volatile uint8_t buffer;
void uart_init(void)
{
UBRRH = (uint8_t) (UBRR_BAUD>>;
UBRRL = (uint8_t) (UBRR_BAUD & 0xFF);
UCSRB = (1<<TXEN) | (1<<RXEN)|(1<<RXCIE);
UCSRC = (1<<URSEL)|(1<<UCSZ1)|(1<<UCSZ0);
}
ISR(USART_RXC_vect)
{
buffer = UDR;
}
void led_init(void)
{
if(buffer==0x31)
PORTA=0x01;
else
PORTA=0x00;
}
int main(void)
{
DDRA = 0xff;
uart_init();
sei();
while(1){
led_init();
}
return 0;
}
Moin,
überprüf mal ob Du auch wirklich 0x31 sendest und nicht 0x01Zitat von booty
bevor in led_init() buffer ausgelesen werden kann, kann ein andere Interrupt buffer wieder geändert haben (ja ich weis - wird bei diesem kleinen Programm nicht passieren)Code:ISR(USART_RXC_vect) { buffer = UDR; } void led_init(void) { if(buffer==0x31) PORTA=0x01; else PORTA=0x00; }
also - entweder
oder die kurze Variante ... da es nur ein Testprogramm istCode:ISR(USART_RXC_vect) { led_init(UDR) } void led_init(char value) { PORTA = value }
um als Alternative zu sehen ob überhaupt was am UART/Interrupt ankommtCode:ISR(USART_RXC_vect) { PORTA = (UDR == 0x31) ? 0x01 : 0x00; // PORTA = UDR; }
DetailänderungCode:ISR(USART_RXC_vect) { static char dummy = 0; PORTA = dummy++; if (dummy == 255) dummy = 0; }
hand, mogelCode:int main(void) { DDRA = 0xff; uart_init(); sei(); while(1) { // CPU schlafen legen ... spart Akkus } return 0; }
Lesezeichen