C-一个独立键盘按键显示到数码管部分代码看不懂
#include<reg52.h> //包含头文件,一般情况不需要改动,头文件包含特殊功能
#define DataPort P0 //定义数据端口程序中遇到DataPort 则用P0 替换
#define KeyPort P3
sbit dula=P2^0;//段锁存
sbit wela=P2^1;//位锁存
sbit CS88=P2^2;//8x8 点阵锁存端
void G88(); //函数声明关点阵函数
unsigned char code
dofly_DuanMa[]={0x3F, //"0"
0x06, //"1"
0x5B, //"2"
0x4F, //"3"
0x66, //"4"
0x6D, //"5"
0x7D, //"6"
0x07, //"7"
0x7F, //"8"
0x6F, //"9"
0x77, //"A"
0x7C, //"B"
0x39, //"C"
0x5E, //"D"
0x79, //"E"
0x71, //"F"
0x76, //"H"
0x38, //"L"
0x37, //"n"
0x3E, //"u"
0x73, //"P"
0x5C, //"o"0x40, //"-"
0x00, //熄灭
0x00 //自定义
};// 显示段码值0~F
unsigned char code
dofly_WeiMa[]={0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0xbf,0x7f};//分别对应相对位数
unsigned char TempData[8]; //存储显示值的全局变量
void DelayUs2x(unsigned char t);//us 级延时函数声明
void DelayMs(unsigned char t); //ms 级延时
void Display(unsigned char FirstBit,unsigned char Num);//数码管显示函数
void Init_Timer0(void);//定时器初始化
KeyPro();
/*------------------------------------------------
主函数
------------------------------------------------*/
void main (void)
{
unsigned char num,i,j;
unsigned char temp[8];
Init_Timer0();
G88();//关点阵
while (1) //主循环
{
num=KeyPro();
if(num!=0xff)
{
if(i<8)
{
temp[i]=dofly_DuanMa[num];
for(j=0;j<=i;j++)
TempData[7-i+j]=temp[j];
}
i++;
if(i==9)//多出一个按键输入为了清屏原本应该为8
{
i=0;
for(j=0;j<8;j++)//清屏
TempData[j]=0;
}
}
//Display(0,8); //显示全部8 位
//主循环中添加其他需要一直工作的程序
}
}
/*------------------------------------------------
uS 延时函数,含有输入参数unsigned char t,无返回值
unsigned char 是定义无符号字符变量,其值的范围是
0~255 这里使用晶振12M,精确延时请使用汇编,大致延时
长度如下T=tx2+5 uS
------------------------------------------------*/
void DelayUs2x(unsigned char t)
{
while(--t);
}
void DelayMs(unsigned char t)
{
while(t--)
{
//大致延时1mS
DelayUs2x(245);
DelayUs2x(245);
}
}
/*------------------------------------------------
显示函数,用于动态扫描数码管
输入参数FirstBit 表示需要显示的第一位,如赋值2 表示从第三个数码管开
始显示
如输入0 表示从第一个显示。
Num 表示需要显示的位数,如需要显示99 两位数值则该值输入2
------------------------------------------------*/
void Display(unsigned char FirstBit,unsigned char Num)
{
static unsigned char i=0;
DataPort=0; //清空数据,防止有交替重影
dula=1; //段锁存
dula=0;
DataPort=dofly_WeiMa[i+FirstBit]; //取位码
wela=1; //位锁存
wela=0;
DataPort=TempData[i]; //取显示数据,段码
dula=1; //段锁存
dula=0;
i++;
if(i==Num)
i=0;
}
void Init_Timer0(void)
{
TMOD |= 0x01; //使用模式1,16 位定时器,使用"|"符号可以在使用多
//TH0=0x00; //给定初值
//TL0=0x00;
EA=1; //总中断打开
ET0=1; //定时器中断打开
TR0=1; //定时器开关打开
}
void Timer0_isr(void) interrupt 1
{
TH0=(65536-2000)/256; //重新赋值2ms
TL0=(65536-2000)%256;
Display(0,8); // 调用数码管扫描
}
KeyPro()
{
P3=0xff;
switch (P3)
{
case 0x7f:DelayMs(200);return 0;break;
case 0xbf:DelayMs(200);return 1;break;
case 0xdf:DelayMs(200);return 2;break;
case 0xef:DelayMs(200);return 3;break;
case 0xf7:DelayMs(200);return 4;break;
case 0xfb:DelayMs(200);return 5;break;
case 0xfd:DelayMs(200);return 6;break;
case 0xfe:DelayMs(200);return 7;break;
default:DelayMs(200);return 0xff;break;
}
}
void G88() //关点阵函数
{
CS88=1; //打开点阵锁存
P0=0xff; //关掉点阵显示
CS88=0; //锁存
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
先介绍一下,多位数码管是不能同时点亮所有位的,一次只能点亮其中一位,但若以一定频率交替点亮每个位的话,只要频率够快,肉眼就不会感觉到闪烁感。
display函数里,用静态变量i保存当前的显示位置,每次进入display,
1. 先清屏,即什么都不显示;
2. 更新位码,即选择要点亮哪一位;(按i偏移)
3. 更新段码,点亮那一位;
4. 更新i(下次更新位码时取下一位);
5. 如果i到了最大num,清零,下次循环显示。
如果想验证的话,在display函数中加一个延时函数(延时500ms以上),肉眼就很容易看出闪烁的效果了。