欧美极品高清xxxxhd,国产日产欧美最新,无码AV国产东京热AV无码,国产精品人与动性XXX,国产传媒亚洲综合一区二区,四库影院永久国产精品,毛片免费免费高清视频,福利所导航夜趣136

 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 400|回復: 0
打印 上一主題 下一主題
收起左側

atmega8多個按鍵控制多個LED

[復制鏈接]
跳轉到指定樓層
樓主
ID:1073237 發表于 2025-10-31 23:51 | 只看該作者 回帖獎勵 |倒序瀏覽 |閱讀模式
atmega8多個按鍵控制多個LED
#include <iom8v.h>
#include <macros.h>

#define uchar unsigned char
#define uint unsigned int

// 按鍵和LED定義
#define KEY_PORT    PIND
#define LED_PORT    PORTC
#define DEBOUNCE_DELAY 10  // 消抖時間10ms
#define SLEEP_DELAY 5000   // 5秒無操作進入睡眠

// 延時函數
void delay_ms(uint ms) {
    uint i, j;
    for(i = 0; i < ms; i++)
        for(j = 0; j < 114; j++);  // 約1ms@8MHz
}

// 初始化外部中斷(用于喚醒睡眠)
void wakeup_init(void) {
    // 配置INT0~INT2(PD0~PD2)為下降沿觸發
    MCUCR |= (1 << 1) | (1 << 3);  // ISC01=1(INT0下降沿), ISC11=1(INT1下降沿)
    MCUCSR &= ~(1 << 6);           // ISC21=0(INT2下降沿)
    GICR |= (1 << 6) | (1 << 7) | (1 << 5);  // 使能INT0、INT1、INT2中斷
}

// 進入睡眠模式(空閑模式):通過機器碼直接執行sleep指令
void enter_sleep(void) {
    // 配置為空閑模式(SM1=0, SM0=0)并允許睡眠(SE=1)
    MCUCR &= ~((1 << 1) | (1 << 0));  // 空閑模式
    MCUCR |= (1 << 7);                // 允許睡眠

    // 寫入sleep指令的機器碼(0x94, 0x8F是AVR sleep指令的16位機器碼)
    *(volatile unsigned short *)0x0000 = 0x948F;
}

// 外部中斷服務程序(僅用于喚醒)
#pragma interrupt_handler ext_int0_isr:2
void ext_int0_isr(void) {}

#pragma interrupt_handler ext_int1_isr:3
void ext_int1_isr(void) {}

#pragma interrupt_handler ext_int2_isr:4
void ext_int2_isr(void) {}

void main(void) {
    uchar i;
    uchar key_flag[5] = {0};
    uchar key_last[5];
    uchar led_state = 0xFF;
    uint idle_cnt = 0;  // 空閑計數器

    // 配置IO口
    DDRD &= ~0x1F;       // PD0~PD4輸入
    PORTD |= 0x1F;       // 使能上拉
    DDRC |= 0x1F;        // PC0~PC4輸出
    LED_PORT = led_state;

    // 初始化按鍵狀態
    for(i = 0; i < 5; i++) {
        key_last[i] = (KEY_PORT & BIT(i)) ? 1 : 0;
    }

    // 初始化喚醒中斷和全局中斷
    wakeup_init();
    SREG |= (1 << 7);  // 使能全局中斷

    while(1) {
        uchar key_activity = 0;  // 按鍵活動標記

        // 按鍵檢測邏輯
        for(i = 0; i < 5; i++) {
            uchar key_current = (KEY_PORT & BIT(i)) ? 1 : 0;

            if(key_current == 0 && key_last[i] == 1) {  // 按下邊緣
                delay_ms(DEBOUNCE_DELAY);
                if((KEY_PORT & BIT(i)) == 0 && key_flag[i] == 0) {
                    led_state ^= BIT(i);
                    LED_PORT = led_state;
                    key_flag[i] = 1;
                    key_activity = 1;
                }
            } else if(key_current == 1 && key_last[i] == 0) {  // 釋放邊緣
                delay_ms(DEBOUNCE_DELAY);
                if((KEY_PORT & BIT(i)) != 0) {
                    key_flag[i] = 0;
                    key_activity = 1;
                }
            }
            key_last[i] = key_current;
        }

        // 無活動時進入睡眠
        if(key_activity) {
            idle_cnt = 0;
        } else {
            idle_cnt++;
            if(idle_cnt >= SLEEP_DELAY) {
                enter_sleep();  // 進入睡眠,等待按鍵喚醒
                idle_cnt = 0;
            }
        }

        delay_ms(1);  // 計數基準
    }
}


分享到:  QQ好友和群QQ好友和群 QQ空間QQ空間 騰訊微博騰訊微博 騰訊朋友騰訊朋友
收藏收藏 分享淘帖 頂 踩
回復

使用道具 舉報

您需要登錄后才可以回帖 登錄 | 立即注冊

本版積分規則

小黑屋|51黑電子論壇 |51黑電子論壇6群 QQ 管理員QQ:125739409;技術交流QQ群281945664

Powered by 單片機教程網

快速回復 返回頂部 返回列表