下面是一个使用ATmega2560的代码示例,使用定时器和多个按钮来闪烁LED:
#include
#include
#define F_CPU 16000000UL
#include
volatile uint8_t button1_state = 0;
volatile uint8_t button2_state = 0;
volatile uint8_t led_state = 0;
void button_init() {
// 设置按钮引脚为输入
DDRD &= ~(1 << PD2);
DDRD &= ~(1 << PD3);
// 启用上拉电阻
PORTD |= (1 << PD2);
PORTD |= (1 << PD3);
// 设置按钮状态改变的中断触发方式为下降沿触发
EICRA |= (1 << ISC21) | (1 << ISC31);
// 启用外部中断
EIMSK |= (1 << INT2) | (1 << INT3);
}
void timer_init() {
// 设置定时器1为CTC模式
TCCR1B |= (1 << WGM12);
// 设置预分频系数为64
TCCR1B |= (1 << CS11) | (1 << CS10);
// 设置比较匹配值,控制闪烁频率
OCR1A = 15624;
// 启用比较匹配中断
TIMSK1 |= (1 << OCIE1A);
}
void led_init() {
// 设置LED引脚为输出
DDRC |= (1 << PC0);
}
void led_on() {
PORTC |= (1 << PC0);
}
void led_off() {
PORTC &= ~(1 << PC0);
}
ISR(INT2_vect) {
// 按钮1状态发生改变
if (!(PIND & (1 << PD2))) {
button1_state = 1;
} else {
button1_state = 0;
}
}
ISR(INT3_vect) {
// 按钮2状态发生改变
if (!(PIND & (1 << PD3))) {
button2_state = 1;
} else {
button2_state = 0;
}
}
ISR(TIMER1_COMPA_vect) {
// 定时器比较匹配中断,控制LED状态
if (button1_state && button2_state) {
led_state = !led_state;
if (led_state) {
led_on();
} else {
led_off();
}
} else {
led_off();
}
}
int main(void) {
button_init();
timer_init();
led_init();
sei(); // 启用全局中断
while (1) {
// 主循环中不需要做任何事情
}
return 0;
}
这个代码示例中,我们使用了外部中断来检测按钮状态的改变。当按钮1和按钮2同时按下时,LED会以指定的频率闪烁。使用定时器中断来控制LED的状态改变。