第十六课 按键之二 独立按键之按键计数
程序讲解:
/*--------------------------------------------------------------*/
//LED八位数码滚动显示
//显示部分用中断方式,便于程序的拓展
/*--------------------------------------------------------------*/
//包含头文件
#include <reg52.h>
#include "74HC595.H" //数码管驱动
//对应开发板端口
sbit K1 = P3^2;
sbit K2 = P3^3;
sbit K3 = P3^4;
sbit K4 = P3^5;
//全局变量定义
unsigned char LED_Pos; //位扫描
unsigned char LED_Seg[8] = {16,16,16,16,16,16,16,16}; //每位数码管要显示的数据缓存
unsigned int x;
/*--------------------------------------------------------------*/
//定时器初始化 前面讲的比较多了这里就简单提下
void T0_init(void)
{
TMOD = 0x01; //定时器0工作在方式1
TH0 = 0xf8; //2000us
TL0 = 0x36;
IE = 0x82; //开总中断和定时器 1中断
TR0 = 1; //允许定时器0工作
}
/*--------------------------------------------------------------*/
void delay10ms(void)
{
unsigned char i,j;
for(i=201;i>0;i--)
for(j=32;j>0;j--);
}
/*--------------------------------------------------------------*/
//LED显示函数2
volatile void LED_Display2(void)
{
Ser_IN(0x80 >> LED_Pos); //位选 每次选中一位
Ser_IN(seg[LED_Seg[LED_Pos]]); //段选 数组seg[]是段码,在74HC595.H"头文件里面
Par_OUT(); //产生上升沿 锁存输出
LED_Pos++; //循环扫描
if(LED_Pos == 8) LED_Pos = 0; //LED_Pos控制位选和段选
}
/*--------------------------------------------------------------*/
//更新数据LED_Seg[8] (每位数码管要显示的数据 )
volatile void Display_pro(void)
{
unsigned char i;
unsigned int temp;
i = 0;
temp = x;
while(temp/10) //判断temp是否为个位数,不是则进入while()循环进行处理
{
LED_Seg = temp%10; //取最低位(个位)送到i对应的数码管位
temp /= 10; //temp右移一位,百位变十位,十位变个位,个位消失(减小10倍)
i++; //指向下位数码管数据
}
LED_Seg = temp; //最高位
i++;
while(i < 8) LED_Seg[i++] = 16; //若高位为0则不显示,16 在数码管段码表数组(seg[])里面的段码为全灭
}
/*--------------------------------------------------------------*/
//中断显示
//定时器中断服务
void T0_intservice(void) interrupt 1
{
TH0 = 0xf8;
TL0 = 0x36;
LED_Display2();
}
/*-------------------------------------------------------------*/
//主函数
void main(void)
{
bit inc;
bit dec;
T0_init();
while(1)
{
if (K1 == 0){delay10ms(); if(K1 == 0) x++; while(K1 == 0);} //手动加
if (K2 == 0){delay10ms(); if(K2 == 0) x--; while(K2 == 0);} //手动减
if (K3 == 0){delay10ms(); if(K3 == 0) inc = ~inc;while(K3 == 0);} //开启(关闭)自动加
if (K4 == 0){delay10ms(); if(K4 == 0) dec = ~dec;while(K4 == 0);} //开启(关闭)自动减
if(inc) x++; //自动加
if(dec) x--; //自动减
Display_pro(); //将要显示的数据写入到缓存
}
}
本节重点:
1、数码管要显示数据的更新。
Display_pro();这个函数即实现了这个功能,比方说数码管要显示的数据室543210,这个函数就可以把0送到数据缓冲区数组(LED_Seg[8] )的最低位(从右至左的第一位),1送到次低位(从右至左的第二位),以此类推。543210只有六位数据,实验板上有8位数码管显然高两位没有要显示的数据,此时利用语句 while(i < 8) LED_Seg[i++] = 16; 即可让高两位关闭显示。这样就实现了数码管显示数据的更新。大家可以慢慢体会一下这个子函数!
2、Display_pro();函数处理数据的过程。
首先判断要显示的数据是否为个位数,是个位数,则直接去他的个位数,将它送到LED_Seg (此时i = 0)就是将数据送到最右(低位)边的那个数码管显示。若不是个位数则进入while()进行处理,首先去要显示数据的最低位,送到LED_Seg (此时i = 0),然后将要显示的数据 temp减小10倍(百位变十位,十位变个位,个位消失)供十位数据的缓存。若 temp减小10倍的temp为个位数了,就执行 LED_Seg = temp;此时 i = 1;即将要显示的数据的十位送到了第二位数码管(从右至左)。百位数、千位数依次类推!
注:写的比较繁琐,就是实现数码管要显示数据的更新!
演示视频:
http://v.youku.com/v_show/id_XOTIzNjI1NTY=.html
相关程序:https://static.assets-stash.eet-china.com/album/old-resources/2009/5/31/8a32a946-1e1b-417b-b47e-cf80f0c1a8f2.rar
文章评论(0条评论)
登录后参与讨论