8个LED连接到PORTB的PB0-PB7。
一个按钮连接到PD2(外部中断0)。
- #include <avr/io.h>
- #include <avr/interrupt.h>
- #define LED_PORT PORTB
- #define LED_DDR DDRB
- #define BUTTON_PIN PIND
- #define BUTTON_DDR DDRD
- #define BUTTON_PORT PORTD
- #define BUTTON PD2
- volatile uint16_t speed = 100; // 初始速度(单位:ms)
- volatile uint8_t timer_overflow_count = 0;
- // 初始化定时器0
- void init_timer0() {
- TCCR0A = 0x00; // 普通模式
- TCCR0B = (1 << CS02) | (1 << CS00); // 分频系数为 1024
- TIMSK0 = (1 << TOIE0); // 使能溢出中断
- }
- // 定时器0溢出中断服务程序
- ISR(TIMER0_OVF_vect) {
- timer_overflow_count++;
- }
- // 外部中断0服务程序
- ISR(INT0_vect) {
- // 每次按下按钮,速度增加50ms,最大不超过500ms
- speed += 50;
- if (speed > 500) {
- speed = 100;
- }
- }
- // 初始化外部中断
- void init_interrupt() {
- EICRA |= (1 << ISC01); // 设置INT0为下降沿触发
- EIMSK |= (1 << INT0); // 使能INT0中断
- }
- // 初始化端口
- void init_ports() {
- LED_DDR = 0xFF; // 设置PORTB为输出
- LED_PORT = 0x00; // 初始关闭所有LED
- BUTTON_DDR &= ~(1 << BUTTON); // 设置PD2为输入
- BUTTON_PORT |= (1 << BUTTON); // 使能PD2上拉电阻
- }
- // 定时器延时函数
- void delay_ms(uint16_t ms) {
- uint16_t required_overflows = ms / 16; // 每个溢出大约16ms(1024分频,256计数)
- timer_overflow_count = 0;
- while (timer_overflow_count < required_overflows) {
- // 等待溢出次数达到要求
- }
- }
- // 流水灯效果
- void flow_led() {
- while (1) {
- for (uint8_t i = 0; i < 8; i++) {
- LED_PORT = (1 << i); // 点亮第i个LED
- delay_ms(speed); // 延时
- }
- }
- }
- int main(void) {
- init_ports();
- init_interrupt();
- init_timer0();
- sei(); // 使能全局中断
- flow_led();
- return 0;
- }
|