单片机小白用的ben方法,请大佬多多指教!
数码管间不能同时进行赋值显示,要用到扫描刷新。
每个数码管显示字符后留影一段时间, while(1)扫描可以让数码管一直刷新显示,让人的眼睛误以为数码管是同时显示的,实际上每个数码管是一亮一灭的,合适的刷新时间可以欺骗人的眼睛。
因程序总是从主函数开始自上而下串行的,数码管刷新时间与间隔一秒再自增冲突(3根数码管显示不同步),所以将数码管刷新函数加至定时器延迟函数中。
独立按键一:按下数码管显示数值增加(>999变000)
独立按键二:按下数码管显示数值减少(<000变999)
独立按键三:按下数码管显示数值清零及退出0-999的自增
独立按键四:按下数码管显示0-999的自增,间隔1秒
程序中函数的调用有点多,所以精度可能会有些许偏差。
代码部分:
#include <reg52.h>
sbit button1=P3^1;
sbit button2=P3^0;
sbit button3=P3^2;
sbit button4=P3^3; //按钮进行位定义
sbit add_1=P2^2;
sbit add_2=P2^3;
sbit add_3=P2^4; //将3个控制选中数码管的引脚进行位定义
/*这3个引脚(可赋值0/1)经74LS138译码后可得到8个结果(2^3=8),分别对应八个数码管*/
char x,y,n; //x,y,n要进行进制转换所以不能用unsigned char
unsigned char code a[10]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};
//数码管显示0-9的字符数组
//有参定时器延时函数 1.25ms*参数=总延时时间
void delay_ds(unsigned char ms)
{
unsigned char T=0;
TMOD=0x01; //定时器方式一 16位定时器计数器 容器最大数2^16=65536
TH0=0xfb; //初值的高位
TL0=0x80; //初值的低位
TR0=1; //定时器启动
while(T<ms)
{
if(TF0==1) //溢出标志位,溢出时硬件自动赋1,不能软件赋值
{
TF0=0; //溢出后重新赋值为0后定时器可以重新计数
TH0=0xfb;
TL0=0x80; // 初值fb80换算成十进制为64384 每次加1直到大于65536后溢出需要1.25ms
T++; //while循环里面语句循环ms次(ms为参数)
}
}
}//1.25*ms
// 三根数码管刷新
void shuaxin()
{
add_1=0;
add_2=1;
add_3=0; //选中第三根数码管
P0=a[y];
delay_ds(3); //留影时间3.75ms
P0=0x00; //消影
add_1=1;
add_2=0;
add_3=0; //选中第二根数码管
P0=a[x];
delay_ds(3);
P0=0x00;
add_1=0;
add_2=0;
add_3=0; //选中第一根数码管
P0=a[n];
delay_ds(3);
P0=0x00;
} /*
数码管的留影时间为调用一次delay_ds(ms)函数的延时时间
调用了3次delay_ds(ms)函数,总的刷新一次需要3*3*1.25=11.25ms
*/
//无参定时器延时带刷新函数 一秒
void Ding_shi01()
{
unsigned char T=0;
TMOD=0x01; //定时器方式一 容器最大数65536
TH0=0xfb;
TL0=0x80; //1.25ms
shuaxin(); //11.25ms 12.5ms
TR0=1;
while(T<79)
{
if(TF0==1)
{
TF0=0;
TH0=0xfb;
TL0=0x80; // 初值fb80换算成十进制为64384 每次加1直到大于65536后溢出需要1.25ms
shuaxin(); //11.25ms 12.5ms*79=987.5ms
T++;
}
}
}
//十进制加
void jia()
{
if(n>9)
{
x++;
n=0;
if(x>9)
{
x=0;
y++;
if(y>9)
y=0;
}
}
}
//十进制减
void jian()
{
if(n<0)
{
x--;
n=9;
if(x<0)
{
x=9;
y--;
if(y<0)
y=9;
}
}
}
void main()
{
button1=0xff;
button2=0xff;
button3=0xff;
button4=0xff;//初始按键要赋1
y=x=n=0;/*y为控制右边第三根数码管字符的变量
x为控制右边第二根数码管字符的变量
n为控制右边第一根数码管字符的变量
将y,x,n都赋值为0*/
while(1)
{
shuaxin(); //因y,x,n初值为0,如不进行以下其他操作,3根都会一直显示000
//按下数码管显示数值增加
if(button1==0) //按键按下确定
{
delay_ds(2); //按键消抖
if(button1==0)//按键按下再次确定
{
while(!button1)//当一直按键按下将会一直运行以下代码,即n一直自增直到松下按键
{
shuaxin();//按下按键数值增加的延迟时间带刷新
n++;
jia();
}
}
}
//按下数码管显示数值减少
if(button2==0)
{
delay_ds(2);
if(button2==0)
{
while(!button2)
{
shuaxin();
n--;
jian();
}
}
}
//按下数码管显示数值清零及退出0-999的自增
if(button3==0)
{
delay_ds(2);
if(button3==0)
{
while(!button3)
{
while(1)
{
x=y=n=0;//将下x,y,n赋值为0
shuaxin();
if(button1==0||button2==0||button4==0)
break; //按下其他键跳出while循环,即可进行其他操作
}
}
}
}
//按下从0自增至999,间隔1秒
if(button4==0)
{
delay_ds(2);
if(button4==0)
{
while(!button4)
{
for(y=0;y<10;y++)
{
if(button3==0)
break; //按下第三颗按键可跳出for循环,即退出从0自增至999
for(x=0;x<10;x++)
{
if(button3==0)
break;
for(n=0;n<10;n++)
{
if(button3==0)
break;
Ding_shi01(); //定时器延迟带刷新函数 1秒
}
}
}
y=x=n=0; //从0自增至999后数码管显示000
}
}
}
}
}