求问大神如何让本程序数码管稳定的显示?
时间:10-02
整理:3721RD
点击:
PS:需要按一下按键加一或者减一,同时要保证数字的稳定显示
#include <reg52.h>
#define uchar unsigned char
#define uint unsigned int
sbit we = P1^1;
sbit du = P1^2;
sbit lcden = P3^4;
uchar num1 = 1, num3=1;
uint num2=1;
uchar leddata[]={
0xC0, //"0"
0xF9, //"1"
0xA4, //"2"
0xB0, //"3"
0x99, //"4"
0x92, //"5"
0x82, //"6"
0xF8, //"7"
0x80, //"8"
0x90, //"9"
};
void delay(uint z);
void KeyScan(); //带返回值的子函数
void show_num_2bit(); //2位数码管显示程序
void show_num_3bit_1(); //第一个3位数码管显示程序
void show_num_3bit_2(); //第二个3位数码管显示程序
void show_num();
/*------------------------------------------------*/
void main()
{
lcden = 0;
TMOD = 0x01;
TH0 = (65536 - 0)/256;
TL0 = (65536 - 0)%256;
EA = 1;
ET0 = 1;
TR0 = 1;
while(1)
{
show_num();
}
}
/*------------------------------------------------*/
void Interrupt_T0()interrupt 1
{
TH0 = (65536 - 0)/256;
TL0 = (65536 - 0)%256;
KeyScan();
}
void delay(uint z)
{
uint x,y;
for(x = z; x > 0; x--)
for(y = 114; y > 0 ; y--);
}
void KeyScan() //带返回值的子函数
{
uchar cord_l,cord_h;//声明列线和行线的值的储存变量
P2 = 0xf8;//1111 0000
if( (P2 & 0xf8) != 0xf8)//判断是否有按键按下
{
delay(5);//软件消抖
if( (P2 & 0xf8) != 0xf8)//判断是否有按键按下
{
cord_l = P2 & 0xf8;// 储存列线值
P2 = cord_l | 0x07;
cord_h = P2 & 0x7;// 储存行线值
switch( cord_l + cord_h )
{
//第一行键值码 控制二位数码管
case 0xf6: if(num1>=0&&num1<=98) num1++; break; //+1
case 0xee: if(num1>=1&&num1<=99) num1--; break; //-1
case 0xde: break;
case 0xbe: break;
case 0x7e: break;
//第二行键值码 控制第一个三位数码管
case 0xf5: if(num2>=1&&num2<=199) num2++; break; //+1
case 0xed: if(num2>=2&&num2<=200) num2--; break; //-1
case 0xdd: break;
case 0xbd: break;
case 0x7d: break;
//第三行键值码 控制第二个三位数码管
case 0xf3: if(num3>=1&&num3<=199) num3++; break; //+1
case 0xeb: if(num3>=2&&num3<=200) num3--; break; //-1
case 0xdb: break;
case 0xbb: break;
case 0x7b: break;
}
}
}
}
void show_num_2bit() //2位数码管显示程序
{
uchar ge, shi;
shi =num1/10;
ge =num1%10;
P0 = 0x01; //十位显示
we = 1;
we = 0;
if(shi==0)
{
P0 = 0xFF;
du=1;
du=0;
delay(2);
}
else if(shi!=0)
{
P0 = leddata[shi];
du=1;
du=0;
delay(2);
}
P0 = 0x02; //个位显示
we = 1;
we = 0;
P0 = leddata[ge];
du=1;
du=0;
delay(2);
}
void show_num_3bit_1() //第一个3位数码管显示程序
{
uchar ge, shi, bai;
bai =num2/100;
shi =num2%100/10;
ge =num2%10;
P0 = 0x04; //百位显示
we = 1;
we = 0;
if(bai==0)
{
P0 = 0xFF;
du=1;
du=0;
delay(2);
}
else if(bai!=0)
{
P0 = leddata[bai];
du=1;
du=0;
delay(2);
}
P0 = 0x08; //十位显示
we = 1;
we = 0;
if(shi==0&&bai==0)
{
P0 = 0xFF;
du=1;
du=0;
delay(2);
}
else if(shi!=0||bai!=0)
{
P0 = leddata[shi];
du=1;
du=0;
delay(2);
}
P0 = 0x10; //个位显示
we = 1;
we = 0;
P0 = leddata[ge];
du=1;
du=0;
delay(2);
}
void show_num_3bit_2() //第二个3位数码管显示程序
{
uchar ge, shi, bai;
bai =num3/100;
shi =num3%100/10;
ge =num3%10;
P0 = 0x20; //百位显示
we = 1;
we = 0;
if(bai==0)
{
P0 = 0xFF;
du=1;
du=0;
delay(2);
}
else if(bai!=0)
{
P0 = leddata[bai];
du=1;
du=0;
delay(2);
}
P0 = 0x40; //十位显示
we = 1;
we = 0;
if(shi==0&&bai==0)
{
P0 = 0xFF;
du=1;
du=0;
delay(2);
}
else if(shi!=0||bai!=0)
{
P0 = leddata[shi];
du=1;
du=0;
delay(2);
}
P0 = 0x80; //个位显示
we = 1;
we = 0;
P0 = leddata[ge];
du=1;
du=0;
delay(2);
}
void show_num()
{
show_num_2bit();
show_num_3bit_1();
show_num_3bit_2();
}
#include <reg52.h>
#define uchar unsigned char
#define uint unsigned int
sbit we = P1^1;
sbit du = P1^2;
sbit lcden = P3^4;
uchar num1 = 1, num3=1;
uint num2=1;
uchar leddata[]={
0xC0, //"0"
0xF9, //"1"
0xA4, //"2"
0xB0, //"3"
0x99, //"4"
0x92, //"5"
0x82, //"6"
0xF8, //"7"
0x80, //"8"
0x90, //"9"
};
void delay(uint z);
void KeyScan(); //带返回值的子函数
void show_num_2bit(); //2位数码管显示程序
void show_num_3bit_1(); //第一个3位数码管显示程序
void show_num_3bit_2(); //第二个3位数码管显示程序
void show_num();
/*------------------------------------------------*/
void main()
{
lcden = 0;
TMOD = 0x01;
TH0 = (65536 - 0)/256;
TL0 = (65536 - 0)%256;
EA = 1;
ET0 = 1;
TR0 = 1;
while(1)
{
show_num();
}
}
/*------------------------------------------------*/
void Interrupt_T0()interrupt 1
{
TH0 = (65536 - 0)/256;
TL0 = (65536 - 0)%256;
KeyScan();
}
void delay(uint z)
{
uint x,y;
for(x = z; x > 0; x--)
for(y = 114; y > 0 ; y--);
}
void KeyScan() //带返回值的子函数
{
uchar cord_l,cord_h;//声明列线和行线的值的储存变量
P2 = 0xf8;//1111 0000
if( (P2 & 0xf8) != 0xf8)//判断是否有按键按下
{
delay(5);//软件消抖
if( (P2 & 0xf8) != 0xf8)//判断是否有按键按下
{
cord_l = P2 & 0xf8;// 储存列线值
P2 = cord_l | 0x07;
cord_h = P2 & 0x7;// 储存行线值
switch( cord_l + cord_h )
{
//第一行键值码 控制二位数码管
case 0xf6: if(num1>=0&&num1<=98) num1++; break; //+1
case 0xee: if(num1>=1&&num1<=99) num1--; break; //-1
case 0xde: break;
case 0xbe: break;
case 0x7e: break;
//第二行键值码 控制第一个三位数码管
case 0xf5: if(num2>=1&&num2<=199) num2++; break; //+1
case 0xed: if(num2>=2&&num2<=200) num2--; break; //-1
case 0xdd: break;
case 0xbd: break;
case 0x7d: break;
//第三行键值码 控制第二个三位数码管
case 0xf3: if(num3>=1&&num3<=199) num3++; break; //+1
case 0xeb: if(num3>=2&&num3<=200) num3--; break; //-1
case 0xdb: break;
case 0xbb: break;
case 0x7b: break;
}
}
}
}
void show_num_2bit() //2位数码管显示程序
{
uchar ge, shi;
shi =num1/10;
ge =num1%10;
P0 = 0x01; //十位显示
we = 1;
we = 0;
if(shi==0)
{
P0 = 0xFF;
du=1;
du=0;
delay(2);
}
else if(shi!=0)
{
P0 = leddata[shi];
du=1;
du=0;
delay(2);
}
P0 = 0x02; //个位显示
we = 1;
we = 0;
P0 = leddata[ge];
du=1;
du=0;
delay(2);
}
void show_num_3bit_1() //第一个3位数码管显示程序
{
uchar ge, shi, bai;
bai =num2/100;
shi =num2%100/10;
ge =num2%10;
P0 = 0x04; //百位显示
we = 1;
we = 0;
if(bai==0)
{
P0 = 0xFF;
du=1;
du=0;
delay(2);
}
else if(bai!=0)
{
P0 = leddata[bai];
du=1;
du=0;
delay(2);
}
P0 = 0x08; //十位显示
we = 1;
we = 0;
if(shi==0&&bai==0)
{
P0 = 0xFF;
du=1;
du=0;
delay(2);
}
else if(shi!=0||bai!=0)
{
P0 = leddata[shi];
du=1;
du=0;
delay(2);
}
P0 = 0x10; //个位显示
we = 1;
we = 0;
P0 = leddata[ge];
du=1;
du=0;
delay(2);
}
void show_num_3bit_2() //第二个3位数码管显示程序
{
uchar ge, shi, bai;
bai =num3/100;
shi =num3%100/10;
ge =num3%10;
P0 = 0x20; //百位显示
we = 1;
we = 0;
if(bai==0)
{
P0 = 0xFF;
du=1;
du=0;
delay(2);
}
else if(bai!=0)
{
P0 = leddata[bai];
du=1;
du=0;
delay(2);
}
P0 = 0x40; //十位显示
we = 1;
we = 0;
if(shi==0&&bai==0)
{
P0 = 0xFF;
du=1;
du=0;
delay(2);
}
else if(shi!=0||bai!=0)
{
P0 = leddata[shi];
du=1;
du=0;
delay(2);
}
P0 = 0x80; //个位显示
we = 1;
we = 0;
P0 = leddata[ge];
du=1;
du=0;
delay(2);
}
void show_num()
{
show_num_2bit();
show_num_3bit_1();
show_num_3bit_2();
}
现在的问题是,数码管可以稳定显示,但是按一下按键数字会增加好多而不是一个。
软件消抖动的值设大一点试试!
delay(5);//软件消抖
希望对你有帮助!
应该是程序框架有问题。这么能把含有延时消抖的键扫描程序放在中断里呢?如果有必要把键扫描程序放在中断里,建议采用中断记数消抖,并且只把获取键值部分留下,键值服务部分放到主循环中处理。定时器中断时间1ms足以。
这个最好改成单次脉冲上调的方式
你的中断服务程序有问题,不知道你想多长时间产生一次中断?
TH0 = (65536 - 0)/256; TH0 = 256 2进制= 1 0000 0000
TL0 = (65536 - 0)%256; TL0 = 256 2进制= 1 0000 0000
8位寄存器能装下9位数吗?就算TH0 = TL0 = 0xFF,假如是12M晶振,1秒要进入中断1000000次,你的中断服务程序还有按键扫描程序,其中还包含5ms的延时,这个中断服务程序能正常工作吗?
所有延时都为定时器延时方式实现