新聞中心

        EEPW首頁 > 嵌入式系統(tǒng) > 設(shè)計應(yīng)用 > 51單片機工程實踐--第3章 74HC595+ULN200

        51單片機工程實踐--第3章 74HC595+ULN200

        作者: 時間:2016-11-25 來源:網(wǎng)絡(luò) 收藏

        void timer0_interrupt(void) interrupt 1
        {
        ET0 = 0;
        EA = 0; // 經(jīng)測試 這里不關(guān)閉定時器中斷也沒有問題 鴻哥這里關(guān)閉定時器中斷不知道是PIC單片機的特點還是其它原因

        key_scan(); // 按鍵掃描函數(shù)

        if(buzzer_time_cnt) // 控制蜂鳴器聲音的長短
        {
        BUZZER_OUT = 0; // 開啟蜂鳴器
        --buzzer_time_cnt; // 蜂鳴器聲音長短的計數(shù)延時
        }
        else
        {
        BUZZER_OUT = 1; // 關(guān)閉蜂鳴器
        }

        TH0 = 0xfe;
        TL0 = 0x33;

        ET0 = 1;
        EA = 1; // 前面關(guān)閉定時器中斷,這里當(dāng)然需要開啟
        }

        void interrupt_init(void)
        {
        TMOD = TMOD | 0x01;
        TMOD = TMOD & 0xFD;

        TH0 = 0xfe;
        TL0 = 0x33; // 定時0.5ms
        TR0 = 1;

        ET0 = 1; // 開啟外部中斷
        EA = 1; // 開啟總中斷
        }

        void key_scan(void)
        {

        switch(key_step)
        {
        case 1:// 按鍵掃描 1、2 號按鍵
        KEY_OUT1 = 0;// 按鍵列掃描 第一列輸出低電平
        KEY_OUT2 = 1;// 第二列輸出高電平
        delay_cnt2 = 0; // 延時計數(shù)器清零
        key_step++;// 切換到下一個步驟運行

        break;

        case 2:
        delay_cnt2++;
        if(delay_cnt2>CNT_DELAY_CNT2)// 小延時,但不是去抖動延時 保證列輸出信號穩(wěn)定
        {
        delay_cnt2 = 0;
        key_step++;// 切換到下一個步驟運行
        }

        break;

        case 3:
        if((1==KEY_IN1)&&(1==KEY_IN2))// 如果沒有按鍵按下,則2個IO輸入都是高電平
        {
        key_step++;// 如果沒有按鍵按下,下一個中斷掃描另外2個按鍵
        key_lock1 = 0;// 按鍵自鎖標(biāo)志清零
        delay_cnt1 = 0;// 按鍵去抖動延時計數(shù)器清零,此處設(shè)計很巧妙
        }
        else if((0==KEY_IN1)&&(1==KEY_IN2)&&(0==key_lock1))
        {

        ++delay_cnt1;// 延時計數(shù)器

        if(delay_cnt1>CNT_DELAY_CNT1)// 延時計數(shù)器超過閥值
        {
        delay_cnt1 = 0;
        key_lock1 = 1;// 自鎖按鍵置位,避免一直觸發(fā),只有松開按鍵,才會被清零
        key_sec = 1;// 觸發(fā) 1 號按鍵
        }
        }

        else if((1==KEY_IN1)&&(0==KEY_IN2)&&(0==key_lock1))
        {
        ++delay_cnt1;
        if(delay_cnt1>CNT_DELAY_CNT1)
        {
        delay_cnt1 = 0;
        key_lock1 = 1;// 自鎖按鍵置位,避免一直觸發(fā),只有松開按鍵,才會被清零
        key_sec = 2;// 觸發(fā) 2 號按鍵
        }
        }

        break;

        case 4:// 掃描 3、4 號按鍵
        KEY_OUT1 = 1;// 第一列輸出高電平
        KEY_OUT2 = 0;// 按鍵列掃描,第二列輸出低電平
        delay_cnt2 = 0;// 延時計數(shù)器清零
        key_step++;// 切換到下一步運行

        break;

        case 5:
        delay_cnt2++;
        if(delay_cnt2>CNT_DELAY_CNT2)// 小延時,但不是去抖動延時 保證列輸出信號穩(wěn)定
        {
        delay_cnt2 = 0;
        key_step++;// 切換到下一步運行
        }

        break;

        case 6:
        if((1==KEY_IN1)&&(1==KEY_IN2))
        {
        key_step++;
        key_lock1 = 0;
        delay_cnt1 = 0;
        }
        else if((0==KEY_IN1)&&(1==KEY_IN2)&&(0==key_lock1))
        {
        ++delay_cnt1;
        if(delay_cnt1>CNT_DELAY_CNT1)
        {
        delay_cnt1 = 0;
        key_lock1 = 1;
        key_sec = 3;// 觸發(fā) 3 號按鍵
        }
        }
        else if((1==KEY_IN1)&&(0==KEY_IN2)&&(0==key_lock1))
        {
        ++delay_cnt1;
        if(delay_cnt1>CNT_DELAY_CNT1)
        {
        delay_cnt1 = 0;
        key_lock1 = 1;
        key_sec = 4;// 觸發(fā) 4 號按鍵
        }
        }

        break;
        }

        if(key_step>6)// 判斷,第一組與第二組按鍵反復(fù)輪流掃描
        {
        key_step = 1;
        }
        }

        void key_service(void)
        {
        switch(key_sec)
        {
        case 1:// 1 號按鍵
        relay_status_clear();// 把relay_status清零
        relay_status_set_1();// 把relay_status對應(yīng)的第一個繼電器啟動
        relay_drive();// 把relay_status的狀態(tài)通過595驅(qū)動出來
        buzzer_time_cnt = CNT_BUZZER_TIME;
        key_sec = 0;// 處理完相應(yīng)按鍵程序后,把按鍵選擇變量清零,避免一直觸發(fā)

        break;

        case 2: // 2 號按鍵
        relay_status_clear();// 把relay_status清零
        relay_status_set_2();// 把relay_status對應(yīng)的第一個繼電器啟動
        relay_drive();// 把relay_status的狀態(tài)通過595驅(qū)動出來
        buzzer_time_cnt = CNT_BUZZER_TIME;
        key_sec = 0;

        break;

        case 3:// 3 號按鍵
        relay_status_clear();// 把relay_status清零
        relay_status_set_3();// 把relay_status對應(yīng)的第一個繼電器啟動
        relay_drive();// 把relay_status的狀態(tài)通過595驅(qū)動出來
        buzzer_time_cnt = CNT_BUZZER_TIME;
        key_sec = 0;

        break;

        case 4:// 4 號按鍵
        relay_status_clear();// 把relay_status清零
        relay_status_set_4();// 把relay_status對應(yīng)的第一個繼電器啟動
        relay_drive();// 把relay_status的狀態(tài)通過595驅(qū)動出來
        buzzer_time_cnt = CNT_BUZZER_TIME;
        key_sec = 0;

        break;
        }
        }

        void relay_status_clear(void)
        {
        relay_status = 0;
        }

        void relay_status_set_1(void)
        {
        relay_status |= 0x0001;
        }

        void relay_status_set_2(void)
        {
        relay_status |= 0x0002;
        }

        void relay_status_set_3(void)
        {
        relay_status |= 0x0004;
        }

        void relay_status_set_4(void)
        {
        relay_status |= 0x0008;
        }

        void relay_drive(void)
        {
        u8 tempdata = 0;
        //u16 relay_status_temp = 0;

        HC595_SCK_OUT = 0;
        HC595_RCK_OUT = 0;

        //relay_status_temp = relay_status;

        for(tempdata=0; tempdata<16; tempdata++)
        {
        if(relay_status & 0x8000)
        {
        HC595_SI_OUT = 1;
        }
        else
        {
        HC595_SI_OUT = 0;
        }

        HC595_SCK_OUT = 0;
        _nop_();
        _nop_();
        HC595_SCK_OUT = 1;
        _nop_();
        _nop_();
        relay_status <<= 1;
        }

        HC595_RCK_OUT = 0;
        _nop_();
        _nop_();
        HC595_RCK_OUT = 1;
        _nop_();
        _nop_();

        HC595_SCK_OUT = 0;// 拉低,增強抗干擾
        HC595_RCK_OUT = 0;
        HC595_SI_OUT = 0;
        }

        void delay(void)
        {
        u8 t = 0;

        for(t=0; t<0x0F; t++)
        {;}
        }


        上一頁 1 2 下一頁

        關(guān)鍵詞: 51單片機74HC595ULN20

        評論


        技術(shù)專區(qū)

        關(guān)閉
        主站蜘蛛池模板: 开远市| 丹东市| 昌图县| 南昌市| 静海县| 武清区| 阜平县| 新丰县| 铜鼓县| 鄱阳县| 裕民县| 金寨县| 峨边| 抚顺县| 湖南省| 兴海县| 景谷| 襄城县| 岳池县| 中江县| 富民县| 积石山| 会理县| 望谟县| 赤水市| 余江县| 东乡县| 佳木斯市| 凌海市| 沧源| 观塘区| 南丹县| 黑河市| 囊谦县| 丰城市| 隆化县| 商南县| 鄂托克旗| 无极县| 大方县| 琼中|