標題:
用單片機+lm331來設計數(shù)字電壓表,為什么proteus中LCD顯示一直不停的兩個值直接跳動?
[打印本頁]
作者:
1250261847
時間:
2022-3-27 11:58
標題:
用單片機+lm331來設計數(shù)字電壓表,為什么proteus中LCD顯示一直不停的兩個值直接跳動?
一直這樣跳動,穩(wěn)定不了一個值。為什么啊發(fā)了程序和仿真
51hei.png
(30.41 KB, 下載次數(shù): 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; //計數(shù)器計滿次數(shù),計滿一次對應的脈沖數(shù)為65536個
unsigned int timecount; //定時器定時1秒的變量,每次對應為50ms,計20次對應就是1秒,然后計算一秒內的計數(shù)器脈沖個數(shù)
bit flag; //計時到1秒時該標志位置1,進行脈沖數(shù)的運算,得出結果送顯示,然后該位清零,重新開始脈沖計數(shù)
unsigned long x; //計算脈沖的數(shù)據(jù)范圍一般比較大,所以用無符號長整形變量定義該變量
uchar code table1[]="FREQ TO VOL TEST"; //初始化顯示字符
uchar code table2[]=" v "; //初始化顯示字符
void delay(uint xms) //延時函數(shù)
{
int a,b;
for(a=xms;a>0;a--)
for(b=110;b>0;b--);
}
void write_com(uchar com) //寫命令函數(shù)
{
lcdrs=0;
P0=com;
delay(1);
lcden=1;
delay(1);
lcden=0;
}
void write_date(uchar date) //寫數(shù)據(jù)函數(shù)
{
lcdrs=1;
P0=date;
delay(1);
lcden=1;
delay(1);
lcden=0;
}
void init_lcd() //初始化函數(shù)
{
uchar i;
lcden=0; //默認開始狀態(tài)為關使能端,見時序圖
write_com(0x0f);
write_com(0x38); //顯示模式設置,默認為0x38,不用變。
write_com(0x01); //顯示清屏,將上次的內容清除,默認為0x01.
write_com(0x0c); //顯示功能設置0x0f為開顯示,顯示光標,光標閃爍;0x0c為開顯示,不顯光標,光標不閃
write_com(0x06); //設置光標狀態(tài)默認0x06,為讀一個字符光標加1.
write_com(0x80); //設置初始化數(shù)據(jù)指針,是在讀指令的操作里進行的
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() //顯示函數(shù)
{
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) //主函數(shù)
{
TMOD=0x15; //定義T1為定時模式,T0位計數(shù)模式
TH0=0;
TL0=0; //計數(shù)器清零
TH1=0x3c;
TL1=0xb0; //定時器賦值(定時50ms)
TR1=1; //打開定時器T1
TR0=1; //打開計數(shù)器T0
ET0=1; //打開中斷允許
ET1=1; //打開中斷允許
EA=1; //打開中斷總開關
init_lcd();
while(1) //進入循環(huán),因為括號內為常數(shù)1,不會變化,所以該表達式一直成立,又稱死循環(huán)
{
f_to_vol();
display(); //調用顯示函數(shù)
if(flag) //判斷1秒時間是否到
{
flag=0; //標志位清零,計算完脈沖數(shù)后重新開始計時計數(shù)
x=T0count*65536+TH0*256+TL0; //讀取1秒時間內的計數(shù)個數(shù)(T0count為每次計數(shù)超過65536時進入計數(shù)中斷加1)
T0count=0; //計數(shù)器中斷次數(shù)清零
TH0=0;
TL0=0; //計數(shù)器清零
TR0=1;
TR1=1; //重新打開定時計數(shù)器
}
}
}
void t0() interrupt 1 //計數(shù)器中斷函數(shù)
{
T0count++; //計數(shù)超過65536,就產(chǎn)生一次中斷
}
void t1() interrupt 3 //定時器中斷函數(shù)
{
TH1=0x3c;
TL1=0xb0; //50ms進入一次中斷,進入中斷后要重新賦初值
timecount++; //每進一次中斷就是50ms,該變量加一
if(timecount==20) //該變量加到20次時,代表1秒到了
{
TR0=0; //關閉計數(shù)器
TR1=0; //關閉定時器
timecount=0; //計時變量清零,準備下次定時
flag=1; //一秒時間到,該標志位置1,主函數(shù)中執(zhí)行脈沖數(shù)運算與顯示函數(shù)
}
}
復制代碼
所有資料51hei附件下載:
仿真程序.7z
(103.65 KB, 下載次數(shù): 14)
2022-3-27 18:10 上傳
點擊文件名下載附件
作者:
人工置頂員
時間:
2022-3-27 18:10
頂一下
作者:
Hephaestus
時間:
2022-3-27 18:49
仿真不要太當真,能工作就行了。到底跳不跳只能用實物。
歡迎光臨 (http://www.torrancerestoration.com/bbs/)
Powered by Discuz! X3.1