数码管动态扫描-按键-流水灯(附仿真图)
时间:10-02
整理:3721RD
点击:
#include<reg52.h>
#define uchar unsigned char //无符号char类型
#define uint unsigned int //无符号int类型
/************************常用位抄作指令*****************************/
#define set_bit(x,y) (x|=(1<<y)) //位置1
#define clr_bit(x,y) (x&=~(1<<y)) //位清0
#define get_bit(x,y) (x&(1<<y)) //位查询
#define xor_bit(x,y) (x^=(1<<y)) //位取反
#define MAKEWORD(v1,v2) (((uint)(v1)<<8) + (uint)(v2)) //高低位字节组合为一个字v1高,v2低
#define HIBYTE(v1) ((uchar)((v1)>>8)) //取高位字节
#define LOBYTE(v1) ((uchar)((v1)&0xff)) //取低位字节
#define nop() _nop_
/********************************************************************/
#define LongToBin(n) \
( \
((n >> 21) & 0x80) | \
((n >> 18) & 0x40) | \
((n >> 15) & 0x20) | \
((n >> 12) & 0x10) | \
((n >> 9) & 0x08) | \
((n >> 6) & 0x04) | \
((n >> 3) & 0x02) | \
((n ) & 0x01) \
)
#define Bin(n) LongToBin(0x##n##l) //write binary charactor set,exsample : Bin(11111111) = 0xff
//*******************************数码管com口定义**********************************//
#define display_location_1_set set_bit(P3,0)//P3_3=1
#define display_location_1_clr clr_bit(P3,0)//P3_3=0
#define display_location_2_set set_bit(P3,1)//P3_2=1
#define display_location_2_clr clr_bit(P3,1)//P3_2=0
#define display_location_3_set set_bit(P3,2)//P3_1=1
#define display_location_3_clr clr_bit(P3,2)//P3_1=0
#define display_location_4_set set_bit(P3,3)//P3_0=1
#define display_location_4_clr clr_bit(P3,3)//P3_0=0
//*******************************数码管断码定义**********************************//
#define display_1_set set_bit(P2,0)//P1_4=0
#define display_1_clr clr_bit(P2,0)//P1_4=1
#define display_2_set set_bit(P2,1)//P1_6=0
#define display_2_clr clr_bit(P2,1)//P1_6=1
#define display_3_set set_bit(P2,2)//P2_5=0
#define display_3_clr clr_bit(P2,2)//P2_5=1
#define display_4_set set_bit(P2,3)//P2_3=0
#define display_4_clr clr_bit(P2,3)//P2_3=1
#define display_5_set set_bit(P2,4)//P2_2=0
#define display_5_clr clr_bit(P2,4)//P2_2=1
#define display_6_set set_bit(P2,5)//P1_5=0
#define display_6_clr clr_bit(P2,5)//P1_5=1
#define display_7_set set_bit(P2,6)//P2_6=0
#define display_7_clr clr_bit(P2,6)//P2_6=1
#define display_8_set set_bit(P2,7)//P2_4=0
#define display_8_clr clr_bit(P2,7)//P2_4=1
uchar bite=1; //数码管位转换数据
//*****************************时间标记变量*************************************//
uchar r_timer_2ms=0; //2ms计数累加器
bit f_timer_2ms=0; //2ms标记
uchar r_timer_500ms=0; //500ms计数累加器
bit f_timer_500ms=0; //500ms标记
uchar key_data_old=0; //按键编码上一状态保持寄存器
uint show_data=1000; //数码管显示数值保持寄存器
//**********************************稳定性处理函数***************************//
uint key_keep_timer[8]; //稳定性计数次数初始化为0
uchar key_station=0; //稳定性状态标志信号反馈
//*****************************数码管BCD码值*************************************//
code unsigned char LED_DATA[10] ={0x03,0x9f,0x25,0x0d,0x99,0x49,0x41,0x1f,
// 0 1 2 3 4 5 6 7
0x01,0x09,};//,0x3e,0x9c,0x7a,0x9e,0x8e};
// 8 9 - 消 e c d e f
void scan_io(uchar LED_TABLE)
{
//*******************************************************************************//
if(LED_TABLE & 0x80) display_1_set;else display_1_clr; //a段码控制
if(LED_TABLE & 0x40) display_2_set;else display_2_clr; //b段码控制
if(LED_TABLE & 0x20) display_3_set;else display_3_clr; //c段码控制
if(LED_TABLE & 0x10) display_4_set;else display_4_clr; //d段码控制
if(LED_TABLE & 0x08) display_5_set;else display_5_clr; //e段码控制
if(LED_TABLE & 0x04) display_6_set;else display_6_clr; //f段码控制
if(LED_TABLE & 0x02) display_7_set;else display_7_clr; //g段码控制
if(LED_TABLE & 0x01) display_8_set;else display_8_set; //H段码控制
//*******************************************************************************//
}
void scan_lcd(uint Timer_Count_show)
{
unsigned char temp_data1;unsigned char temp_data2;unsigned char temp_data3;unsigned char temp_data4;unsigned char LED_TABLE;
//********************数码管1-4全消隐,避免产生鬼影******************************//
display_location_1_clr; //数码管1消隐
display_location_2_clr; //数码管2消隐
display_location_3_clr; //数码管3消隐
display_location_4_clr; //数码管4消隐
display_1_clr;display_2_clr;display_3_clr; //消隐数码屏
display_4_clr;display_5_clr;display_6_clr; //消隐数码屏
display_7_clr;display_8_clr; //消隐数码屏
//*******************************获取个位*******************************//
temp_data1=Timer_Count_show/1000;
temp_data2=Timer_Count_show%1000/100;
temp_data3=Timer_Count_show%1000%100/10;
temp_data4=Timer_Count_show%1000%100%10;
switch(bite)
{
case 1: //千位
{
bite=2;
display_location_1_set;
//******************************获取查表数值*************************************//
LED_TABLE=LED_DATA[temp_data1]; //获取查表数值
//******************************************************//
break;
}
case 2: //百位
{
bite=3;
display_location_2_set;
//******************************获取查表数值*************************************//
LED_TABLE=LED_DATA[temp_data2]; //获取查表数值
//*******************************************************************************//
break;
}
case 3: //十位
{
bite=4;
display_location_3_set;
//******************************获取查表数值*************************************//
LED_TABLE=LED_DATA[temp_data3]; //获取查表数值
//*******************************************************************************//
break;
}
case 4:
{
bite=1; //个位
display_location_4_set;
//******************************获取查表数值*************************************//
LED_TABLE=LED_DATA[temp_data4]; //获取查表数值
//*******************************************************************************//
break;
}
default:break;
}
scan_io(LED_TABLE); //数码管扫描
}
/*===================定时器1初始化程序区=====================*/
/*16.6M12分频时钟,八位自动重装定时125us定时器*/
void timer0_init(void)
{
clr_bit(TMOD,0); //M01 0 0 : 13 位定时器/计数器 0 1 : 16 位定时器/计数器
set_bit(TMOD,1); //M11 1 0 : 8 位自动重载定时器 1 1 : 定时器0 此时作为双8 位定时器/计数器
clr_bit(TMOD,2); //C/T1 0:定时器,T0 计数来源于Fosc 分频 1:计数器,T0 计数来源于外部管脚T0/P1.2
clr_bit(TMOD,3); //GATE1 TMOD[3]控制定时器0,置0 且TR0 置1 时才打开T0
//1-T1FD T1 输入频率选择控制 0:T1 频率源自于Fosc/12 1:T1 频率源自于Fosc/4
//0-T0FD T1 输入频率选择控制 0:T1 频率源自于Fosc/12 1:T1 频率源自于Fosc/4
TL0=0x83; //8位自动重载125us一次中断
TH0=0x83;
TR0=0; //定时器T1的运行控制位。打开timer1前,先清TRO
ET0=1; //允许timer1中断
TR0=1; //允许timer1开始计数
EA=1;
}
/***********************定时器1中断入口函数**************************/
void timer0() interrupt 1 //125us中断一次
{
r_timer_2ms++;
xor_bit(P3,5);
if(r_timer_2ms>=16) //125us*16=2ms
{
r_timer_2ms=0;
f_timer_2ms=1;
}
}
//**************************************************************************//
void key_station_scan(uchar station,uint click_timer,uchar keep_way) //稳定性检测函数 station 为输入状态检测信号
{ //click_timer为检测次数 keep_way为利用的函数信号通道
if(station) //信号输入比较是否为1
{
if(key_keep_timer[keep_way]==click_timer) //计数对比是否达到稳定性次数要求
set_bit(key_station,keep_way); //状态标记置位
if(key_keep_timer[keep_way]<65535) //防计数溢出
key_keep_timer[keep_way]++; //计数未达到要求继续累加计数
}
else //稳定性信号不符合清楚计数和标记
{
key_keep_timer[keep_way]=0; //计数器清零
clr_bit(key_station,keep_way); //状态标记清零
}
}
void key_deal(void) //按键功能处理
{
uchar key_data=0;
if(get_bit(P3,7))set_bit(key_data,0);
if(get_bit(P3,6))set_bit(key_data,1);
key_station_scan(key_data_old==key_data,10,0); //检测是否有联系20次按键稳定值
key_data_old=key_data; //按键状态值更新
if(get_bit(key_station,0))
{clr_bit(key_station,0); //检测到稳定的按键值信号标记
switch(key_data) //检测到按键稳定性后进行按键解码处理
{
case Bin(00000001):show_data++;break; //+
case Bin(00000010):show_data--;break; //-
}
}
}
void timer_count(void) //时间标记计数函数
{
r_timer_500ms++;
if(r_timer_500ms>=10)
{
r_timer_500ms=0;
f_timer_500ms=1; //置位500ms时间基准标记
}
}
uchar P1_data=Bin(00000001);
void liushui_led(void)
{
if(f_timer_500ms)
{f_timer_500ms=0;
P1_data=(P1_data<<1);
if(!P1_data){P1_data=Bin(00000001);}
P1=P1_data;
}
}
void main()
{
timer0_init(); //定时器0初始化
P1=Bin(00000000);
while(1)
{
if(f_timer_2ms) //2ms执行一次主程序
{
f_timer_2ms=0; //时间标记清零
key_deal(); //按键处理函数
scan_lcd(show_data); //数码管显示函数
timer_count(); //时间基准函数
liushui_led(); //流水灯处理
xor_bit(P3,4);
}
}
}
#define uchar unsigned char //无符号char类型
#define uint unsigned int //无符号int类型
/************************常用位抄作指令*****************************/
#define set_bit(x,y) (x|=(1<<y)) //位置1
#define clr_bit(x,y) (x&=~(1<<y)) //位清0
#define get_bit(x,y) (x&(1<<y)) //位查询
#define xor_bit(x,y) (x^=(1<<y)) //位取反
#define MAKEWORD(v1,v2) (((uint)(v1)<<8) + (uint)(v2)) //高低位字节组合为一个字v1高,v2低
#define HIBYTE(v1) ((uchar)((v1)>>8)) //取高位字节
#define LOBYTE(v1) ((uchar)((v1)&0xff)) //取低位字节
#define nop() _nop_
/********************************************************************/
#define LongToBin(n) \
( \
((n >> 21) & 0x80) | \
((n >> 18) & 0x40) | \
((n >> 15) & 0x20) | \
((n >> 12) & 0x10) | \
((n >> 9) & 0x08) | \
((n >> 6) & 0x04) | \
((n >> 3) & 0x02) | \
((n ) & 0x01) \
)
#define Bin(n) LongToBin(0x##n##l) //write binary charactor set,exsample : Bin(11111111) = 0xff
//*******************************数码管com口定义**********************************//
#define display_location_1_set set_bit(P3,0)//P3_3=1
#define display_location_1_clr clr_bit(P3,0)//P3_3=0
#define display_location_2_set set_bit(P3,1)//P3_2=1
#define display_location_2_clr clr_bit(P3,1)//P3_2=0
#define display_location_3_set set_bit(P3,2)//P3_1=1
#define display_location_3_clr clr_bit(P3,2)//P3_1=0
#define display_location_4_set set_bit(P3,3)//P3_0=1
#define display_location_4_clr clr_bit(P3,3)//P3_0=0
//*******************************数码管断码定义**********************************//
#define display_1_set set_bit(P2,0)//P1_4=0
#define display_1_clr clr_bit(P2,0)//P1_4=1
#define display_2_set set_bit(P2,1)//P1_6=0
#define display_2_clr clr_bit(P2,1)//P1_6=1
#define display_3_set set_bit(P2,2)//P2_5=0
#define display_3_clr clr_bit(P2,2)//P2_5=1
#define display_4_set set_bit(P2,3)//P2_3=0
#define display_4_clr clr_bit(P2,3)//P2_3=1
#define display_5_set set_bit(P2,4)//P2_2=0
#define display_5_clr clr_bit(P2,4)//P2_2=1
#define display_6_set set_bit(P2,5)//P1_5=0
#define display_6_clr clr_bit(P2,5)//P1_5=1
#define display_7_set set_bit(P2,6)//P2_6=0
#define display_7_clr clr_bit(P2,6)//P2_6=1
#define display_8_set set_bit(P2,7)//P2_4=0
#define display_8_clr clr_bit(P2,7)//P2_4=1
uchar bite=1; //数码管位转换数据
//*****************************时间标记变量*************************************//
uchar r_timer_2ms=0; //2ms计数累加器
bit f_timer_2ms=0; //2ms标记
uchar r_timer_500ms=0; //500ms计数累加器
bit f_timer_500ms=0; //500ms标记
uchar key_data_old=0; //按键编码上一状态保持寄存器
uint show_data=1000; //数码管显示数值保持寄存器
//**********************************稳定性处理函数***************************//
uint key_keep_timer[8]; //稳定性计数次数初始化为0
uchar key_station=0; //稳定性状态标志信号反馈
//*****************************数码管BCD码值*************************************//
code unsigned char LED_DATA[10] ={0x03,0x9f,0x25,0x0d,0x99,0x49,0x41,0x1f,
// 0 1 2 3 4 5 6 7
0x01,0x09,};//,0x3e,0x9c,0x7a,0x9e,0x8e};
// 8 9 - 消 e c d e f
void scan_io(uchar LED_TABLE)
{
//*******************************************************************************//
if(LED_TABLE & 0x80) display_1_set;else display_1_clr; //a段码控制
if(LED_TABLE & 0x40) display_2_set;else display_2_clr; //b段码控制
if(LED_TABLE & 0x20) display_3_set;else display_3_clr; //c段码控制
if(LED_TABLE & 0x10) display_4_set;else display_4_clr; //d段码控制
if(LED_TABLE & 0x08) display_5_set;else display_5_clr; //e段码控制
if(LED_TABLE & 0x04) display_6_set;else display_6_clr; //f段码控制
if(LED_TABLE & 0x02) display_7_set;else display_7_clr; //g段码控制
if(LED_TABLE & 0x01) display_8_set;else display_8_set; //H段码控制
//*******************************************************************************//
}
void scan_lcd(uint Timer_Count_show)
{
unsigned char temp_data1;unsigned char temp_data2;unsigned char temp_data3;unsigned char temp_data4;unsigned char LED_TABLE;
//********************数码管1-4全消隐,避免产生鬼影******************************//
display_location_1_clr; //数码管1消隐
display_location_2_clr; //数码管2消隐
display_location_3_clr; //数码管3消隐
display_location_4_clr; //数码管4消隐
display_1_clr;display_2_clr;display_3_clr; //消隐数码屏
display_4_clr;display_5_clr;display_6_clr; //消隐数码屏
display_7_clr;display_8_clr; //消隐数码屏
//*******************************获取个位*******************************//
temp_data1=Timer_Count_show/1000;
temp_data2=Timer_Count_show%1000/100;
temp_data3=Timer_Count_show%1000%100/10;
temp_data4=Timer_Count_show%1000%100%10;
switch(bite)
{
case 1: //千位
{
bite=2;
display_location_1_set;
//******************************获取查表数值*************************************//
LED_TABLE=LED_DATA[temp_data1]; //获取查表数值
//******************************************************//
break;
}
case 2: //百位
{
bite=3;
display_location_2_set;
//******************************获取查表数值*************************************//
LED_TABLE=LED_DATA[temp_data2]; //获取查表数值
//*******************************************************************************//
break;
}
case 3: //十位
{
bite=4;
display_location_3_set;
//******************************获取查表数值*************************************//
LED_TABLE=LED_DATA[temp_data3]; //获取查表数值
//*******************************************************************************//
break;
}
case 4:
{
bite=1; //个位
display_location_4_set;
//******************************获取查表数值*************************************//
LED_TABLE=LED_DATA[temp_data4]; //获取查表数值
//*******************************************************************************//
break;
}
default:break;
}
scan_io(LED_TABLE); //数码管扫描
}
/*===================定时器1初始化程序区=====================*/
/*16.6M12分频时钟,八位自动重装定时125us定时器*/
void timer0_init(void)
{
clr_bit(TMOD,0); //M01 0 0 : 13 位定时器/计数器 0 1 : 16 位定时器/计数器
set_bit(TMOD,1); //M11 1 0 : 8 位自动重载定时器 1 1 : 定时器0 此时作为双8 位定时器/计数器
clr_bit(TMOD,2); //C/T1 0:定时器,T0 计数来源于Fosc 分频 1:计数器,T0 计数来源于外部管脚T0/P1.2
clr_bit(TMOD,3); //GATE1 TMOD[3]控制定时器0,置0 且TR0 置1 时才打开T0
//1-T1FD T1 输入频率选择控制 0:T1 频率源自于Fosc/12 1:T1 频率源自于Fosc/4
//0-T0FD T1 输入频率选择控制 0:T1 频率源自于Fosc/12 1:T1 频率源自于Fosc/4
TL0=0x83; //8位自动重载125us一次中断
TH0=0x83;
TR0=0; //定时器T1的运行控制位。打开timer1前,先清TRO
ET0=1; //允许timer1中断
TR0=1; //允许timer1开始计数
EA=1;
}
/***********************定时器1中断入口函数**************************/
void timer0() interrupt 1 //125us中断一次
{
r_timer_2ms++;
xor_bit(P3,5);
if(r_timer_2ms>=16) //125us*16=2ms
{
r_timer_2ms=0;
f_timer_2ms=1;
}
}
//**************************************************************************//
void key_station_scan(uchar station,uint click_timer,uchar keep_way) //稳定性检测函数 station 为输入状态检测信号
{ //click_timer为检测次数 keep_way为利用的函数信号通道
if(station) //信号输入比较是否为1
{
if(key_keep_timer[keep_way]==click_timer) //计数对比是否达到稳定性次数要求
set_bit(key_station,keep_way); //状态标记置位
if(key_keep_timer[keep_way]<65535) //防计数溢出
key_keep_timer[keep_way]++; //计数未达到要求继续累加计数
}
else //稳定性信号不符合清楚计数和标记
{
key_keep_timer[keep_way]=0; //计数器清零
clr_bit(key_station,keep_way); //状态标记清零
}
}
void key_deal(void) //按键功能处理
{
uchar key_data=0;
if(get_bit(P3,7))set_bit(key_data,0);
if(get_bit(P3,6))set_bit(key_data,1);
key_station_scan(key_data_old==key_data,10,0); //检测是否有联系20次按键稳定值
key_data_old=key_data; //按键状态值更新
if(get_bit(key_station,0))
{clr_bit(key_station,0); //检测到稳定的按键值信号标记
switch(key_data) //检测到按键稳定性后进行按键解码处理
{
case Bin(00000001):show_data++;break; //+
case Bin(00000010):show_data--;break; //-
}
}
}
void timer_count(void) //时间标记计数函数
{
r_timer_500ms++;
if(r_timer_500ms>=10)
{
r_timer_500ms=0;
f_timer_500ms=1; //置位500ms时间基准标记
}
}
uchar P1_data=Bin(00000001);
void liushui_led(void)
{
if(f_timer_500ms)
{f_timer_500ms=0;
P1_data=(P1_data<<1);
if(!P1_data){P1_data=Bin(00000001);}
P1=P1_data;
}
}
void main()
{
timer0_init(); //定时器0初始化
P1=Bin(00000000);
while(1)
{
if(f_timer_2ms) //2ms执行一次主程序
{
f_timer_2ms=0; //时间标记清零
key_deal(); //按键处理函数
scan_lcd(show_data); //数码管显示函数
timer_count(); //时间基准函数
liushui_led(); //流水灯处理
xor_bit(P3,4);
}
}
}
顶顶顶顶顶顶顶顶顶顶顶顶顶顶
先谢谢小编的分享精神, 稍后认真看看小编的代码, 对于按键这个地方, 一直是似懂非懂!
有不理解需要咨询可以问我,很乐意帮忙
好帖,做个记号!
好东西就应该给大家分享才行
好的!谢谢小编!
谢谢小编分享啊,好东西
都是实际应用开发中的精华提取,供大家学习和应用