标题:
用单片机+lm331来设计数字电压表,为什么proteus中LCD显示一直不停的两个值直接跳动?
[打印本页]
作者:
1250261847
时间:
2022-3-27 11:58
标题:
用单片机+lm331来设计数字电压表,为什么proteus中LCD显示一直不停的两个值直接跳动?
一直这样跳动,稳定不了一个值。为什么啊发了程序和仿真
51hei.png
(30.41 KB, 下载次数: 31)
下载附件
2022-3-27 18:08 上传
单片机源程序如下:
#include <reg52.h>
#define uchar unsigned char
#define uint unsigned int
sbit lcdrs=P2^0; //液晶控制引脚
sbit lcden=P2^1;
unsigned long v = 0;
unsigned int T0count; //计数器计满次数,计满一次对应的脉冲数为65536个
unsigned int timecount; //定时器定时1秒的变量,每次对应为50ms,计20次对应就是1秒,然后计算一秒内的计数器脉冲个数
bit flag; //计时到1秒时该标志位置1,进行脉冲数的运算,得出结果送显示,然后该位清零,重新开始脉冲计数
unsigned long x; //计算脉冲的数据范围一般比较大,所以用无符号长整形变量定义该变量
uchar code table1[]="FREQ TO VOL TEST"; //初始化显示字符
uchar code table2[]=" v "; //初始化显示字符
void delay(uint xms) //延时函数
{
int a,b;
for(a=xms;a>0;a--)
for(b=110;b>0;b--);
}
void write_com(uchar com) //写命令函数
{
lcdrs=0;
P0=com;
delay(1);
lcden=1;
delay(1);
lcden=0;
}
void write_date(uchar date) //写数据函数
{
lcdrs=1;
P0=date;
delay(1);
lcden=1;
delay(1);
lcden=0;
}
void init_lcd() //初始化函数
{
uchar i;
lcden=0; //默认开始状态为关使能端,见时序图
write_com(0x0f);
write_com(0x38); //显示模式设置,默认为0x38,不用变。
write_com(0x01); //显示清屏,将上次的内容清除,默认为0x01.
write_com(0x0c); //显示功能设置0x0f为开显示,显示光标,光标闪烁;0x0c为开显示,不显光标,光标不闪
write_com(0x06); //设置光标状态默认0x06,为读一个字符光标加1.
write_com(0x80); //设置初始化数据指针,是在读指令的操作里进行的
for(i=0;i<16;i++) //显示初始化
{
write_date(table1[i]); //显示第一行字符
}
write_com(0x80+0x40); //选择第二行
for(i=0;i<16;i++)
{
write_date(table2[i]); //显示第二行字符
}
}
void f_to_vol()
{
unsigned long Rt,RL,Rs;
float Ct;
Ct=4.7;
Rt=10;
RL=360;
Rs=36;
v=(2.09*Ct*Rt*RL*x)/Rs;
}
void display() //显示函数
{
write_com(0x80+0x40+8);
write_date(v/1000%10+0x30);
write_date('.');
write_date(v/100%10+0x30);
write_date((v/10%10)+0x30);
write_date((v%10)+0x30);
}
void main(void) //主函数
{
TMOD=0x15; //定义T1为定时模式,T0位计数模式
TH0=0;
TL0=0; //计数器清零
TH1=0x3c;
TL1=0xb0; //定时器赋值(定时50ms)
TR1=1; //打开定时器T1
TR0=1; //打开计数器T0
ET0=1; //打开中断允许
ET1=1; //打开中断允许
EA=1; //打开中断总开关
init_lcd();
while(1) //进入循环,因为括号内为常数1,不会变化,所以该表达式一直成立,又称死循环
{
f_to_vol();
display(); //调用显示函数
if(flag) //判断1秒时间是否到
{
flag=0; //标志位清零,计算完脉冲数后重新开始计时计数
x=T0count*65536+TH0*256+TL0; //读取1秒时间内的计数个数(T0count为每次计数超过65536时进入计数中断加1)
T0count=0; //计数器中断次数清零
TH0=0;
TL0=0; //计数器清零
TR0=1;
TR1=1; //重新打开定时计数器
}
}
}
void t0() interrupt 1 //计数器中断函数
{
T0count++; //计数超过65536,就产生一次中断
}
void t1() interrupt 3 //定时器中断函数
{
TH1=0x3c;
TL1=0xb0; //50ms进入一次中断,进入中断后要重新赋初值
timecount++; //每进一次中断就是50ms,该变量加一
if(timecount==20) //该变量加到20次时,代表1秒到了
{
TR0=0; //关闭计数器
TR1=0; //关闭定时器
timecount=0; //计时变量清零,准备下次定时
flag=1; //一秒时间到,该标志位置1,主函数中执行脉冲数运算与显示函数
}
}
复制代码
所有资料51hei附件下载:
仿真程序.7z
(103.65 KB, 下载次数: 14)
2022-3-27 18:10 上传
点击文件名下载附件
作者:
人工置顶员
时间:
2022-3-27 18:10
顶一下
作者:
Hephaestus
时间:
2022-3-27 18:49
仿真不要太当真,能工作就行了。到底跳不跳只能用实物。
欢迎光临 (http://www.51hei.com/bbs/)
Powered by Discuz! X3.1