找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 3899|回复: 6
收起左侧

单片机做的自行车里程表,求助,求助。

[复制链接]
ID:115422 发表于 2016-4-20 12:31 | 显示全部楼层 |阅读模式
求助大神,小弟找了一段源程序,但是有点问题,求助大神帮忙。
源程序:
#include<reg52.h>
#define         uchar unsigned char

/****************************************************************
引脚定义:
P20=SW1   时钟设置时更改“时”,直径设置时更改十位
P21=SW2           时钟设置时更改“分”的十位,直径设置时更改个位
P22=SW3    时钟设置时更改“分”的个位
P23=Enter 确认更改设置
P32=Disp  正常工作时更改显示模式
****************************************************************************/
sbit P10=P1^0;        //独立键盘端口
sbit P11=P1^1;
sbit P12=P1^2;
sbit P13=P1^3;
sbit P33=P3^3;        //改变显示内容键
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      圈数临时变量,用于判断里程显示选用m还是km作为单位
qs     圈数
sj     累计行驶时间,单位为秒
lc              累计里程
pjsd    平均速度
ssji    定时器T1 20ms中断次数,用于计算速度等
sji             本次速度对应的20ms中断次数
sjiold          上次速度对应的20ms中断次数
sd2            当前速度
tc            轮胎周长

*s                  字符串显示子程序字符指针
line          字符串显示子程序列数
row                  字符串显示子程序行数
com                  写控制字
dat                  显示码字
gw                  累计里程、当前速度、累计时间、平均速度的个位
sw                  累计里程、当前速度、累计时间、平均速度的十位
bw                  累计里程、当前速度、累计时间、平均速度的百位
qw                  累计里程、当前速度、累计时间、平均速度的千位
ww                  累计里程、累计时间的万位
sww                  累计里程、累计时间的十万位
ssj    定时器T0 50ms中断次数,每20次sj加1
cgw                  当前时间(时钟)的个位
csw                  当前时间(时钟)的十位
cbw                  当前时间(时钟)的百位
cqw                  当前时间(时钟)的千位
cww                  当前时间(时钟)的万位
csww          当前时间(时钟)的十万位
cww2          当前时间(时钟)的辅助万位
MODE          显示模式
tr1                  轮胎设置变量1(十位)
tr2                  轮胎设置变量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()*****************************
    该函数的作用是对LCD进行检测,看LCD是否处于忙的状态.当bflag=1时表示忙,
此时不可以向LCD进行读写操作.而当busy=0时,表示可以向它读写数据.
****************************************************************************/
void wait()
{P0=0xff;
RW=1; RS=0;                  
do{E=0;E=1;}while(busy==1);
}

/**************************************void dispone()*******************************
    该函数的作用是向LCD写入数据并显示出来.
***********************************************************************************/
void dispone(dat)
{P0=dat;
RW=0; RS=1;                 
E=0; E=1;                    
wait();
}

/**********************************void wrcom()*******************************
      该函数的作用是向LCD写入控制字.
******************************************************************************/
void wrcom(com)
{P0=com;
RW=0; RS=0;                  
E=0; E=1;   
wait();
}

/***************************************void init_LCD()*******************************
     该函数的作用是初始化LCD.
*****************************************************************************************/
void init_LCD()
{wrcom(0x01);        
wrcom(0x06);        
wrcom(0x38);        
wrcom(0x0c);      
}

/****************************************void dispmore()********************************
    该函数的作用是向LCD写入一串数据,并把数据串显示出来.
******************************************************************************************/
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()********************************
累计行驶时间数据处理及显示子程序
******************************************************************************************/
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中断服务子程序,每20ms中断一次,ssji加1,根据公式S=tc*qs和V=tc/ssj计算累计里程和
******************************************************************************************/
void timer1() interrupt 3       
{                                                               
ssji++;
TH1=0xb1;
TL1=0xdf;
}

/****************************************void lcp()********************************
累计里程数据处理和显示子程序,若<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()********************************
平均速度数据处理及显示子程序
******************************************************************************************/
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()********************************
当前速度数据处理及显示子程序
******************************************************************************************/
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()********************************
当前时间(时钟)数据处理及显示子程序
******************************************************************************************/
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(霍尔)中断服务程序
*****************************************************************************************/
void int0() interrupt 0                       
{
EX0=0;                               
qs++;                                                        //圈数+1
TR1=0;
sjiold=sji;                                            //停止T1计时
sji=ssji;                       
TH1=0xb1;                                                //重置T1定时常数
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)中断服务子程序
******************************************************************************************/
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中断服务子程序,主要用于计算累计行驶时间,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,显示欢迎信息,更改时钟、直径设置,开中断、计时器等
******************************************************************************************/
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;                                           //置定时常数
TL0=0xb0;
TH1=0xb1;
TL1=0xdf;
IT0=1;                                                   //外部中断触发方式均是边缘触发
IT1=1;
IE=0x9f;                                           //开中断
IP=0x02;
TR0=1;                                                   //T0和T1开始计时
TR1=1;
P35=1;                                                   //霍尔口
IE0=0;
wrcom(0x01);
for (;;);

}

编译结果:
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).


求解救
回复

使用道具 举报

ID:115422 发表于 2016-4-20 12:32 | 显示全部楼层
顶·~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
回复

使用道具 举报

ID:1 发表于 2016-4-20 18:15 | 显示全部楼层
"总程序" - 0 Error(s), 2 Warning(s).
0个错误 程序是没有问题的  2个警告可以忽略.
回复

使用道具 举报

ID:115422 发表于 2016-4-20 23:27 | 显示全部楼层
admin 发表于 2016-4-20 18:15
"总程序" - 0 Error(s), 2 Warning(s).
0个错误 程序是没有问题的  2个警告可以忽略.

谢谢~但我用Protus仿真也提示错误,[SPICE]H1:unknown controlling source(null),我百度翻译是;未知控制源错误。这怎么弄啊?
求教大神!!!!!

评分

参与人数 1黑币 +20 收起 理由
admin + 20 回帖助人的奖励!

查看全部评分

回复

使用道具 举报

ID:86621 发表于 2016-4-21 09:09 | 显示全部楼层
论坛有帖子啊  你找自行车就可找到

评分

参与人数 1黑币 +20 收起 理由
admin + 20 回帖助人的奖励!

查看全部评分

回复

使用道具 举报

ID:115422 发表于 2016-4-21 10:25 | 显示全部楼层
1678 发表于 2016-4-21 09:09
论坛有帖子啊  你找自行车就可找到

谢谢                  
回复

使用道具 举报

ID:99341 发表于 2016-5-2 15:06 | 显示全部楼层
这有个AT89C2051自行车里程表 新建文件夹.rar (34.74 KB, 下载次数: 47)
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表