第12章 常用单片机接口程序
1静 态 显 示
2动 态 显 示
3独立按键
4矩阵按键
数码管是常用的输出显示器件,按键是常用的信号输入器件。
常见数码管引脚排列如图所示
静态显示电路如下图:
编写字型码关键步骤如下:
① 数码管要显示某个数字或字符,首先根据单只数码管引脚图,确定需要点亮数 码管的哪几段,从而确定数码管8个引脚电平的高低。
例12.1 74HC595移位显示程序,上电后数码管固定显示123456。
unsigned char DispBuf[6];
unsigned char code DispTab[]={0x03,0x9f,0x25,0x0d,0x19,0x41,0x1f,0x01,0x09,
0x11,0xc1,0x63,0x85,0x61,0x71}; // 定义定形码表
void SendData(unsigned char SDat) // 74HC595传送一个字节的数据
{ // 固定代码,直接复制使用
}
void Disp() // 显示位数在6位内不用修改
{
unsigned char c=0,i=0;
CNT=0; // 为产生脉冲上升沿作准备
for(i=0;i<6;i++) // 显示位数需用根据硬件修改
{
c=DispBuf[ i ]; // 取出待显示字符 SendData(DispTab[c]); // 送出字形码数据
}
CNT=1; // 产生脉冲上升沿,并行输出数据
}
void main()
{
unsigned long i=123456; // 123456
DispBuf[0]=i%10; // 个位 DispBuf[1]=i/10%10; // 十位 DispBuf[2]=i/100%10; // 百位 DispBuf[3]=i/1000%10; // 千位 DispBuf[4]=i/10000%10; // 万位 DispBuf[5]=i/100000%10; // 十万位 Disp();
for(;;)
{
; // 程序停在这里
}
}
2 动态显示
这里介绍的动态显示电路如下图所示,看起来有点像静态显示电路,但比静态 显示电路占用硬件要少,比单片机直接驱动数码管占用IO口也要少。
DAT
结合电路图,控制某一位数码管电源通断的位选码就简单多了,如下所示。
例12.3 单片机上电后数码管显示123456
unsigned char code BitTab[]={0xFE,0xFD,0xFB,0x7F,0xBF,0xDF,}; // 位选
code unsigned char DispTab[] = {0x14,0x77,0x4c,0x45,0x27,0x85,0x84,0x57,
0x04,0x05,0x06,0xa4,0x9c,0x64,0x8c,0x8e}; // 字形码
unsigned char DispBuf[6]; // 6字节的显示缓冲区,DispBuf[0]是最低位;
void SendData(unsigned char SendDat) // 74HC595传送一个字节的数据
{ ;// 同例12.1
}
void timer0_init() // 定时器初始化
{
// 2ms定时中断设置
}
void main()
{
timer0_init();
DispBuf[0]=6; DispBuf[1]=5; DispBuf[2]=4;DispBuf[3]=3; DispBuf[4]=2;DispBuf[5]=1;
for(;;)
{
;
}
}
void Timer0() interrupt 1
{
unsigned char tmp; //临时变量
static unsigned char Count=0; //显示程序通过它得知现正显示哪个数码管
// ***************** 重装定时常数 ***************************
TH0=0xf1;
TL0=0x99; // 定时时间为2ms/22.1184MHz
// ******************点亮某位数码管************************** CNT=0; // 为产生脉冲上升沿作准备 SendData(BitTab[Count]); // 最先点亮最右边个位
// ******************输出待显数据************************** tmp=DispBuf[Count]; // 根据当前的计数值取显示缓冲待显示值 tmp=DispTab[tmp]; // 取字形码
SendData(tmp) ;
CNT=1; // 产生脉冲上升沿,并行输出数据
// ******************************************** Count++;
if(Count==6) Count=0;
}
3 独立按键
电路如图所示,单片机引脚作为输入使用,软件首先将接有按键的IO口置1,当键
没有被按下时,单片机引脚上为高电平,而当键被按下后,引脚接地,单片机引 脚上为低电平,通过编程即可获知是否有键按下及按键的位置。
由于机械按键按下和松开瞬间都会产生抖动,为了不让一次按键动作过程中程序产生多
次响应引起混乱,就需要软件去抖动处理,它的思路是:在单片机获得某按键IO口为低 的信息后,不是立即认定该键被按下,而是延时一段时间,通常选择10mS,再次检测IO 口,如果仍为低,则说明该键的确被按下,这避开了按键的前沿抖动,而在检测到按键 释放后(该IO口为高),再延时10mS,消除释放时的后沿抖动,然后再对键值进行处
理,实际的程序中其实一般都是不需要后沿抖动处理的,在后沿抖动的过程中,程序可 能误判为键按下,在键按下后程序会执行前沿延时10mS,所以前沿的10mS延时也就同时 用作了后沿去抖动的10mS。主要程序代码如下:
void main()
{
}
}
}
unsigned char Key() // 获取键值函数
{
unsigned char KValue; // 存放键值
unsigned char tmp; // 临时变量
P3|=0x3c; // 0x3c=0011 1100,将P3口接键盘的中间四位置1
return(0); // 返回,如尚未返回,说明一定有1或更多位被按下
for(;;)
{
tmp=P3; // 等待按键释放
if((tmp|0xc3)==0xff)
break;
}
return(KValue);
}
4 矩阵按键
电路如图所示,只要熟悉了独立按键,矩阵按键也同样的简单。
主要代码如下:
sbit KeyOut1 = P2^7;sbit KeyOut2 = P2^6;sbit KeyOut3 = P2^5;sbit KeyOut4 = P2^4;
sbit KeyIn1 = P2^3;sbit KeyIn2 = P2^2;sbit KeyIn3 = P2^1;sbit KeyIn4 = P2^0; unsigned char
KeyScan()
{
unsigned char key=0xff; // 临时变量
KeyOut1 = 1; KeyOut2 = 1; KeyOut3 = 1; KeyOut4 = 0; // 扫描第1列
if(KeyIn1 == 0)
{
delay10ms(); if(KeyIn1 == 0) key=0x00;
}
if(KeyIn2 == 0)
{
delay10ms(); if(KeyIn2 == 0) key=0x04;
}
if(KeyIn3 == 0)
{
delay10ms(); if(KeyIn3 == 0) key=0x08;
}
if(KeyIn4 == 0)
{
delay10ms(); if(KeyIn4 == 0) key=0x0c;
}
KeyOut1 = 1; KeyOut2 = 1; KeyOut3 = 0; KeyOut4 = 1; // 扫描第2列
if(KeyIn1 == 0)
{
delay10ms(); if(KeyIn1 == 0) key=0x01;
}
……
}
相关帖子
- • STC15单片机+DS3231+DS18B20+DHT11+OLED12864+ESP8266_01S组成网络时间 有待改善
- • 基于单片机的自行车里程表程序 大写N到底是什么性质的变量 在哪里声明
- • proteus仿真时[SPICE] Too many iterations without converge...怎么处理?求指点
- • 可以用单片机制作320*96大规模的点阵吗?
- • 有人能帮我解释下这个单片机公交车自动报站红外模块的原理吗?
- • STC8A8A8K单片机+蓝牙+电机控制+遥控灯--资料和PCB程序源码
- • c语言定时器T0方式2控制led点亮时间1s 仿真led闪得很快
- • stm32按键点灯仿真无反应 求帮助
- • stm32跑马灯仿真错误 求帮助
- • STC15F2K60S2单片机的二十个基本实验程序