Tôi đang gặp vấn đề khi thực hiện trình tự theo dõi vô hiệu hóa trên AVR ATtiny84A thực sự đặt lại chip mặc dù bộ định thời nên còn nhiều thời gian trên đó. Điều này xảy ra không nhất quán và khi chạy cùng một mã trên nhiều phần vật lý; một số thiết lập lại mỗi lần, một số đôi khi thiết lập lại, và một số không bao giờ.
Để giải thích vấn đề, tôi đã viết một chương trình đơn giản ...
- Cho phép cơ quan giám sát với thời gian chờ 1 giây
- Đặt lại cơ quan giám sát
- Bật đèn LED trắng trong 0,1 giây
- Tắt đèn LED trắng trong 0,1 giây
- Vô hiệu hóa cơ quan giám sát
Tổng thời gian giữa kích hoạt và vô hiệu hóa watchdog nhỏ hơn 0,3 giây, nhưng đôi khi thiết lập lại watchdog xảy ra khi chuỗi vô hiệu hóa được thực thi.
Đây là mã:
#define F_CPU 1000000 // Name used by delay.h. We are running 1Mhz (default fuses)
#include <avr/io.h>
#include <util/delay.h>
#include <avr/wdt.h>
// White LED connected to pin 8 - PA5
#define WHITE_LED_PORT PORTA
#define WHITE_LED_DDR DDRA
#define WHITE_LED_BIT 5
// Red LED connected to pin 7 - PA6
#define RED_LED_PORT PORTA
#define RED_LED_DDR DDRA
#define RED_LED_BIT 6
int main(void)
{
// Set LED pins to output mode
RED_LED_DDR |= _BV(RED_LED_BIT);
WHITE_LED_DDR |= _BV(WHITE_LED_BIT);
// Are we coming out of a watchdog reset?
// WDRF: Watchdog Reset Flag
// This bit is set if a watchdog reset occurs. The bit is reset by a Power-on Reset, or by writing a
// logic zero to the flag
if (MCUSR & _BV(WDRF) ) {
// We should never get here!
// Light the RED led to show it happened
RED_LED_PORT |= _BV(RED_LED_BIT);
MCUCR = 0; // Clear the flag for next time
}
while(1)
{
// Enable a 1 second watchdog
wdt_enable( WDTO_1S );
wdt_reset(); // Not necessary since the enable macro does it, but just to be 100% sure
// Flash white LED for 0.1 second just so we know it is running
WHITE_LED_PORT |= _BV(WHITE_LED_BIT);
_delay_ms(100);
WHITE_LED_PORT &= ~_BV(WHITE_LED_BIT);
_delay_ms(100);
// Ok, when we get here, it has only been about 0.2 seconds since we reset the watchdog.
wdt_disable(); // Turn off the watchdog with plenty of time to spare.
}
}
Khi khởi động, chương trình sẽ kiểm tra xem liệu thiết lập lại trước đó có phải do thời gian chờ của watchdog gây ra hay không và nếu vậy nó sẽ sáng đèn LED màu đỏ và xóa cờ thiết lập lại watchdog để cho biết rằng thiết lập lại watchdog đã xảy ra. Tôi tin rằng mã này sẽ không bao giờ được thực thi và đèn LED màu đỏ sẽ không bao giờ được bật, nhưng nó thường như vậy.
Chuyện gì đang xảy ra ở đây?