单片机IO口复用
合集下载
相关主题
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
IO 口复用用于按键和数码管显示
1.在一些情况下单片机的 IO 口不够用,遇到 IO 口不够用的时候我们该怎么做呢,大家都能 想到用芯片来扩展 IO,或者用 74HC595 等来驱动数码管减少 IO源自文库口的使用。今天,我告诉大 家不用其他芯片就能实现按键和数码管显示公用 IO 口。 2.废话不多说,先说原理图(其实电路也不是自己想到的,也是看到别人的),该电路只需用 到普通 PNP 三极管(因为我用的是共阳极数码管)和二极管 1N4148,原理图如下:
uint8 SegShow1; uint8 SegShow2; uint8 SegShow3; uint8 SegShow4;
#define KeyDelayTime 5 uint8 KeyCode = 0;
uint8 code Tab[]= //共阳极数码管段码 {
0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,0x80,0x90, //"0~9" 0xBF,0x8C,0xFF,0x88,0xAF //10"-",11"P",12"空",13"A",14"r" };
switch(num) {
case 0: SEG_A = 0; P0 = Tab[SegShow1]; break;
case 1: SEG_A = 1; P0 = 0xFE; break;
case 2:
SEG_B = 0;
P0 = Tab[SegShow2];
break;
case 3:
SEG_B = 1;
void Key_Dispaly_Driver();
void Timer0_Init() {
TMOD |= 0x01; TH0 = (65536-1000)/256; TL0 = (65536-1000)%256; EA = 1; ET0 = 1; TR0 = 1; }
//定时 1ms
void main() {
3.其中,数码管阳极接的下拉电阻正常情况是不需要的,可以不知道为什么 Protues 中不接 就不能正常显示。电路中有四个按键(也可添加更多的按键,理论上总的可以接 8 个),分 别是 S1、S2、S3 和 S4。测试程序中,仿真开始显示数字”0”,按下 S1 则显示 1,按下 S2 则显 示 2,以此类推。 4.下面是程序,其中按键检测原理是借用吴鸿坚按键检测的思想。数码管显示就是普通的动 态扫描,程序代码如下: #include <reg52.h> typedef unsigned char uint8; typedef unsigned short int uint16; sbit SEG_A = P2^0; sbit SEG_B = P2^1; sbit SEG_C = P2^2; sbit SEG_D = P2^3; sbit KeyCom = P1^0; //按键公共端 IO
Timer0_Init(); SegShow1 = 12; SegShow2 = 12; SegShow3 = 12; SegShow4 = 0; while(1) {
switch(KeyCode) {
case 1: SegShow4=1; KeyCode = 0; break;
case 2: SegShow4=2; KeyCode = 0;
P0 = 0xF7;
break;
}
if(KeyCom==1)//判断无按键按键,解锁
{
KeyLock = 0;
}
else if(KeyLock==0&&num==1) //如果按下的是 Key1
{
Key1TimeCont++;
//计数
if(Key1TimeCont>KeyDelayTime)//计数大于去抖时间
P0 = 0xFD;
break;
case 4:
SEG_C = 0;
P0 = Tab[SegShow3];
break;
case 5:
SEG_C = 1;
P0 = 0xFB;
break;
case 6:
SEG_D = 0;
P0 = Tab[SegShow4];
break;
case 7:
SEG_D = 1;
{
Key1TimeCont = 0; //计数清零,下次好用
KeyLock = 1; //自锁
KeyCode = 1; //按键值为 1
}
}
/******其他按键同上********/
else if(KeyLock==0&&num==3)
{
Key2TimeCont++;
if(Key2TimeCont>KeyDelayTime)
break; case 3:
SegShow4=3; KeyCode = 0; break; case 4: SegShow4=4; KeyCode = 0; break; } } }
void Timer0_Isr() interrupt 1 {
TF0 = 0; TR0 = 0;
Key_Dispaly_Driver();
TH0 = (65536-1000)/256; TL0 = (65536-1000)%256; TR0 = 1; }
void Key_Dispaly_Driver() //按键检测和数码管显示放一起 {
static uint8 num=0; //顺序扫描 static uint8 Key1TimeCont=0;//key1 去抖延时计数 static uint8 Key2TimeCont=0;//key2 去抖延时计数 static uint8 Key3TimeCont=0;//key3 去抖延时计数 static uint8 Key4TimeCont=0;//key4 去抖延时计数 static uint8 KeyLock=0;
结束语:上面程序有些已经注释了,本人也是看到公司的一个蒸汽流量计的显示电路就是用 此电路来实现数码管和按键公用 IO 口。所以自己就编了个程序来实现其键盘和显示的功能, 如有不对的地方,还望指正。本人是菜鸟,一直很喜欢电子,虽然现在从事的不是这方面的 工作。
{ Key2TimeCont = 0; KeyLock = 1; KeyCode = 2;
} } else if(KeyLock==0&&num==5) {
Key3TimeCont++; if(Key3TimeCont>KeyDelayTime) {
Key3TimeCont = 0; KeyLock = 1; KeyCode = 3; } } else if(KeyLock==0&&num==7) { Key4TimeCont++; if(Key4TimeCont>KeyDelayTime) { Key4TimeCont = 0; KeyLock = 1; KeyCode = 4; } } num++; if(num>7) num = 0; }
1.在一些情况下单片机的 IO 口不够用,遇到 IO 口不够用的时候我们该怎么做呢,大家都能 想到用芯片来扩展 IO,或者用 74HC595 等来驱动数码管减少 IO源自文库口的使用。今天,我告诉大 家不用其他芯片就能实现按键和数码管显示公用 IO 口。 2.废话不多说,先说原理图(其实电路也不是自己想到的,也是看到别人的),该电路只需用 到普通 PNP 三极管(因为我用的是共阳极数码管)和二极管 1N4148,原理图如下:
uint8 SegShow1; uint8 SegShow2; uint8 SegShow3; uint8 SegShow4;
#define KeyDelayTime 5 uint8 KeyCode = 0;
uint8 code Tab[]= //共阳极数码管段码 {
0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,0x80,0x90, //"0~9" 0xBF,0x8C,0xFF,0x88,0xAF //10"-",11"P",12"空",13"A",14"r" };
switch(num) {
case 0: SEG_A = 0; P0 = Tab[SegShow1]; break;
case 1: SEG_A = 1; P0 = 0xFE; break;
case 2:
SEG_B = 0;
P0 = Tab[SegShow2];
break;
case 3:
SEG_B = 1;
void Key_Dispaly_Driver();
void Timer0_Init() {
TMOD |= 0x01; TH0 = (65536-1000)/256; TL0 = (65536-1000)%256; EA = 1; ET0 = 1; TR0 = 1; }
//定时 1ms
void main() {
3.其中,数码管阳极接的下拉电阻正常情况是不需要的,可以不知道为什么 Protues 中不接 就不能正常显示。电路中有四个按键(也可添加更多的按键,理论上总的可以接 8 个),分 别是 S1、S2、S3 和 S4。测试程序中,仿真开始显示数字”0”,按下 S1 则显示 1,按下 S2 则显 示 2,以此类推。 4.下面是程序,其中按键检测原理是借用吴鸿坚按键检测的思想。数码管显示就是普通的动 态扫描,程序代码如下: #include <reg52.h> typedef unsigned char uint8; typedef unsigned short int uint16; sbit SEG_A = P2^0; sbit SEG_B = P2^1; sbit SEG_C = P2^2; sbit SEG_D = P2^3; sbit KeyCom = P1^0; //按键公共端 IO
Timer0_Init(); SegShow1 = 12; SegShow2 = 12; SegShow3 = 12; SegShow4 = 0; while(1) {
switch(KeyCode) {
case 1: SegShow4=1; KeyCode = 0; break;
case 2: SegShow4=2; KeyCode = 0;
P0 = 0xF7;
break;
}
if(KeyCom==1)//判断无按键按键,解锁
{
KeyLock = 0;
}
else if(KeyLock==0&&num==1) //如果按下的是 Key1
{
Key1TimeCont++;
//计数
if(Key1TimeCont>KeyDelayTime)//计数大于去抖时间
P0 = 0xFD;
break;
case 4:
SEG_C = 0;
P0 = Tab[SegShow3];
break;
case 5:
SEG_C = 1;
P0 = 0xFB;
break;
case 6:
SEG_D = 0;
P0 = Tab[SegShow4];
break;
case 7:
SEG_D = 1;
{
Key1TimeCont = 0; //计数清零,下次好用
KeyLock = 1; //自锁
KeyCode = 1; //按键值为 1
}
}
/******其他按键同上********/
else if(KeyLock==0&&num==3)
{
Key2TimeCont++;
if(Key2TimeCont>KeyDelayTime)
break; case 3:
SegShow4=3; KeyCode = 0; break; case 4: SegShow4=4; KeyCode = 0; break; } } }
void Timer0_Isr() interrupt 1 {
TF0 = 0; TR0 = 0;
Key_Dispaly_Driver();
TH0 = (65536-1000)/256; TL0 = (65536-1000)%256; TR0 = 1; }
void Key_Dispaly_Driver() //按键检测和数码管显示放一起 {
static uint8 num=0; //顺序扫描 static uint8 Key1TimeCont=0;//key1 去抖延时计数 static uint8 Key2TimeCont=0;//key2 去抖延时计数 static uint8 Key3TimeCont=0;//key3 去抖延时计数 static uint8 Key4TimeCont=0;//key4 去抖延时计数 static uint8 KeyLock=0;
结束语:上面程序有些已经注释了,本人也是看到公司的一个蒸汽流量计的显示电路就是用 此电路来实现数码管和按键公用 IO 口。所以自己就编了个程序来实现其键盘和显示的功能, 如有不对的地方,还望指正。本人是菜鸟,一直很喜欢电子,虽然现在从事的不是这方面的 工作。
{ Key2TimeCont = 0; KeyLock = 1; KeyCode = 2;
} } else if(KeyLock==0&&num==5) {
Key3TimeCont++; if(Key3TimeCont>KeyDelayTime) {
Key3TimeCont = 0; KeyLock = 1; KeyCode = 3; } } else if(KeyLock==0&&num==7) { Key4TimeCont++; if(Key4TimeCont>KeyDelayTime) { Key4TimeCont = 0; KeyLock = 1; KeyCode = 4; } } num++; if(num>7) num = 0; }