標(biāo)題: 4個(gè)單片機(jī)IO,LED燈,按鍵共用,STC怎么編程? [打印本頁]

作者: finezwl    時(shí)間: 2020-8-14 23:44
標(biāo)題: 4個(gè)單片機(jī)IO,LED燈,按鍵共用,STC怎么編程?
4個(gè)IO,LED燈,按鍵共用,STC怎么編程

作者: 滄興電子    時(shí)間: 2020-8-15 05:44
建議LED燈PWM模式,調(diào)整占空比,在IO口高電平時(shí)檢測(cè)按鍵是否按下,如果按下等待按鍵處理程序,LED燈暫時(shí)就不要管了。
作者: xianfajushi    時(shí)間: 2020-8-15 06:45
IO口復(fù)用必須借助其它芯片先行解放IO才能談及復(fù)用的可能,還需要有控制其它芯片的IO。
作者: wulin    時(shí)間: 2020-8-15 07:36
LED燈、按鍵共用4個(gè)單片機(jī)IO示例


#include <reg52.h>

sfr P1M0 = 0x92;  //0000,0000 端口1模式寄存器0
sfr P1M1 = 0x91;  //0000,0000 端口1模式寄存器1

sbit LED1 = P1^4;        //LED端口聲明
sbit LED2 = P1^5;
sbit LED3 = P1^6;
sbit LED4 = P1^7;

unsigned char KeySec=0;//鍵值變量

/**********************************
  1ms延時(shí)程序(僅限于STC15W 1T MCU)
**********************************/
void Delay1ms()                //@12.000MHz
{
        unsigned char i, j;
        i = 12;
        j = 169;
        do
        {
                while (--j);
        } while (--i);
}

/**********************************
        按鍵掃描程序
**********************************/
void key_scan()
{
        static unsigned char count=0;//靜態(tài)計(jì)數(shù)變量
        static bit sign_key=0;                        //靜態(tài)標(biāo)志位
        unsigned char time_key,time_LED;//臨時(shí)變量

        time_LED=P1&0xf0;//保存4個(gè)LED狀態(tài)
        P1M0=0x00;//P1.4~7設(shè)置弱上拉
        P1M1=0x00;//P1.4~7設(shè)置弱上拉
        P1|=0xf0; //P1.4~7置高電平       
        if(P1&0xf0!=0xf0)//有鍵按下
        {
                if(++count>=10 && sign_key==0)//消抖
                {
                        sign_key=1;//自鎖
                        time_key=P1&0xf0;//保存P1.4~7狀態(tài)
                        switch(time_key)
                        {
                                case 0xe0: KeySec=1; break;//輸出鍵值
                                case 0xd0: KeySec=2; break;
                                case 0xb0: KeySec=3; break;
                                case 0x70: KeySec=4; break;
                        }
                }
        }
        else //抬起
        {
                count=0;//計(jì)數(shù)變量清0
                sign_key=0;//鍵態(tài)標(biāo)志清0
        }
        P1&=0x0f;    //P1.4~7清0
        P1|=time_LED;//還原4個(gè)LED狀態(tài)
        P1M0=0xf0;   //還原P1.4~7推挽設(shè)置
        P1M1=0x00;   //還原P1.4~7推挽設(shè)置
}
/*********************************
        按鍵服務(wù)程序
*********************************/
void key_service()
{
        switch(KeySec)
        {
                case 1:        LED1=~LED1;KeySec=0;break;
                case 2:        LED2=~LED2;KeySec=0;break;
                case 3:        LED3=~LED3;KeySec=0;break;
                case 4:        LED4=~LED4;KeySec=0;break;
        }                  
}
/********************************
        主程序
********************************/
void main()
{
        P1M0=0xf0;//P1.4~7設(shè)置推挽
        P1M1=0x00;//P1.4~7設(shè)置推挽
        while(1)
        {
                key_scan();
                key_service();
                Delay1ms();//控制主循環(huán)周期約1ms
        }
}





作者: 壓著我頭發(fā)啦    時(shí)間: 2020-8-15 08:36
wulin 發(fā)表于 2020-8-15 07:36
LED燈、按鍵共用4個(gè)單片機(jī)IO示例

學(xué)習(xí)了
作者: 溫存723    時(shí)間: 2020-8-15 23:18
wulin 發(fā)表于 2020-8-15 07:36
LED燈、按鍵共用4個(gè)單片機(jī)IO示例

  又漲姿勢(shì)了  很實(shí)用
作者: jianuli    時(shí)間: 2021-8-31 15:35
wulin 發(fā)表于 2020-8-15 07:36
LED燈、按鍵共用4個(gè)單片機(jī)IO示例



你好,我按你上面的程序在stc12c2052ad上不能工作,不知道是那里的原因,P1M0、P1M1有修改,LED1在P1.5、LED2在P1.4,其它一樣
作者: jianuli    時(shí)間: 2021-8-31 15:42
wulin 發(fā)表于 2020-8-15 07:36
LED燈、按鍵共用4個(gè)單片機(jī)IO示例



程序如下

IMG_20210831_153850.jpg (1.76 MB, 下載次數(shù): 134)

IMG_20210831_153850.jpg

IMG_20210831_153905.jpg (1.55 MB, 下載次數(shù): 140)

IMG_20210831_153905.jpg

作者: lkc8210    時(shí)間: 2021-8-31 16:29
本帖最后由 lkc8210 于 2021-8-31 16:33 編輯
jianuli 發(fā)表于 2021-8-31 15:42
程序如下

例子用的是STC15



你用的是STC12



有試過跟STC15一樣設(shè)置嗎?
P1M0=0xF0;
P1M1=0x00;

作者: 2633753197    時(shí)間: 2021-8-31 17:01
………………

CSDN_1630400410697.jpg (238.88 KB, 下載次數(shù): 131)

CSDN_1630400410697.jpg

作者: jianuli    時(shí)間: 2021-8-31 17:31
lkc8210 發(fā)表于 2021-8-31 16:29
例子用的是STC15



那我燈在P1口啊,
作者: 188610329    時(shí)間: 2021-8-31 17:56
你是幾個(gè)LED,幾個(gè)按鍵?一般一個(gè)IO復(fù)用LED和按鍵,不是很推薦,如果LED是周期點(diǎn)亮,比如數(shù)碼管的公共級(jí),通常是一個(gè)IO復(fù)用多個(gè)按鍵,接到不同數(shù)碼管的公共級(jí),通過數(shù)碼管的周期點(diǎn)亮,區(qū)別不同按鍵的狀態(tài),這樣的效果比較好,比反復(fù)切換IO狀態(tài)要好。
作者: jianuli    時(shí)間: 2021-8-31 20:41
188610329 發(fā)表于 2021-8-31 17:56
你是幾個(gè)LED,幾個(gè)按鍵?一般一個(gè)IO復(fù)用LED和按鍵,不是很推薦,如果LED是周期點(diǎn)亮,比如數(shù)碼管的公共級(jí),通 ...

2個(gè)燈,2個(gè)按鍵,電路跟手冊(cè)上的一樣
作者: jianuli    時(shí)間: 2021-8-31 22:19
沒人說下了嗎
作者: jianuli    時(shí)間: 2021-9-8 11:24
溫存723 發(fā)表于 2020-8-15 23:18
又漲姿勢(shì)了  很實(shí)用

我反復(fù)調(diào)試都不行,說說你的想法或程序,謝謝啦
作者: jianuli    時(shí)間: 2021-9-14 16:59
wulin 發(fā)表于 2020-8-15 07:36
LED燈、按鍵共用4個(gè)單片機(jī)IO示例



大佬,幫忙分析下,我反復(fù)調(diào)試都不行,謝謝啦
作者: jianuli    時(shí)間: 2021-9-14 19:20
wulin 發(fā)表于 2020-8-15 07:36
LED燈、按鍵共用4個(gè)單片機(jī)IO示例



大佬,幫我分析下,我反復(fù)調(diào)試好久了都不行,謝謝啦
作者: jianuli    時(shí)間: 2021-9-14 21:09
電路圖

捕獲.PNG (56.6 KB, 下載次數(shù): 130)

捕獲.PNG

作者: jianuli    時(shí)間: 2021-9-14 21:33
wulin 發(fā)表于 2020-8-15 07:36
LED燈、按鍵共用4個(gè)單片機(jī)IO示例



原理圖

U (78.33 KB, 下載次數(shù): 157)

U

作者: angmall    時(shí)間: 2021-9-14 22:03
你把你的代碼完整地貼上來看看
(不要截圖!不要截圖!不要截圖!)

語焉不詳、去頭掐尾也是愛莫能助的了。。。


作者: jianuli    時(shí)間: 2021-9-14 22:49
angmall 發(fā)表于 2021-9-14 22:03
你把你的代碼完整地貼上來看看
(不要截圖!不要截圖!不要截圖!)


代碼我貼了呀,怎么顯示,我再重新貼上,不好意思
作者: jianuli    時(shí)間: 2021-9-14 22:54
#include <reg52.h>
#include<intrins.h>

sfr P1M0  = 0x91;
sfr P1M1  = 0x92;

sbit LED1 = P1^4;        //LED端口聲明
sbit LED2 = P1^5;
sbit LED3 = P1^6;
sbit LED4 = P1^7;

unsigned char KeySec=0;//鍵值變量

/**********************************
  1ms延時(shí)程序
**********************************/
void Delay1ms()                //@12.000MHz
{
        unsigned char i, j;

        _nop_();
        _nop_();
        i = 12;
        j = 168;
        do
        {
                while (--j);
        } while (--i);
}
/**********************************
        按鍵掃描程序
**********************************/
void key_scan()
{
        static unsigned char count=0;//靜態(tài)計(jì)數(shù)變量
        static bit sign_key=0;                        //靜態(tài)標(biāo)志位
        unsigned char time_key,time_LED;//臨時(shí)變量

        time_LED=P1&0xf0;//保存4個(gè)LED狀態(tài)
        P1M0=0xf0;//P1.4~7設(shè)置弱上拉
        P1M1=0x00;//P1.4~7設(shè)置弱上拉
        P1|=0xf0; //P1.4~7置高電平        
        if(P1&0xf0!=0xf0)//有鍵按下
        {
                if(++count>=10 && sign_key==0)//消抖
                {
                        sign_key=1;//自鎖
                        time_key=P1&0xf0;//保存P1.4~7狀態(tài)
                        switch(time_key)
                        {
                                case 0xe0: KeySec=1; break;//輸出鍵值
                                case 0xd0: KeySec=2; break;
                                case 0xb0: KeySec=3; break;
                                case 0x70: KeySec=4; break;
                        }
                }
        }
        else //抬起
        {
                count=0;//計(jì)數(shù)變量清0
                sign_key=0;//鍵態(tài)標(biāo)志清0
        }
        P1&=0x0f;    //P1.4~7清0
        P1|=time_LED;//還原4個(gè)LED狀態(tài)
        P1M0=0x00;   //還原P1.4~7推挽設(shè)置
        P1M1=0xf0;   //還原P1.4~7推挽設(shè)置
}
/*********************************
        按鍵服務(wù)程序
*********************************/
void key_service()
{
        switch(KeySec)
        {
                case 1:        LED1=~LED1;KeySec=0;break;
                case 2:        LED2=~LED2;KeySec=0;break;
                case 3:        LED3=~LED3;KeySec=0;break;
                case 4:        LED4=~LED4;KeySec=0;break;
        }                  
}
/********************************
        主程序
********************************/
void main()
{
        P1M0=0xf0;//P1.4~7設(shè)置推挽
        P1M1=0x00;//P1.4~7設(shè)置推挽
        while(1)
        {
                key_scan();
                key_service();
                Delay1ms();//控制主循環(huán)周期約1ms
        }
}
作者: jianuli    時(shí)間: 2021-9-15 12:39
angmall 發(fā)表于 2021-9-14 22:03
你把你的代碼完整地貼上來看看
(不要截圖!不要截圖!不要截圖!)


大佬,代碼己貼上
作者: jizhongbiao    時(shí)間: 2021-9-17 09:06
可以用狀態(tài)機(jī)做,在較短的時(shí)間間隔里面切換狀態(tài),一個(gè)狀態(tài)用來檢測(cè)按鍵,一個(gè)狀態(tài)用來點(diǎn)亮led。
作者: jianuli    時(shí)間: 2021-9-17 09:31
jizhongbiao 發(fā)表于 2021-9-17 09:06
可以用狀態(tài)機(jī)做,在較短的時(shí)間間隔里面切換狀態(tài),一個(gè)狀態(tài)用來檢測(cè)按鍵,一個(gè)狀態(tài)用來點(diǎn)亮led。

來個(gè)例程
作者: Jiang_YY    時(shí)間: 2021-9-17 10:10
jianuli 發(fā)表于 2021-9-14 22:54
#include
#include

    while(1)
        {
                vLedOff(); // 關(guān)閉LED,將IO口設(shè)置成輸入模式
                Delay1ms();//控制主循環(huán)周期約1ms,等待IO穩(wěn)定后檢測(cè)按鍵
                key_scan(); // 按鍵檢測(cè),不用處理LED
                key_service();
                vLedDisplay(); // 檢測(cè)完按鍵后點(diǎn)亮LED
                Delay1ms();//控制主循環(huán)周期約1ms,LED點(diǎn)亮周期。
        }
// 另,你LED數(shù)據(jù)最好用一個(gè)變量來保存,不要通過讀IO口狀態(tài)備份,容易產(chǎn)生問題。

作者: lkc8210    時(shí)間: 2021-9-17 17:39
jianuli 發(fā)表于 2021-9-14 22:54
#include
#include



用了地板的電路(就是10k+1k+1k那個(gè))
再加上你的代碼
只改了其中一句
if((P1&0xf0)!=0xf0)//有鍵按下//<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
加了括號(hào),不加的話會(huì)有警告:warning C294: unreachable code



作者: jianuli    時(shí)間: 2021-9-17 21:11
lkc8210 發(fā)表于 2021-9-17 17:39
用了地板的電路(就是10k+1k+1k那個(gè))
再加上你的代碼
只改了其中一句

大佬,昨天還是前天我也驗(yàn)證可以了,就是按鍵按下的那個(gè)判斷語句少了括號(hào),加上了就可以了,但是這個(gè)電路還有不足的地方,上電瞬間會(huì)亮一下,就算加下拉電阻可以消除,但對(duì)按鍵也有影響,只能折中吧,還有關(guān)了LED還會(huì)微亮,你實(shí)測(cè)中有沒有發(fā)現(xiàn)
作者: 188610329    時(shí)間: 2021-9-17 22:00
jianuli 發(fā)表于 2021-9-14 21:33
原理圖

你電路設(shè)計(jì)不合理啊……

在按鍵設(shè)計(jì)中,一般都是避免和 強(qiáng)推挽共用的…… 按你的電路設(shè)計(jì),其實(shí)你可以設(shè)計(jì)成 兩個(gè)LED一頭并聯(lián),連接到 P1.4, 另外一頭分別接到 數(shù)碼管的 A,B, 把數(shù)碼管的本來 3 分頻改成 4分頻,就是把這兩個(gè) LED 拓展成數(shù)碼管的第4個(gè)”數(shù)字“ 這樣你最多可以接 8 個(gè)LED.
然后,把 按鍵一頭并聯(lián),接到P1.5, 另一頭接數(shù)碼管的 8.9.12 中的任意兩個(gè), 在數(shù)碼管的輪流點(diǎn)亮過程中 點(diǎn)亮哪個(gè)位的時(shí)候,P1.5 電平變了,就說明哪個(gè)按鍵被按下了,這樣,你最多可以有 3個(gè) + 剛才說的LED 新增加的 P1.4 的那個(gè)公共端,總共 4個(gè)按鍵,這樣設(shè)計(jì)電路不是更合理可靠,還不用不停 切換IO狀態(tài)么?
作者: jianuli    時(shí)間: 2021-9-17 22:10
188610329 發(fā)表于 2021-9-17 22:00
你電路設(shè)計(jì)不合理啊……

在按鍵設(shè)計(jì)中,一般都是避免和 強(qiáng)推挽共用的…… 按你的電路設(shè)計(jì),其實(shí)你可以 ...

謝謝講解,其實(shí)我是看到手冊(cè)上有這樣接法,也看到別人有這樣用,所以也想學(xué)習(xí)下
作者: jianuli    時(shí)間: 2021-9-17 23:45
188610329 發(fā)表于 2021-9-17 22:00
你電路設(shè)計(jì)不合理啊……

在按鍵設(shè)計(jì)中,一般都是避免和 強(qiáng)推挽共用的…… 按你的電路設(shè)計(jì),其實(shí)你可以 ...

比如有時(shí)僅剩一個(gè)IO口時(shí),要做指示跟按鍵用,也可以這樣用吧
作者: 188610329    時(shí)間: 2021-9-18 00:29
jianuli 發(fā)表于 2021-9-17 23:45
比如有時(shí)僅剩一個(gè)IO口時(shí),要做指示跟按鍵用,也可以這樣用吧

如果僅僅剩一個(gè)IO, 而你的單片機(jī),又沒有別的按鍵,也沒有別的LED,或者數(shù)碼管連接,也沒有其他長(zhǎng)期周期性工作的元件的時(shí)候,又偏偏需要 一個(gè)按鍵,和一個(gè)LED的時(shí)候,作為下下策,可以這樣接,但是,站在共用IO的角度來講,LED和按鍵通過切換IO模式來,共用IO是最不推薦的共用方法, 而大多數(shù)時(shí)候,你的整個(gè)電路中,應(yīng)該能找到,其他的IO口和LED或按鍵共用的IO的。LED和按鍵的共用,應(yīng)該作為實(shí)在沒辦法的時(shí)候的最后辦法。比如你單片機(jī)作為主機(jī),SPI的 始能 引腳 只有單片機(jī)去拉低從機(jī)的 沒有從機(jī)拉低主機(jī)的,你也可以接按鍵,只要被拉低了,就是按鍵被按下了。而即便這個(gè)時(shí)候,SPI在傳輸也沒有所謂,因?yàn)槭寄芤_正在被拉低,完全不影響正在發(fā)生的傳輸。 等等,各種共用方法很多很多。
作者: lkc8210    時(shí)間: 2021-9-20 14:22
jianuli 發(fā)表于 2021-9-17 21:11
大佬,昨天還是前天我也驗(yàn)證可以了,就是按鍵按下的那個(gè)判斷語句少了括號(hào),加上了就可以了,但是這個(gè)電路 ...

有沒有微亮沒留意
試完就把電路拆了
回看我上傳的gif
好像沒有耶~
作者: jianuli    時(shí)間: 2021-9-24 09:35
lkc8210 發(fā)表于 2021-9-20 14:22
有沒有微亮沒留意
試完就把電路拆了
回看我上傳的gif

有微亮
作者: huangfu112000    時(shí)間: 2022-8-23 11:00
jianuli 發(fā)表于 2021-9-14 22:54
#include
#include

如果共用使用的端口有P1.1,P21,P32,P41呢?怎么寫?
作者: huangfu112000    時(shí)間: 2022-9-22 20:35
怎么做成呼吸燈?
作者: jackyangjiali    時(shí)間: 2023-3-31 07:08
wulin 發(fā)表于 2020-8-15 07:36
LED燈、按鍵共用4個(gè)單片機(jī)IO示例



我要說一下此電路配合此程序是錯(cuò)誤的,事實(shí)上此電路,在弱上拉下無法將接有正向的導(dǎo)通的LED端口拉向高電平,程序和電路都需要修改才能正常工作
作者: lkc8210    時(shí)間: 2023-3-31 10:26
jackyangjiali 發(fā)表于 2023-3-31 07:08
我要說一下此電路配合此程序是錯(cuò)誤的,事實(shí)上此電路,在弱上拉下無法將接有正向的導(dǎo)通的LED端口拉向高電 ...

但我沒改電路也成功也~




歡迎光臨 (http://www.torrancerestoration.com/bbs/) Powered by Discuz! X3.1