基于吴坚鸿与祁绪电子程序修改
单片机源程序如下:
- #include "REG52.H"
- #define const_voice_short 40 //蜂鸣器短叫的持续时间
- #define const_key_time1 20 //按键去抖动延时的时间
- #define const_key_time2 20 //按键去抖动延时的时间
- #define const_key_time3 20 //按键去抖动延时的时间
- void initial_myself();
- void initial_peripheral();
- void delay_short(unsigned int uiDelayshort);
- void delay_long(unsigned int uiDelaylong);
- void dig_hc595_drive(unsigned char ucDigStatusTemp16_09,unsigned char ucDigStatusTemp08_01);
- void display_drive();//显示数码管字模的驱动函数
- void display_service();//显示的窗口菜单服务程序
- void T0_time();//定时中断函数
- void key_service();//按键服务的应用程序
- void key_scan();//按键扫描函数 放在定时中断里
- sbit key_sr1=P1^0;
- sbit key_sr2=P1^1;
- sbit key_sr3=P1^2;
- sbit beep_dr=P2^7;//蜂鸣器的驱动 IO 口
- sbit led_dr=P3^5;//作为中途暂停指示灯 亮的时候表示中途暂停
- sbit dig_hc595_sh_dr=P2^3; //数码管的 74HC595 程序
- sbit dig_hc595_st_dr=P2^4;
- sbit dig_hc595_ds_dr=P2^5;
- sbit hc595_sh_dr=P2^0;//LED 灯的 74HC595 程序
- sbit hc595_st_dr=P2^1;
- sbit hc595_ds_dr=P2^2;
- unsigned char ucKeySec=0;//被触发的按键编号
- unsigned int uiKeyTimeCnt1=0;//按键去抖动延时计数器
- unsigned char ucKeyLock1=0;//按键触发后自锁的变量标志
- unsigned int uiKeyTimeCnt2=0;//按键去抖动延时计数器
- unsigned char ucKeyLock2=0;//按键触发后自锁的变量标志
- unsigned int uiKeyTimeCnt3=0;//按键去抖动延时计数器
- unsigned char ucKeyLock3=0;//按键触发后自锁的变量标志
- unsigned int uiVoiceCnt=0;//蜂鸣器鸣叫的持续时间计数器
- unsigned char ucDigShowTemp=0;//临时中间变量
- unsigned char ucDisplayDriveStep=1;//动态扫描数码管的步骤变量
- unsigned char ucWd1Update=1;//窗口 1 更新显示标志
- unsigned char ucWd2Update=0;//窗口 2 更新显示标志
- unsigned char ucWd3Update=0;//窗口 3 更新显示标志
- unsigned char ucWd4Update=0;//窗口 4 更新显示标志
- unsigned char ucWd=1;//本程序的核心变量,窗口显示变量。类似于一级菜单的变量。代表显示不同的窗口。
- unsigned int uiSetData1=999;//本程序中需要被设置的参数 1
- unsigned int uiSetData2=99;//本程序中需要被设置的参数 2
- unsigned int uiSetData3=9;//本程序中需要被设置的参数 3
- unsigned int uiSetData4=1;//本程序中需要被设置的参数 4
- //根据原理图得出的共阴数码管字模表
- code unsigned char dig_table[]=
- {
- 0x3f, //0 序号 0
- 0x06, //1 序号 1
- 0x5b, //2 序号 2
- 0x4f, //3 序号 3
- 0x66, //4 序号 4
- 0x6d, //5 序号 5
- 0x7d, //6 序号 6
- 0x07, //7 序号 7
- 0x7f, //8 序号 8
- 0x6f, //9 序号 9
- 0x00, //无 序号 10
- 0x40, //- 序号 11
- 0x73, //P 序号 12
- };
- code unsigned char dig[]={0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0xbf,0x7f,};
- unsigned char ucDigDot[8];//要显示的8个小数点
- unsigned char ucDigShow[8];//要显示的8个数字
- void main()
- {
- initial_myself();
- delay_long(100);
- initial_peripheral();
- while(1)
- {
- key_service();//按键服务的应用程序
- display_service();//显示的窗口菜单服务程序
- }
- }
- void display_service() //显示的窗口菜单服务程序
- { unsigned char i;
- unsigned int temp;
- switch(ucWd) //本程序的核心变量,窗口显示变量。类似于一级菜单的变量。代表显示不同的窗口。
- {
- case 1: //显示 P--1 窗口的数据
- if(ucWd1Update==1) //窗口 1 要全部更新显示
- {
- ucWd1Update=0;//及时清零标志,避免一直进来扫描
- ucDigShow[7]=12;//第 8 位数码管显示 P
- ucDigShow[6]=11;//第 7 位数码管显示-
- ucDigShow[5]=1;//第 6 位数码管显示 1
- ucDigShow[4]=10;//第 5 位数码管显示无
- temp=uiSetData1;
- for(i=0;i<4;i++)//分解数字
- {
- ucDigShow[i]=temp%10;
- temp=temp/10;
- }
- for(i=3;i>=1;i--) //高位为0不显示
- {
- if( ucDigShow[i]==0)
- ucDigShow[i]=10;
- else break;
- }
- } break;
- case 2: //显示 P--2 窗口的数据
- if(ucWd2Update==1) //窗口 2 要全部更新显示
- {
- ucWd2Update=0;//及时清零标志,避免一直进来扫描
- ucDigShow[7]=12;//第 8 位数码管显示 P
- ucDigShow[6]=11;//第 7 位数码管显示-
- ucDigShow[5]=2;//第 6 位数码管显示 1
- ucDigShow[4]=10;//第 5 位数码管显示无
- temp=uiSetData2;
- for(i=0;i<4;i++)//分解数字
- {
- ucDigShow[i]=temp%10;
- temp=temp/10;
- }
- for(i=3;i>=1;i--) //高位为0不显示
- {
- if( ucDigShow[i]==0)
- ucDigShow[i]=10;
- else
- break;
- }
-
- }break;
- case 3: //显示 P--3 窗口的数据
- if(ucWd3Update==1) //窗口 3 要全部更新显示
- {
- ucWd3Update=0;//及时清零标志,避免一直进来扫描
- ucDigShow[7]=12;//第 8 位数码管显示 P
- ucDigShow[6]=11;//第 7 位数码管显示-
- ucDigShow[5]=3;//第 6 位数码管显示 1
- ucDigShow[4]=10;//第 5 位数码管显示无
- temp=uiSetData3;
- for(i=0;i<4;i++)
- {
- ucDigShow[i]=temp%10;
- temp=temp/10;
- }
- if(uiSetData3<1000)
- {
- ucDigShow[3]=10;
- if(uiSetData3<100)
- {
- ucDigShow[2]=10;
- if(uiSetData3<10)
- {
- ucDigShow[1]=10;
- }
- }
- }
- }break;
- case 4: //显示 P--4 窗口的数据
- if(ucWd4Update==1) //窗口 4 要全部更新显示
- {
- ucWd4Update=0;//及时清零标志,避免一直进来扫描
- ucDigShow[7]=12;//第 8 位数码管显示 P
- ucDigShow[6]=11;//第 7 位数码管显示-
- ucDigShow[5]=4;//第 6 位数码管显示 1
- ucDigShow[4]=10;//第 5 位数码管显示无
- temp=uiSetData4;
- for(i=0;i<4;i++)
- {
- ucDigShow[i]=temp%10;
- temp=temp/10;
- }
- if(uiSetData4<1000)
- {
- ucDigShow[3]=10;
- if(uiSetData4<100)
- {
- ucDigShow[2]=10;
- if(uiSetData4<10)
- {
- ucDigShow[1]=10;
- }}}
-
- }break;
- }
- }
- void key_scan()//按键扫描函数 放在定时中断里
- {
- if(key_sr1==1)//IO 是高电平,说明按键没有被按下,这时要及时清零一些标志位
- {
- ucKeyLock1=0;//按键自锁标志清零
- uiKeyTimeCnt1=0;//按键去抖动延时计数器清零,此行非常巧妙,是我实战中摸索出来的。
- } else if(ucKeyLock1==0)//有按键按下,且是第一次被按下
- {
- uiKeyTimeCnt1++;//累加定时中断次数
- if(uiKeyTimeCnt1>const_key_time1)
- {
- uiKeyTimeCnt1=0;
- ucKeyLock1=1;//自锁按键置位,避免一直触发
- ucKeySec=1;//触发 1 号键
- }
- }
- if(key_sr2==1)//IO 是高电平,说明按键没有被按下,这时要及时清零一些标志位
- {
- ucKeyLock2=0;//按键自锁标志清零
- uiKeyTimeCnt2=0;//按键去抖动延时计数器清零,此行非常巧妙,是我实战中摸索出来的。
- } else if(ucKeyLock2==0)//有按键按下,且是第一次被按下
- {
- uiKeyTimeCnt2++;//累加定时中断次数
- if(uiKeyTimeCnt2>const_key_time2)
- {
- uiKeyTimeCnt2=0;
- ucKeyLock2=1;//自锁按键置位,避免一直触发
- ucKeySec=2;//触发 2 号键
- }
- }
- if(key_sr3==1)//IO 是高电平,说明按键没有被按下,这时要及时清零一些标志位
- {
- ucKeyLock3=0;//按键自锁标志清零
- uiKeyTimeCnt3=0;//按键去抖动延时计数器清零,此行非常巧妙,是我实战中摸索出来的。
- } else if(ucKeyLock3==0)//有按键按下,且是第一次被按下
- {
- uiKeyTimeCnt3++;//累加定时中断次数
- if(uiKeyTimeCnt3>const_key_time3)
- {
- uiKeyTimeCnt3=0;
- ucKeyLock3=1;//自锁按键置位,避免一直触发
- ucKeySec=3;//触发 3 号键
- }
- }
- }
- void key_service() //按键服务的应用程序
- {
- switch(ucKeySec) //按键服务状态切换
- {
- case 1:// 加按键 对应朱兆祺学习板的 S1 键
- switch(ucWd) //在不同的窗口下,设置不同的参数
- {
- case 1:
- uiSetData1++;
- if(uiSetData1>9999) //最大值是 9999
- {
- uiSetData1=9999;
- }
- ucWd1Update=1;//窗口 1 更新显示
- break;
- case 2:
- uiSetData2++;
- if(uiSetData2>9999) //最大值是 9999
- {
- uiSetData2=9999;
- }
- ucWd2Update=1;//窗口 2 更新显示
- break;
- case 3:
- uiSetData3++;
- if(uiSetData3>9999) //最大值是 9999
- {
- uiSetData3=9999;
- }
- ucWd3Update=1;//窗口 3 更新显示
- break;
- case 4:
- uiSetData4++;
- if(uiSetData4>9999) //最大值是 9999
- {
- uiSetData4=9999;
- }
- ucWd4Update=1;//窗口 4 更新显示
- break;
- }
- uiVoiceCnt=const_voice_short;//按键声音触发,滴一声就停。
- ucKeySec=0;//响应按键服务处理程序后,按键编号清零,避免一致触发
- break;
- case 2:// 减按键 对应朱兆祺学习板的 S5 键
- switch(ucWd) //在不同的窗口下,设置不同的参数
- {
- case 1:
- uiSetData1--;
- if(uiSetData1>9999)
- {
- uiSetData1=0;//最小值是 0
- }
- ucWd1Update=1;//窗口 1 更新显示
- break;
- case 2:
- uiSetData2--;
- if(uiSetData2>9999)
- {
- uiSetData2=0;//最小值是 0
- }
- ucWd2Update=1;//窗口 2 更新显示
- break;
- case 3:
- uiSetData3--;
- if(uiSetData3>9999)
- {
- uiSetData3=0;//最小值是 0
- }
- ucWd3Update=1;//窗口 3 更新显示
- break;
- case 4:
- uiSetData4--;
- if(uiSetData4>9999)
- {
- uiSetData4=0;//最小值是 0
- }
- ucWd4Update=1;//窗口 4 更新显示
- break;
- }
- uiVoiceCnt=const_voice_short;//按键声音触发,滴一声就停
- ucKeySec=0;//响应按键服务处理程序后,按键编号清零,避免一致触发
- break;
- case 3:// 切换窗口按键
- ucWd++;//切换窗口
- if(ucWd>4)
- {
- ucWd=1;
- }
- switch(ucWd) //在不同的窗口下,在不同的窗口下,更新显示不同的窗口
- {
- case 1:
- ucWd1Update=1;//窗口 1 更新显示
-
- break;
- case 2:
- ucWd2Update=1; //窗口 2 更新显示
- break;
- case 3:
- ucWd3Update=1;//窗口 3 更新显示
- break;
- case 4:
- ucWd4Update=1;//窗口 4 更新显示
- break;
- }
- uiVoiceCnt=const_voice_short;//按键声音触发,滴一声就停。
- ucKeySec=0;//响应按键服务处理程序后,按键编号清零,避免一致触发
- break;
- }
- }
- void display_drive() //显示驱动
- {
- static unsigned char i=0;
- switch(i)
- {
- case 0:
- case 1:
- case 2:
- case 3:
- case 4:
- case 5:
- case 6:
- case 7:
- ucDigShowTemp=dig_table[ucDigShow[i]];
- if(ucDigDot[i]==1)
- {
- ucDigShowTemp=ucDigShowTemp|0x80;//显示小数点
- }
- dig_hc595_drive(ucDigShowTemp,dig[i]);
- break;
- }
- i++;
- i=i%8;
- }
- //数码管的 74HC595 驱动函数
- void dig_hc595_drive(unsigned char ucDigStatusTemp16_09,unsigned char ucDigStatusTemp08_01)
- {
- unsigned char i;
- unsigned char ucTempData;
- dig_hc595_sh_dr=0;
- dig_hc595_st_dr=0;
- ucTempData=ucDigStatusTemp16_09;//先送高 8 位
- for (i=0;i<8;i++)
- {
- if(ucTempData>=0x80)dig_hc595_ds_dr=1; else dig_hc595_ds_dr=0;
- dig_hc595_sh_dr=0;//SH 引脚的上升沿把数据送入寄存器
- delay_short(1);
- dig_hc595_sh_dr=1;
- delay_short(1);
- ucTempData=ucTempData<<1;
- }
- ucTempData=ucDigStatusTemp08_01;//再先送低 8 位
- for (i=0;i<8;i++)
- {
- if(ucTempData>=0x80)dig_hc595_ds_dr=1; else dig_hc595_ds_dr=0;
- dig_hc595_sh_dr=0;//SH 引脚的上升沿把数据送入寄存器
- delay_short(1);
- dig_hc595_sh_dr=1;
- delay_short(1);
- ucTempData=ucTempData<<1;
- }
- dig_hc595_st_dr=0;//ST 引脚把两个寄存器的数据更新输出到 74HC595 的输出引脚上并且锁存起来
- delay_short(1);
- dig_hc595_st_dr=1;
- delay_short(1);
- dig_hc595_sh_dr=0;//拉低,抗干扰就增强
- dig_hc595_st_dr=0;
- dig_hc595_ds_dr=0;
- }
-
- void T0_time() interrupt 1
- {
- TF0=0;//清除中断标志
- TR0=0;//关中断
- key_scan();//按键扫描函数
- if(uiVoiceCnt!=0)
- {
- uiVoiceCnt--;//每次进入定时中断都自减 1,直到等于零为止。才停止鸣叫
- beep_dr=0;//蜂鸣器是 PNP 三极管控制,低电平就开始鸣叫
- } else
- {
- beep_dr=1;
- }
- display_drive();//数码管字模的驱动函数
- TH0=0xfe;//重装初始值(65535-500)=65035=0xfe0b
- TL0=0x0b;
- TR0=1;//开中断
- }
- void delay_short(unsigned int uiDelayshort)
- {
- ……………………
- …………限于本文篇幅 余下代码请从51黑下载附件…………
复制代码
所有资料51hei附件下载:
029-74HC595菜单显示高位为零.zip
(435.29 KB, 下载次数: 72)
|