|
求助大神,小弟找了一段源程序,但是有點問題,求助大神幫忙。
源程序:
#include<reg52.h>
#define uchar unsigned char
/****************************************************************
引腳定義:
P20=SW1 時鐘設(shè)置時更改“時”,直徑設(shè)置時更改十位
P21=SW2 時鐘設(shè)置時更改“分”的十位,直徑設(shè)置時更改個位
P22=SW3 時鐘設(shè)置時更改“分”的個位
P23=Enter 確認(rèn)更改設(shè)置
P32=Disp 正常工作時更改顯示模式
****************************************************************************/
sbit P10=P1^0; //獨立鍵盤端口
sbit P11=P1^1;
sbit P12=P1^2;
sbit P13=P1^3;
sbit P33=P3^3; //改變顯示內(nèi)容鍵
sbit RS=P3^7; //LCDRS腳
sbit RW=P3^6; //LCDRW腳
sbit E=P3^4; //LCDE腳
sbit busy=P0^7;
sbit P35=P3^5; //霍爾口
/****************************************************************
變量定義:
i 延時變量
qsls 圈數(shù)臨時變量,用于判斷里程顯示選用m還是km作為單位
qs 圈數(shù)
sj 累計行駛時間,單位為秒
lc 累計里程
pjsd 平均速度
ssji 定時器T1 20ms中斷次數(shù),用于計算速度等
sji 本次速度對應(yīng)的20ms中斷次數(shù)
sjiold 上次速度對應(yīng)的20ms中斷次數(shù)
sd2 當(dāng)前速度
tc 輪胎周長
*s 字符串顯示子程序字符指針
line 字符串顯示子程序列數(shù)
row 字符串顯示子程序行數(shù)
com 寫控制字
dat 顯示碼字
gw 累計里程、當(dāng)前速度、累計時間、平均速度的個位
sw 累計里程、當(dāng)前速度、累計時間、平均速度的十位
bw 累計里程、當(dāng)前速度、累計時間、平均速度的百位
qw 累計里程、當(dāng)前速度、累計時間、平均速度的千位
ww 累計里程、累計時間的萬位
sww 累計里程、累計時間的十萬位
ssj 定時器T0 50ms中斷次數(shù),每20次sj加1
cgw 當(dāng)前時間(時鐘)的個位
csw 當(dāng)前時間(時鐘)的十位
cbw 當(dāng)前時間(時鐘)的百位
cqw 當(dāng)前時間(時鐘)的千位
cww 當(dāng)前時間(時鐘)的萬位
csww 當(dāng)前時間(時鐘)的十萬位
cww2 當(dāng)前時間(時鐘)的輔助萬位
MODE 顯示模式
tr1 輪胎設(shè)置變量1(十位)
tr2 輪胎設(shè)置變量2(個位)
****************************************************************************/
unsigned int i,qsls;
unsigned long qs,sj,lc,pjsd,ssji,sji,sjiold,sd2,tc;
uchar *s,line,row,com,dat,gw,sw,bw,qw,ww,sww,ssj,cgw,csw,cbw,cqw,cww,csww,cww2,MODE,tr1,tr2;
/***********************************void wait()*****************************
該函數(shù)的作用是對LCD進行檢測,看LCD是否處于忙的狀態(tài).當(dāng)bflag=1時表示忙,
此時不可以向LCD進行讀寫操作.而當(dāng)busy=0時,表示可以向它讀寫數(shù)據(jù).
****************************************************************************/
void wait()
{P0=0xff;
RW=1; RS=0;
do{E=0;E=1;}while(busy==1);
}
/**************************************void dispone()*******************************
該函數(shù)的作用是向LCD寫入數(shù)據(jù)并顯示出來.
***********************************************************************************/
void dispone(dat)
{P0=dat;
RW=0; RS=1;
E=0; E=1;
wait();
}
/**********************************void wrcom()*******************************
該函數(shù)的作用是向LCD寫入控制字.
******************************************************************************/
void wrcom(com)
{P0=com;
RW=0; RS=0;
E=0; E=1;
wait();
}
/***************************************void init_LCD()*******************************
該函數(shù)的作用是初始化LCD.
*****************************************************************************************/
void init_LCD()
{wrcom(0x01);
wrcom(0x06);
wrcom(0x38);
wrcom(0x0c);
}
/****************************************void dispmore()********************************
該函數(shù)的作用是向LCD寫入一串?dāng)?shù)據(jù),并把數(shù)據(jù)串顯示出來.
******************************************************************************************/
void dispmore(line,row,uchar dat[],i) //格式為dispmore(第幾行,第幾列,開始要顯示的字符地址,顯示幾個字符);
{uchar com;
s=dat;
if(line==1)
{com=0x80+row-1;
wrcom(com);
while((i--)!=0&&com<=0x8f)
{dispone(*s);
com++;
s++;
}
}
else
{com=0xc0+row-1;
wrcom(com);
while((i--)!=0&&com<=0xcf)
{dispone(*s);
com++;
s++;
}
}
}
/****************************************void ttimep()********************************
累計行駛時間數(shù)據(jù)處理及顯示子程序
******************************************************************************************/
void ttimep()
{
sww=sj/36000;
ww=sj%36000/3600;
qw=sj%3600/600;
bw=sj%600/60;
sw=sj%60/10;
gw=sj%10;
wrcom(0xc1);
dispone('T');
dispone('i');
dispone('m');
dispone('e');
dispone(' ');
dispone(' ');
dispone(sww+0x30);
dispone(ww+0x30);
dispone(':');
dispone(qw+0x30);
dispone(bw+0x30);
dispone(':');
dispone(sw+0x30);
dispone(gw+0x30);
}
/****************************************void timer1()********************************
T1中斷服務(wù)子程序,每20ms中斷一次,ssji加1,根據(jù)公式S=tc*qs和V=tc/ssj計算累計里程和
******************************************************************************************/
void timer1() interrupt 3
{
ssji++;
TH1=0xb1;
TL1=0xdf;
}
/****************************************void lcp()********************************
累計里程數(shù)據(jù)處理和顯示子程序,若<999m則單位為m,若>999m則單位為km
******************************************************************************************/
void lcp()
{
qsls=100000/tc;
if(qs>qsls){
sww=qs*tc/10000000;
ww=qs*tc%10000000/1000000;
qw=qs*tc%1000000/100000;
bw=qs*tc%10000000/10000;
sw=qs*tc%10000/1000;
wrcom(0x81);
dispone('S');
dispone(' ');
dispone(' ');
dispone(' ');
dispone(' ');
dispone(sww+0x30);
dispone(ww+0x30);
dispone(qw+0x30);
dispone('.');
dispone(bw+0x30);
dispone(sw+0x30);
dispone(' ');
dispone('k');
dispone('m');
}
else{
qw=qs*tc%100000/10000;
bw=qs*tc%10000/1000;
sw=qs*tc%1000/100;
gw=qs*tc%100/10;
wrcom(0x81);
dispone('S');
dispone(' ');
dispone(' ');
dispone(' ');
dispone(' ');
dispone(' ');
dispone(' ');
dispone(qw+0x30);
dispone(bw+0x30);
dispone(sw+0x30);
dispone('.');
dispone(gw+0x30);
dispone(' ');
dispone('m');
}
}
/****************************************void pjsdp()********************************
平均速度數(shù)據(jù)處理及顯示子程序
******************************************************************************************/
void pjsdp()
{
pjsd=qs*tc*36/sj;
qw=pjsd%100000/10000;
bw=pjsd%10000/1000;
sw=pjsd%1000/100;
gw=pjsd%100/10;
wrcom(0x82);
dispone('V');
dispone('a');
dispone(' ');
dispone(' ');
dispone(qw+0x30);
dispone(bw+0x30);
dispone('.');
dispone(sw+0x30);
dispone(gw+0x30);
dispone(' ');
dispone('k');
dispone('m');
dispone('/');
dispone('h');
}
/****************************************void sdp()********************************
當(dāng)前速度數(shù)據(jù)處理及顯示子程序
******************************************************************************************/
void sdp()
{
if(sji!=0)
sd2=tc*1800/sji;
else sd2=0;
qw=sd2%100000/10000;
bw=sd2%10000/1000;
sw=sd2%1000/100;
gw=sd2%100/10;
wrcom(0x82);
dispone('V');
dispone(' ');
dispone(' ');
dispone(' ');
dispone(qw+0x30);
dispone(bw+0x30);
dispone('.');
dispone(sw+0x30);
dispone(gw+0x30);
dispone(' ');
dispone('k');
dispone('m');
dispone('/');
dispone('h');
}
/****************************************void clkp()********************************
當(dāng)前時間(時鐘)數(shù)據(jù)處理及顯示子程序
******************************************************************************************/
void clkp()
{
wrcom(0xc4);
dispone(csww+0x30);
dispone(cww+0x30);
dispone(':');
dispone(cqw+0x30);
dispone(cbw+0x30);
dispone(':');
dispone(csw+0x30);
dispone(cgw+0x30);
}
/****************************************void int0()********************************
外部中斷0(霍爾)中斷服務(wù)程序
*****************************************************************************************/
void int0() interrupt 0
{
EX0=0;
qs++; //圈數(shù)+1
TR1=0;
sjiold=sji; //停止T1計時
sji=ssji;
TH1=0xb1; //重置T1定時常數(shù)
TL1=0xdf;
ssji=0;
TR1=1; //T1重新開始計時
switch(MODE)
{
case 0:wrcom(0x01);lcp();ttimep();break;
case 1:wrcom(0x01);sdp();pjsdp();break;
case 2:wrcom(0x01);dispmore(1,5,"Time Now",8);clkp();break;
default:break;
}
for(i=0;i<32000;i++);
IE0=0;
EX0=1;
}
/****************************************void int1()********************************
顯示模式選擇按鈕(Disp)中斷服務(wù)子程序
******************************************************************************************/
void int1() interrupt 2
{
EX1=0;
if(++MODE>3) MODE=0;
switch(MODE)
{
case 0:wrcom(0x01);lcp();ttimep();break;
case 1:wrcom(0x01);sdp();pjsdp();break;
case 2:wrcom(0x01);dispmore(1,5,"Time Now",8);clkp();break;
default:break;
}
for(i=0;i<32000;i++);
IE1=0;
EX1=1;
}
/****************************************vvoid timer0()********************************
T0中斷服務(wù)子程序,主要用于計算累計行駛時間,50ms一次中斷,每20次sj++,更新累計行駛時間(單位秒)
*******************************************************************************************/
void timer0() interrupt 1
{
TH0=0x3c;
TL0=0xb0;
if(++ssj>19)
{
sj++;
ssj=0;
cgw++;
if(cgw>9){cgw=0;csw++;
if(csw>5){csw=0;++cbw;
if(cbw>9){cbw=0;++cqw;
if(cqw>5){cqw=0;
cww2++;if(cww2>23)cww2=0;csww=cww2/10;cww=cww2%10;
}
}
}
}
if (MODE==0) {lcp();ttimep();}
if (MODE==2) clkp();
}
}
/****************************************void main()********************************
主程序,初始化LCD,顯示歡迎信息,更改時鐘、直徑設(shè)置,開中斷、計時器等
******************************************************************************************/
void main()
{
init_LCD();
dispmore(1,1,"-Digital Meter-",16);
for(i=0;i<25000;i++);
dispmore(2,1," Welcome ",16);
for(i=0;i<25000;i++);
dispmore(2,1," Welcome. ",16);
for(i=0;i<25000;i++);
dispmore(2,1," Welcome.. ",16);
for(i=0;i<25000;i++);
dispmore(2,1," Welcome... ",16);
for(i=0;i<25000;i++);
dispmore(2,1," Welcome.... ",16);
for(i=0;i<25000;i++);
dispmore(2,1," Welcome..... ",16);
for(i=0;i<30000;i++);
wrcom(0x01);
MODE=0;
qs=0;
P1=0xff; //鍵盤口
cgw=csw=cbw=cqw=cww=csww=cww2=0;
wrcom(0x01);
dispmore(1,5,"Set Time",8);
clkp();
while(1){
if(P13==0){for(i=0;i<4000;i++);if(P13==0)break;}
if(P10==0){for(i=0;i<4000;i++);if(P10==0){cww2++;if(cww2>23)cww2=0;csww=cww2/10;cww=cww2%10;clkp();for(i=0;i<32000;i++);}}
if(P11==0){for(i=0;i<4000;i++);if(P11==0){if(++cqw>5)cqw=0;clkp();for(i=0;i<32000;i++);}}
if(P12==0){for(i=0;i<4000;i++);if(P12==0){if(++cbw>9)cbw=0;clkp();for(i=0;i<32000;i++);}}
}
for(i=0;i<30000;i++);
tr1=5;
tr2=5;
wrcom(0x01);
dispmore(1,1,"Set Bike Tire L=",16);
wrcom(0xc9);
dispone('c');
wrcom(0xca);
dispone('m');
P1=0xff;
wrcom(0xc6);dispone(tr1+0x30);
wrcom(0xc7);dispone(tr2+0x30);
while(1){
if(P10==0){for(i=0;i<4000;i++);if(P10==0){if(++tr1>9)tr1=0;wrcom(0xc6);dispone(tr1+0x30);for(i=0;i<32000;i++);}}
if(P11==0){for(i=0;i<4000;i++);if(P11==0){if(++tr2>9)tr2=0;wrcom(0xc7);dispone(tr2+0x30);for(i=0;i<32000;i++);}}
if(P13==0){for(i=0;i<4000;i++);if(P13==0)break;}
}
tc=3.14*(10*tr1+tr2);
TMOD=0x11; //T0和T1均是定時器方式
TH0=0x3c; //置定時常數(shù)
TL0=0xb0;
TH1=0xb1;
TL1=0xdf;
IT0=1; //外部中斷觸發(fā)方式均是邊緣觸發(fā)
IT1=1;
IE=0x9f; //開中斷
IP=0x02;
TR0=1; //T0和T1開始計時
TR1=1;
P35=1; //霍爾口
IE0=0;
wrcom(0x01);
for (;;);
}
編譯結(jié)果:
Build target 'Target 1'
compiling 總程序.c...
linking...
*** WARNING L15: MULTIPLE CALL TO SEGMENT
SEGMENT: ?PR?_DISPMORE?譥程序
CALLER1: ?PR?INT0?譥程序
CALLER2: ?PR?INT1?譥程序
*** WARNING L15: MULTIPLE CALL TO SEGMENT
SEGMENT: ?PR?_DISPMORE?譥程序
CALLER1: ?PR?INT1?譥程序
CALLER2: ?C_C51STARTUP
Program Size: data=103.0 xdata=0 code=4190
creating hex file from "總程序"...
"總程序" - 0 Error(s), 2 Warning(s).
求解救
|
|