找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 3096|回復(fù): 19
收起左側(cè)

請教一下單片機(jī)IO口復(fù)用驅(qū)動數(shù)碼管時如何避免沖突?

  [復(fù)制鏈接]
ID:734017 發(fā)表于 2022-4-11 21:08 | 顯示全部樓層 |閱讀模式
51hei截圖_20220411205056.png 51hei截圖_20220411205021.png
如上圖的單片機(jī)電路圖,用26個IO 復(fù)用驅(qū)動6個數(shù)碼管,21個LDE ,18個按鍵。、
個人理解按鍵那里會與段選沖突。
比喻在一個1MS的周期內(nèi),P44位選給1.段選全部給0.數(shù)碼管顯示8.
如果在這個周期里,P46給的是1,當(dāng)按下Key1的時候,F(xiàn)段理論上滅掉
情況2  周期內(nèi)位選 P44給1,段選全給1 。P46給0.當(dāng)按下key1時,F(xiàn)段理論會亮


回復(fù)

使用道具 舉報

ID:401564 發(fā)表于 2022-4-11 21:48 | 顯示全部樓層
一個數(shù)字的數(shù)碼,com是短路的,接一個就行了,不用接兩個引腳的
6個數(shù)碼管只會用到8+6=14個引腳
不知道你是怎么用到26個IO的?
這么多的按鍵,為什么不用ADC
四多的STC8A8K有59個IO和上拉電阻,為什么不用?
回復(fù)

使用道具 舉報

ID:734017 發(fā)表于 2022-4-11 21:51 | 顯示全部樓層
Y_G_G 發(fā)表于 2022-4-11 21:48
一個數(shù)字的數(shù)碼,com是短路的,接一個就行了,不用接兩個引腳的
6個數(shù)碼管只會用到8+6=14個引腳
不知道你是 ...

15年的產(chǎn)品了,庫存貨想自己改掉。原理圖是對著畫的
回復(fù)

使用道具 舉報

ID:734017 發(fā)表于 2022-4-11 21:53 | 顯示全部樓層
Y_G_G 發(fā)表于 2022-4-11 21:48
一個數(shù)字的數(shù)碼,com是短路的,接一個就行了,不用接兩個引腳的
6個數(shù)碼管只會用到8+6=14個引腳
不知道你是 ...

寫錯了,是6個雙位的數(shù)碼管,
回復(fù)

使用道具 舉報

ID:624769 發(fā)表于 2022-4-11 22:26 | 顯示全部樓層
按鍵復(fù)用 接數(shù)碼管的  位,  不要接數(shù)碼管的  段。
在點(diǎn)亮某個  位  的數(shù)碼管時  順便判斷  和該位共用的 按鍵有沒有 被按下即可。
回復(fù)

使用道具 舉報

ID:824490 發(fā)表于 2022-4-11 22:28 | 顯示全部樓層
只要軟件能做到“分時復(fù)用”,沒有問題,IO復(fù)用多了去了。
回復(fù)

使用道具 舉報

ID:734017 發(fā)表于 2022-4-11 22:53 | 顯示全部樓層
188610329 發(fā)表于 2022-4-11 22:26
按鍵復(fù)用 接數(shù)碼管的  位,  不要接數(shù)碼管的  段。
在點(diǎn)亮某個  位  的數(shù)碼管時  順便判斷  和該位共用的  ...

我這是共陽的,按你的方法,按下去的時候不是要把 位選拉低嗎?那不影響數(shù)碼管顯示嗎?方便的話,提供一個圖,謝謝
回復(fù)

使用道具 舉報

ID:624769 發(fā)表于 2022-4-11 23:38 | 顯示全部樓層
happy2058 發(fā)表于 2022-4-11 22:53
我這是共陽的,按你的方法,按下去的時候不是要把 位選拉低嗎?那不影響數(shù)碼管顯示嗎?方便的話,提供一 ...

共陽的數(shù)碼管 和 按鍵復(fù)用時  按鍵檢測端的IO 內(nèi)部寄存器置1,外部通過47K~100K 電阻下拉到地, IO模式設(shè)置為高阻或者開漏, 檢測 外部電平, 高電平表示按鍵被按下,低電平表示按鍵沒有被按下。
回復(fù)

使用道具 舉報

ID:161164 發(fā)表于 2022-4-11 23:52 | 顯示全部樓層
是2015年的產(chǎn)品還是15年前的產(chǎn)品?
用什么型號的單片機(jī)?
有高阻IO設(shè)定時嗎?
如果有就好辦了

顯示的時候P46/P13/P15設(shè)為高阻
按鍵就不影響顯示

按鍵掃描時
所有位輸出置0
P46/P13/P15設(shè)為雙向弱上拉并置1
把段輸出設(shè)為0xFE,并檢測P46/P13有沒有拉低,有就是key3/key8被按下
把段輸出設(shè)為0xFD,并檢測P46/P13/P15有沒有拉低,有就是key5/key14/key18被按下
...
把各段都拉低后還原要顯示的段輸出,還原位輸出,P46/P13/P15設(shè)為高阻

回復(fù)

使用道具 舉報

ID:734017 發(fā)表于 2022-4-12 01:04 | 顯示全部樓層
188610329 發(fā)表于 2022-4-11 23:38
共陽的數(shù)碼管 和 按鍵復(fù)用時  按鍵檢測端的IO 內(nèi)部寄存器置1,外部通過47K~100K 電阻下拉到地, IO模式設(shè) ...

嗯,感謝了, 按你的方法,循環(huán)時間快。不用單獨(dú)判斷
回復(fù)

使用道具 舉報

ID:734017 發(fā)表于 2022-4-12 01:05 | 顯示全部樓層
lkc8210 發(fā)表于 2022-4-11 23:52
是2015年的產(chǎn)品還是15年前的產(chǎn)品?
用什么型號的單片機(jī)?
有高阻IO設(shè)定時嗎?

2015的  15W408S 查了手冊,IO可選4種態(tài)度
回復(fù)

使用道具 舉報

ID:213173 發(fā)表于 2022-4-12 06:59 | 顯示全部樓層
happy2058 發(fā)表于 2022-4-12 01:05
2015的  15W408S 查了手冊,IO可選4種態(tài)度

按你現(xiàn)有的條件可以做到用26個IO 復(fù)用驅(qū)動6個兩位數(shù)碼管,21個LDE ,18個按鍵。不過電路連接關(guān)系要改。把12個數(shù)碼管看成96個LED,加上21個LDE共117,或看成15個數(shù)碼管,有15個共用陽極,分別各接一個按鍵,另3個IO各接一個按鍵。 無標(biāo)題.jpg

無標(biāo)題1.jpg

回復(fù)

使用道具 舉報

ID:734017 發(fā)表于 2022-4-12 09:34 | 顯示全部樓層
wulin 發(fā)表于 2022-4-12 06:59
按你現(xiàn)有的條件可以做到用26個IO 復(fù)用驅(qū)動6個兩位數(shù)碼管,21個LDE ,18個按鍵。不過電路連接關(guān)系要改。把1 ...

我有點(diǎn)疑惑,檢測的時候,IO電平會拉低,燈不是滅了嗎?
回復(fù)

使用道具 舉報

ID:213173 發(fā)表于 2022-4-12 10:14 | 顯示全部樓層
happy2058 發(fā)表于 2022-4-12 09:34
我有點(diǎn)疑惑,檢測的時候,IO電平會拉低,燈不是滅了嗎?

檢測按鍵的時候,如有鍵按下,IO口電平會被拉低,燈是要滅的。但這個過程只有幾微秒,你能察覺出來?
回復(fù)

使用道具 舉報

ID:734017 發(fā)表于 2022-4-12 10:30 | 顯示全部樓層
wulin 發(fā)表于 2022-4-12 10:14
檢測按鍵的時候,如有鍵按下,IO口電平會被拉低,燈是要滅的。但這個過程只有幾微秒,你能察覺出來?

那也是,謝謝了
回復(fù)

使用道具 舉報

ID:734017 發(fā)表于 2022-4-12 10:30 | 顯示全部樓層
wulin 發(fā)表于 2022-4-12 10:14
檢測按鍵的時候,如有鍵按下,IO口電平會被拉低,燈是要滅的。但這個過程只有幾微秒,你能察覺出來?

長按的時候???一直不亮
回復(fù)

使用道具 舉報

ID:123289 發(fā)表于 2022-4-12 11:28 | 顯示全部樓層
在掃描顯示的“消隱”期間查鍵即可。
“消隱”:掃顯時,在切換顯示值之前,先關(guān)顯示(讓LED的COM失效即可),而后再切換顯示內(nèi)容,這時由于LED已關(guān)閉,所以不會產(chǎn)生亂顯,之后再打開顯示。這段時間就是“消隱”期。
回復(fù)

使用道具 舉報

ID:213173 發(fā)表于 2022-4-12 11:29 | 顯示全部樓層
happy2058 發(fā)表于 2022-4-12 10:30
長按的時候???一直不亮

這與短按和長按沒有任何關(guān)系。如果以入門級水平寫按鍵程序就另當(dāng)別論了。
回復(fù)

使用道具 舉報

ID:734017 發(fā)表于 2022-4-18 22:56 | 顯示全部樓層
程序?qū)懥艘槐椋接邢,請指?nbsp; 流程上往下,按鍵掃描從循環(huán)數(shù)碼管輸出中插入
bit key_service_Lock=0;                                        //循環(huán)標(biāo)志位,禁止連續(xù)掃描       
uchar KeySec = 0;                                                //按鍵編號       
uchar KeyTimeCnt=0;                                         //按鍵去抖動延時計(jì)數(shù)器
uchar key_service_tmp;
while(1)
        {
void Reuse_time_sharing()                                        //復(fù)用驅(qū)動數(shù)碼管  此函數(shù)通用定時器標(biāo)位控制,1MS循環(huán)一次,每次約15MS
{       
        if(Reuse)
        {       
                Reuse=~Reuse;               
                Reuse_count++;
                                switch(Reuse_count)
                                {
                                        case 1 :                                          //DS1_1        第一個數(shù)碼管個位
                                                        P05=0;                       //關(guān)閉上一個輸出位選
                                                        if(!key_service_Lock)  //循環(huán)標(biāo)志位0,進(jìn)入掃描按鍵
                                                        key_select();       //掃描按鍵函數(shù)
                                                        P2=Digital_tube_Segment_program_123[Energy_TXD(Ion_B,1)];    //輸出段選
                                                        P03=1;       //打開位選
                                                        break;
                                        case 2 :                                         //DS1_10
                                                                P03=0;
                                                                if(!key_service_Lock)
                                                                key_select();
                                                                P2=Digital_tube_Segment_program_123[Energy_TXD(Ion_B,1)];
                                                                P04=1;
                                                                                break;
                                        case 3 :                                         //DS2_1               
                                                                P04=0;
                                                                if(!key_service_Lock)
                                                                key_select();
                                                                P2=Digital_tube_Segment_program_123[Energy_TXD(Ion_B,1)];               
                                                                P02=1;               
                                                                                break;
                                        case 4 :                                         //DS2_10       
                                                                P02=0;
                                                                if(!key_service_Lock)
                                                                key_select();
                                                                P2=Digital_tube_Segment_program_123[Energy_TXD(Ion_B,10)];               
                                                                P47=1;
                                                                                break;
                                        case 5 :                                         //DS3_1       
                                                                P47=0;
                                                                if(!key_service_Lock)
                                                                key_select();
                                                                P2=Digital_tube_Segment_program_123[Energy_TXD(Ion_A,1)];       
                                                                P01=1;
                                                                                break;
                                        case 6 :                                         //DS3_10       
                                                                P01=0;       
                                                                if(!key_service_Lock)
                                                                key_select();
                                                                P2=Digital_tube_Segment_program_123[Energy_TXD(Ion_A,10)];
                                                                P00=1;
                                                                                break;
                                        case 7 :                                         //DS4_1         time
                                                                P00=0;
                                                                if(!key_service_Lock)
                                                                key_select();
                                                                P2=Digital_tube_Segment_program_456[Energy_TXD(Time_MIN,1)];
                                                                P37=1;
                                                                                break;
                                        case 8:                                         //DS4_10        time
                                                                P37=0;
                                                                if(!key_service_Lock)
                                                                key_select();
                                                                P2=Digital_tube_Segment_program_456[Energy_TXD(Time_MIN,10)];
                                                                P41=1;
                                                                                break;
                                        case 9 :                                         //DS5_1               
                                                                P41=0;
                                                                if(!key_service_Lock)
                                                                key_select();
                                                                P2=Digital_tube_Segment_program_456[Energy_TXD(Heat_B,1)];
                                                                P36=1;
                                                                                break;
                                        case 10 :                                        //DS5_10       
                                                                P36=0;
                                                                if(!key_service_Lock)
                                                                key_select();
                                                                P2=Digital_tube_Segment_program_456[Energy_TXD(Heat_B,10)];
                                                                P43=1;
                                                                                break;
                                        case 11 :                                        //DS6_1       
                                                                P43=0;
                                                                if(!key_service_Lock)
                                                                key_select();
                                                                P2=Digital_tube_Segment_program_456[Energy_TXD(Heat_A,1)];
                                                                P45=1;
                                                                                break;
                                        case 12:                                         //DS6_10       
                                                                P45=0;
                                                                if(!key_service_Lock)
                                                                key_select();
                                                                P2=Digital_tube_Segment_program_456[Energy_TXD(Heat_A,10)];
                                                                P44=1;
                                                                                break;
                                        case 13 :                                         //D1~D8
                                                                P44=0;       
                                                                if(!key_service_Lock)
                                                                key_select();
                                                                                if(Ion_mode==0)
                                                                                        P2=0xfb;
                                                                                        else if(Ion_mode==1)
                                                                                                P2=0xfd;
                                                                                                else
                                                                                                        P2=0xfe;
                                                                                                       P11=1;
                                                                                break;
                                        case 14 :                                        //D19~D16
                                                                P11=0;
                                                                if(!key_service_Lock)
                                                                key_select();
                                                                                if(start_Time)
                                                                                        P2=0xf7;
                                                                                else P2=0xff;
                                                                P42=1;
                                                                                break;
                                        case 15 :                                        //D17~D21
                                                                P42=0;
                                                                if(!key_service_Lock)
                                                                key_select();
                                                                P05=1;
                                                                                break;
                                                                        default:break;
                                }
                        if(Reuse_count>=15)
                                Reuse_count=0;
        }
}
}      //大循環(huán)到止
void key_select()             //按鍵掃描函數(shù)
{       
        uchar i;
        Bidirectional_IO();    //P46,P13,P15 設(shè)用準(zhǔn)雙口
        for(i=1;i<=8;i++)
        {
        switch(i)                                                                         //按鍵服務(wù)狀態(tài)切換
                {
                        case 1:          P2=0x7f;                                //掃描按鍵  復(fù)用IO輸出O
                                                _nop_();               //這里不加空操作,會讀不到
                                                _nop_();
                                                if(P13==0)            //判斷IO是否拉低
                                                {KeySec =7; key_service_Lock=~key_service_Lock;return;}            //緩存對應(yīng)按鍵 ,循環(huán)標(biāo)志位取反,放開TO內(nèi)部函數(shù)
                                                else if(P46==0)      //判斷IO是否拉低
                                                {KeySec =12; key_service_Lock=~key_service_Lock;return;}           //緩存對應(yīng)按鍵 ,循環(huán)標(biāo)志位取反,
                                                               
                                  break;
                        case 2:                P2=0xbf;
                                               
                                                if(P13==0)
                                                {KeySec =9; key_service_Lock=~key_service_Lock;return;}               
                                                else if(P46==0)
                                                {KeySec =1;key_service_Lock=~key_service_Lock;return;}       
                                                                       
                                  break;  
                        case 3:                P2=0xdf;
                                               
                                                if(P13==0)
                                                {KeySec =8;        key_service_Lock=~key_service_Lock;return;}               
                                                else if(P46==0)
                                                {KeySec =3; key_service_Lock=~key_service_Lock;return;}       
                                                                               
                                  break;           
                        case 4:                P2=0xef;
                                               
                                                if(P13==0)
                                                       
                                                {KeySec        =5;        key_service_Lock=~key_service_Lock;return;}               
                                                else if(P15==0)
                                                {KeySec =18; key_service_Lock=~key_service_Lock;return;}       
                                                else if(P46==0)
                                                {KeySec =14; key_service_Lock=~key_service_Lock;return;}       
                                                                                                                                       
                                  break;           
                        case 5:                P2=0xf7;       
                                               
                                                if(P13==0)
                                               
                                                {KeySec        =6; key_service_Lock=~key_service_Lock;return;}                       
                                                else if(P15==0)
                                                {KeySec =17; key_service_Lock=~key_service_Lock;return;}       
                                                else if(P46==0)
                                                {KeySec =4; key_service_Lock=~key_service_Lock;return;}       
                                                                               
                                  break;           
                        case 6:         P2=0xfb;
                                               
                                                if(P15==0)
                                                {KeySec =15; key_service_Lock=~key_service_Lock;return;}       
                                                else if(P46==0)
                                                {KeySec =2; key_service_Lock=~key_service_Lock;return;}       
                                                                                                                       
                                  break;
                        case 7:                P2=0xfd;
                                               
                                                if(P15==0)
                                                {KeySec =19; key_service_Lock=~key_service_Lock;return;}       
                                                else if(P46==0)
                                                {KeySec =13; key_service_Lock=~key_service_Lock;return;}       
                                                                               
                                  break;  
                        case 8:                P2=0xfe;
                                               
                                                if(P15==0)
                                                {KeySec =16; key_service_Lock=~key_service_Lock;return;}       
                                                else if(P46==0)
                                                {KeySec =11; key_service_Lock=~key_service_Lock;return;}       
                                                                                       
                                  break;           
        default: break;       

                }
        }
        High_IO();    //P46,P13,P15 設(shè)用高阻
}
void TM0_Isr() interrupt 1                                        //定時器0中斷
{       
        if(!Reuse)
        Reuse=~Reuse;
       
        if(key_service_Lock)             //循環(huán)標(biāo)志位取反,進(jìn)入中斷
        {
                        KeyTimeCnt++;
                if(KeyTimeCnt>=20)     //大于20Ms
                {        P0&=0xc0;         //拉低循環(huán)過程中位選
                        P11=0;             //拉低循環(huán)過程中位選
                        P3&=0x1f;        //拉低循環(huán)過程中位選
                        P4&=0x43;        //拉低循環(huán)過程中位選
                        KeyTimeCnt=0;   
                        key_service_Lock=~key_service_Lock;      ////循環(huán)標(biāo)志位取反,防止進(jìn)入中斷,開放循環(huán)掃描
                        key_service_tmp=KeySec;                          //緩存上次掃描結(jié)果
                        key_select();                                           //再次掃描
                        if(key_service_tmp==KeySec)                 //對比掃描結(jié)果
                        {
                                key_service();                                      //調(diào)用按鍵服務(wù)程序
                        }
                        //else KeySec=0;
                       P0|=0xc0;        
                        P11=1;            
                        P3|=0x1f;        
                        P4|=0x43;        
                }
        }
       
        }
請問怎么優(yōu)化,還有_nop_(); 那里原因,謝謝

回復(fù)

使用道具 舉報

ID:1019604 發(fā)表于 2022-4-19 09:22 | 顯示全部樓層
按鍵掃描時
所有位輸出置0
P46/P13/P15設(shè)為雙向弱上拉并置1
把段輸出設(shè)為0xFE,并檢測P46/P13有沒有拉低,有就是key3/key8被按下
回復(fù)

使用道具 舉報

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

本版積分規(guī)則

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

Powered by 單片機(jī)教程網(wǎng)

快速回復(fù) 返回頂部 返回列表