Ich habe vorher ATmega32A verwendet und migriere jetzt zu ATmega324PA, nur um die Energieverwaltung zu verbessern. Jetzt teste ich den neuen Controller in jeder Hinsicht. Dies ist ein einfacher Code, um den Watchdog-Timer zu überprüfen, aber er setzt den Controller immer wieder zurück.
Code:
int main(void)
{
uart_init();
PORTA|=(1<<PORTA1);
_delay_ms(1500);
PORTA&=~(1<<PORTA1);
_delay_ms(2000);
uart_array("FFFFFFFFFFFFFFFFFF");
wdt_enable(WDTO_2S);
_delay_ms(5000);
}
void uart_init()
{
/*set PinA1 as output for LED*/
DDRA|=(1<<1);
/*set PinD3 as output for UART*/
DDRD|=(1<<3);
/*set pinD2 as input for UART*/
DDRD&=~(1<<2);
/*enabling TX and RX*/
UCSR1B |=(1<<TXEN1) | (1<<RXEN1);
/*asynchronous mode selection*/
UCSR1C&=~(1<<UMSEL11);
UCSR1C&=~(1<<UMSEL10);
/*setting data format to 8 bit*/
UCSR1B &=~(1<<UCSZ12);
UCSR1C|=(1<<UCSZ11)|(1<<UCSZ10);
/* setting one bit as stop bit*/
UCSR1C &=~(1<<USBS1);
/*Disabling parity*/
UCSR1C &= ~((1<<UPM11) | (1<<UPM10));
/* loading 8 LSB to UBRRL*/
UBRR1L = UBRRL_VALUE;
/* loading 4 MSB to UBRRH*/
UBRR1H = UBRRH_VALUE;
}
Der Code funktioniert beim ersten Mal gut, aber danach blinkt die LED weiter.
Hinweis: Das Sicherungsbit des Watchdog (WDTON) ist deaktiviert.
Ja, das liegt daran, dass Sie nach dem Auslösen des Watchdogs das entsprechende Flag zurücksetzen müssen, bevor Main wieder startet (es gibt ein Register, in dem Sie auslesen können, was den Reset verursacht hat) und den Watchdog daran hindern, immer wieder zu feuern.
Dieser Code behebt Ihr Problem:
// This function is called upon a HARDWARE RESET:
void reset(void) __attribute__((naked)) __attribute__((section(".init3")));
/*! Clear SREG_I on hardware reset. */
void reset(void)
{
cli();
// Note that for newer devices (any AVR that has the option to also
// generate WDT interrupts), the watchdog timer remains active even
// after a system reset (except a power-on condition), using the fastest
// prescaler value (approximately 15 ms). It is therefore required
// to turn off the watchdog early during program startup.
MCUSR = 0; // clear reset flags
wdt_disable();
}
Dieses .init3
Ding ist ein spezieller Codeabschnitt, in den Sie Code einfügen können, der vor dem Hauptstart ausgeführt wird. Hier ist ein Link , der das beschreibt, aber Sie sollten sich nicht zu viele Gedanken machen, der obige Code wird gut funktionieren, wenn er in die main.c
.
Über die vorherigen reset()
Funktionshinweise hinaus müssen Sie den Watchdog im Bootloader deaktivieren (falls natürlich verwendet). Es gibt/war zB ein bekannter Fehler des ursprünglichen Arduino-Bootloaders, der den Watchdog nicht deaktiviert hat.
gzix
jjstcool
gzix
jjstcool