標(biāo)題:
解決單片機(jī)按鍵控制數(shù)碼管帶來(lái)閃滅顯示問(wèn)題的項(xiàng)目工程(優(yōu)化版二)
[打印本頁(yè)]
作者:
51黑電子會(huì)員
時(shí)間:
2020-5-21 21:31
標(biāo)題:
解決單片機(jī)按鍵控制數(shù)碼管帶來(lái)閃滅顯示問(wèn)題的項(xiàng)目工程(優(yōu)化版二)
本帖最后由 51黑電子會(huì)員 于 2020-5-23 13:50 編輯
/*****
承接上一個(gè)解決按鍵控制數(shù)碼管帶來(lái)閃滅顯示問(wèn)題的項(xiàng)目工程(優(yōu)化版一)來(lái)
做解決按鍵控制數(shù)碼管帶來(lái)閃滅顯示問(wèn)題的項(xiàng)目工程(優(yōu)化版二)。為何呢?
由于上一個(gè)解決按鍵控制數(shù)碼管帶來(lái)閃滅顯示問(wèn)題的項(xiàng)目工程(優(yōu)化版一)
程序內(nèi)按鍵掃描函數(shù)和數(shù)碼管顯示函數(shù)存在大量的不精準(zhǔn)延時(shí),導(dǎo)致CPU消耗
過(guò)大,拖慢CPU處理指令的速度。如何來(lái)解決呢?請(qǐng)看下面講解。
為什么按下按鍵到按鍵抬起后,會(huì)干擾到數(shù)碼管的顯示?原因:如果按鍵掃描
函數(shù)和數(shù)碼管顯示函數(shù)都放在主函數(shù)的固定循環(huán)內(nèi),當(dāng)按鍵按下后,按鍵掃描
函數(shù)進(jìn)行按鍵掃描,在掃描到按鍵延時(shí)后,CPU被限制在按鍵延時(shí)處進(jìn)行計(jì)時(shí),
卻無(wú)法運(yùn)行其他程序,從而導(dǎo)致數(shù)碼管顯示函數(shù)無(wú)法運(yùn)行,就會(huì)出現(xiàn)數(shù)碼管閃
滅顯示問(wèn)題。人能看到數(shù)碼管閃爍是因?yàn)槿搜勰茏R(shí)別高頻率(人眼看不到閃爍
的頻率為50Hz)低于50Hz,即1/50Hz=0.02秒,因此要想讓人眼看不到數(shù)碼管閃
爍,數(shù)碼管顯示函數(shù)的顯示頻率至少是50Hz,即1/50Hz=0.02秒,也不是越高
好,還要結(jié)合按鍵掃描函數(shù)的按鍵延時(shí)來(lái)取出最恰當(dāng)?shù)娘@示頻率。
除了以上問(wèn)題,解決按鍵控制數(shù)碼管帶來(lái)閃滅顯示問(wèn)題的項(xiàng)目工程(優(yōu)化版一)
還存在程序內(nèi)按鍵掃描函數(shù)和數(shù)碼管顯示函數(shù)存在大量的不精準(zhǔn)延時(shí),導(dǎo)致CPU
消耗過(guò)大,拖慢CPU處理指令的速度。
本程序分兩個(gè)程序。一個(gè)是程序一,按鍵控制數(shù)碼管帶來(lái)閃滅顯示問(wèn)題的程序。
另一個(gè)是程序二,解決按鍵控制數(shù)碼管帶來(lái)閃滅顯示問(wèn)題的項(xiàng)目工程(優(yōu)化版
二)。通過(guò)去掉按鍵控制數(shù)碼管帶來(lái)閃滅顯示問(wèn)題的項(xiàng)目工程(優(yōu)化版一)程
序內(nèi)按鍵掃描函數(shù)和數(shù)碼管顯示函數(shù)存在大量的不精準(zhǔn)延時(shí)。定時(shí)器解決按鍵
消抖原理:編寫(xiě)一個(gè)類(lèi)似普通延時(shí)函數(shù)的定時(shí)器延時(shí)函數(shù),用來(lái)替換掉普通延
時(shí)即可。提醒:先試程序一,再試程序二,之后兩者對(duì)比,找出不同點(diǎn),取最
適合的。
*****/
//程序一:按鍵控制數(shù)碼管帶來(lái)閃滅顯示問(wèn)題的程序
//#include<reg51.h>
//#define uchar unsigned char
//#define uint unsigned int
//sbit add=P3^0;
//sbit dec=P3^4;
//uchar lingweiflag;
//uchar code table[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f} ; //共陰數(shù)碼管段碼數(shù)字0~9字碼表,高電平點(diǎn)亮數(shù)碼管段碼數(shù)字0~9。
//uint num;
//uint qian,bai,shi,ge;//定義拆字變量
// /**ms級(jí)延時(shí)子程序**/
// void delay(uint x)
//{
// uint i,j;
// for(i=0;i<x;i++)
// for(j=0;j<110;j++);
// }
// void display()
//{
// qian=num/1000;//取得千位數(shù)字
// bai=num%1000/100;//取得百位數(shù)字
// shi=num%100/10;//取得十位數(shù)字
// ge=num%10;//取得個(gè)位數(shù)字
//
// P2=0xfe;//數(shù)碼管千位顯示位
// P1=table[qian];//數(shù)碼管千位數(shù)值顯示
// delay(2);//延時(shí)
//
// P2=0xfd;//數(shù)碼管百位顯示位
// P1=table[bai];//數(shù)碼管百位數(shù)值顯示
// delay(2);//延時(shí)
//
// P2=0xfb;//數(shù)碼管十位顯示位
// P1=table[shi];//數(shù)碼管十位數(shù)值顯示
// delay(2);//延時(shí)
//
// P2=0xf7;//數(shù)碼管個(gè)位顯示位
// P1=table[ge];//數(shù)碼管個(gè)位數(shù)值顯示
// delay(2);//延時(shí)
// }
// void keyscan()
//{
// if(add==0)
// {
// delay(5);
// if(add==0)
// {
// num++;
// while(!add);
// lingweiflag=0;
// }
// }
// if(dec==0&&lingweiflag==0)
// {
// delay(5);
// if(dec==0)
// {
// num--;
// while(!dec);
// }
// }
// if(num>9999)
// {
// num=0;
// }
// if(num==0)
// {
// num=0;
// lingweiflag=1;
// }
// }
// void main()
//{
// while(1)
// {
// display();
// keyscan();
// }
// }
//程序二:解決按鍵控制數(shù)碼管帶來(lái)閃滅顯示問(wèn)題的程序
#include<reg51.h>
#define uchar unsigned char
#define uint unsigned int
sbit add=P3^0;
sbit dec=P3^4;
sbit led=P3^5;
sbit led2=P3^6;
uchar count;//定時(shí)器中斷次數(shù)變量
uchar time;//按鍵定時(shí)器延時(shí)變量
uchar lingweiflag;//顯示0標(biāo)志位變量
uchar code weima[]={0xfe,0xfd,0xfb,0xf7};//數(shù)碼管位碼表
uchar code table[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f} ; //共陰數(shù)碼管段碼數(shù)字0~9字碼表,高電平點(diǎn)亮數(shù)碼管段碼數(shù)字0~9。
uint num;//數(shù)值變量
uint qian,bai,shi,ge;//定義拆字變量
// /**ms級(jí)延時(shí)子程序**/
// void delay(uint x)
//{
// uint i,j;
// for(i=0;i<x;i++)
// for(j=0;j<110;j++);
// }
/**定時(shí)器ms級(jí)延時(shí)子程序**/
void time0_delay(uchar time)//注意這里不是普通延時(shí),而是定時(shí)器延時(shí)函數(shù)。
{
count = 0;//需要定時(shí)器延時(shí)count,先清零,再循環(huán)檢測(cè)是否計(jì)到count,是則退出。
while(1)
{
if(count>=time)
{
break;
}
}
}
// void display()
//{
// qian=num/1000;//取得千位數(shù)字
// bai=num%1000/100;//取得百位數(shù)字
// shi=num%100/10;//取得十位數(shù)字
// ge=num%10;//取得個(gè)位數(shù)字
//
// P2=0xfe;//數(shù)碼管千位顯示位
// P1=table[qian];//數(shù)碼管千位數(shù)值顯示
// delay(2);//延時(shí)
//
// P2=0xfd;//數(shù)碼管百位顯示位
// P1=table[bai];//數(shù)碼管百位數(shù)值顯示
// delay(2);//延時(shí)
//
// P2=0xfb;//數(shù)碼管十位顯示位
// P1=table[shi];//數(shù)碼管十位數(shù)值顯示
// delay(2);//延時(shí)
//
// P2=0xf7;//數(shù)碼管個(gè)位顯示位
// P1=table[ge];//數(shù)碼管個(gè)位數(shù)值顯示
// delay(2);//延時(shí)
// }
void display()//顯示程序
{
static uchar i;
P1=0x00;
P2=weima[i];
switch(i)
{
case 0:
P1=table[num/1000];
break;
case 1:
P1=table[num%1000/100];
break;
case 2:
P1=table[num%100/10];
break;
case 3:
P1=table[num%10];
break;
}
i++;
i%=4;
}
void keyscan()
{
// if(add==0)
// {
// delay(5);
// if(add==0)
// {
// num++;
// while(!add);
// lingweiflag=0;
// }
// }
if(add==0)
{
time0_delay(20);//注意這里不是普通延時(shí),而是定時(shí)器延時(shí)函數(shù)。
if(add==0)
{
time0_delay(20);//注意這里不是普通延時(shí),而是定時(shí)器延時(shí)函數(shù)。
while(!add);
num++;
lingweiflag=0;
}
}
// if(dec==0&&lingweiflag==0)
// {
// delay(5);
// if(dec==0)
// {
// num--;
// while(!dec);
// }
// }
if(dec==0&&lingweiflag==0)
{
time0_delay(20);//注意這里不是普通延時(shí),而是定時(shí)器延時(shí)函數(shù)。
if(dec==0)
{
time0_delay(20);//注意這里不是普通延時(shí),而是定時(shí)器延時(shí)函數(shù)。
while(!dec);
num--;
}
}
if(num>9999)
{
num=0;
}
if(num==0)
{
num=0;
lingweiflag=1;
}
}
void Time0_init()
{
TMOD=0x01;
TH0=(65536-2000)/256;//為什么取定時(shí)器中斷時(shí)間為2000微妙,即2毫秒,亦0.002秒,則頻率為1/0.002S=500Hz?由于人眼能看到數(shù)碼管閃爍是源于人眼能識(shí)別高頻率(人眼看不到閃爍的頻率為50Hz)低于50Hz,即1/50Hz=0.02秒,因此要想讓人眼看不到數(shù)碼管閃爍,數(shù)管顯示函數(shù)的顯示頻率至少是50Hz,即1/50Hz=0.02秒,也不是越高越好,還要結(jié)合按鍵掃描函數(shù)的按鍵延時(shí)來(lái)取出最恰當(dāng)?shù)娘@示頻率。
TL0=(65536-2000)%256;
EA=1;
ET0=1;
TR0=1;
}
void time0() interrupt 1
{
TH0=(65536-2000)/256;
TL0=(65536-2000)%256;
count++;
display();
}
void main()
{
Time0_init();
while(1)
{
keyscan();
}
}
復(fù)制代碼
1680900-20200521212951883-1605766455.png
(114.34 KB, 下載次數(shù): 71)
下載附件
2020-5-21 21:31 上傳
歡迎光臨 (http://www.torrancerestoration.com/bbs/)
Powered by Discuz! X3.1