4909|13

74

帖子

0

TA的资源

一粒金砂(初级)

楼主
 

哪位高手帮我看懂十二页的代码 [复制链接]

哪位高手帮我看懂十二页的代码,主要问题是要用C语言在At89s52单片机上实现对自行车行驶时的路程和速度的显示,这里有用C语言写好的代码,前面还有一些1602LCD的一些输入,不是太能看懂,那位高手能帮我看懂具体的流程,然后能告诉我路程的输出到LCD上的具体的过程,要描述出在经过每个函数的及重要函数参数的过程和作用,最好详细点,分数不够我再加,谢谢各位高手了,程序比较长,分为几部分给出了在线等。




#include
#define         uchar unsigned char

/****************************************************************
引脚定义:
P20=SW1 时钟设置时更改“时”,直径设置时更改十位
P21=SW2         时钟设置时更改“分”的十位,直径设置时更改个位
P22=SW3  时钟设置时更改“分”的个位
P23=Enter 确认更改设置
P32=Disp  正常工作时更改显示模式
****************************************************************************/
sbit P20=P2^0;
sbit P21=P2^1;
sbit P22=P2^2;
sbit P23=P2^3;
sbit P32=P3^2;
sbit RS=P3^7;
sbit RW=P3^6;
sbit E=P3^5;
sbit busy=P1^7;

/****************************************************************
变量定义:
i      延时变量
qsls      圈数临时变量,用于判断里程显示选用m还是km作为单位
qs     圈数
sj     累计行驶时间,单位为秒
totallc        累计里程
pjsd    平均速度
ssji     定时器T1 20ms中断次数,用于计算速度等
sji            本次速度对应的20ms中断次数
sjiold             上次速度对应的20ms中断次数
aa                 加速度
sd2            当前速度
mxsd    用于更新最大速度
mxsd2   最大速度对应的20ms次数
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,totallc,pjsd,ssji,sji,sjiold,aa,sd2,mxsd,mxsd2,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()
{P1=0xff;
RW=1; RS=0;                  
do{E=0;E=1;}while(busy==1);
}

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

/**********************************void wrcom()*******************************
      该函数的作用是向LCD写入控制字.
******************************************************************************/
void wrcom(com)
{P1=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);
}

最新回复

谢谢大家啊,大概搞明白了  详情 回复 发表于 2010-1-10 12:44
点赞 关注

回复
举报

73

帖子

0

TA的资源

一粒金砂(初级)

沙发
 
/****************************************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 mxsdp()********************************
最大速度数据处理及显示子程序
******************************************************************************************/
void mxsdp()                                 
{
if(mxsd!=0)
mxsd2=tc*1800/mxsd;
else mxsd2=0;
qw=mxsd2%100000/10000;
bw=mxsd2%10000/1000;
sw=mxsd2%1000/100;
gw=mxsd2%100/10;
wrcom(0xc2);
dispone('V');
dispone('m');
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 apfz()********************************
加速度数据处理及显示子程序 辅助程序
******************************************************************************************/
void apfz()
{
wrcom(0xc2);
dispone('a');
wrcom(0xc6);
dispone(qw+0x30);
dispone(bw+0x30);
dispone('.');
dispone(sw+0x30);
dispone(gw+0x30);
dispone(' ');
dispone('m');
dispone('/');
dispone('s');
dispone('2');
}
/****************************************void ap()********************************
加速度数据处理及显示子程序
******************************************************************************************/
void ap()
{
if (sjiold==sji)
   {gw=sw=bw=qw=0;
    apfz();}
else if(sjiold     {aa=360*tc*(sji-sjiold)/sji/sjiold/(sji+sjiold);
        qw=aa/1000;
        bw=aa%1000/100;
        sw=aa%100/10;
        gw=aa%10;
        wrcom(0xc5);
        dispone('-');
        apfz();}
else if(sjiold>sji)
    {aa=360*tc*(sjiold-sji)/sji/sjiold/(sji+sjiold);
        qw=aa/1000;
        bw=aa%1000/100;
        sw=aa%100/10;
        gw=aa%10;
        wrcom(0xc5);
        dispone(' ');
        apfz();}
}

/****************************************void int0()********************************
外部中断0(干簧管)中断服务程序
*****************************************************************************************/
void int0() interrupt 0                       
{
EX0=0;                               
qs++;                                                        //圈数+1
TR1=0;
sjiold=sji;                                                        //停止T1计时
sji=ssji;

if (mxsd!=0)                                        //更新最大速度
      {
        if (sji           }
else mxsd=sji;                       
TH1=0xb1;                                                //重置T1定时常数
TL1=0xdf;
ssji=0;
TR1=1;                                                    //T1重新开始计时
switch(MODE)
{
   case 0:wrcom(0x01);lcp();ttimep();break;
   case 1:wrcom(0x01);sdp();mxsdp();break;
   case 2:wrcom(0x01);pjsdp();ap();break;
   case 3: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();mxsdp();break;
   case 2:wrcom(0x01);pjsdp();ap();break;
   case 3: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==3) 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;


P2=0xff;
cgw=csw=cbw=cqw=cww=csww=cww2=0;
wrcom(0x01);
dispmore(1,5,"Set Time",8);
clkp();
while(1){
if(P23==0){for(i=0;i<4000;i++);if(P23==0)break;}
if(P20==0){for(i=0;i<4000;i++);if(P20==0){cww2++;if(cww2>23)cww2=0;csww=cww2/10;cww=cww2%10;clkp();for(i=0;i<32000;i++);}}
if(P21==0){for(i=0;i<4000;i++);if(P21==0){if(++cqw>5)cqw=0;clkp();for(i=0;i<32000;i++);}}
if(P22==0){for(i=0;i<4000;i++);if(P22==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');
P2=0xff;
wrcom(0xc6);dispone(tr1+0x30);
wrcom(0xc7);dispone(tr2+0x30);
while(1){
if(P20==0){for(i=0;i<4000;i++);if(P20==0){if(++tr1>9)tr1=0;wrcom(0xc6);dispone(tr1+0x30);for(i=0;i<32000;i++);}}
if(P21==0){for(i=0;i<4000;i++);if(P21==0){if(++tr2>9)tr2=0;wrcom(0xc7);dispone(tr2+0x30);for(i=0;i<32000;i++);}}
if(P23==0){for(i=0;i<4000;i++);if(P23==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;
P32=1;
IE0=0;
wrcom(0x01);
for (;;);

}
 
 

回复

78

帖子

0

TA的资源

一粒金砂(初级)

板凳
 
晕~~~~~~~~~~~~~~~~~~这么多,谁有那耐心看完哇~~~~~~~~~~
 
 
 

回复

76

帖子

0

TA的资源

一粒金砂(初级)

4
 
不行的话,大概的过程也行,谁答给谁分
 
 
 

回复

75

帖子

0

TA的资源

一粒金砂(初级)

5
 
C语言模块化写的,看起来也比较快
 
 
 

回复

54

帖子

0

TA的资源

一粒金砂(初级)

6
 
高手帮帮忙啊,新手但急着交,分不够接着加,人不多,谁答分就给谁
 
 
 

回复

85

帖子

0

TA的资源

一粒金砂(初级)

7
 
呵呵!太长了!没有时间看呀!帮顶一下!
 
 
 

回复

68

帖子

0

TA的资源

一粒金砂(初级)

8
 
他是在车轮处放一个磁铁,配合干簧管,通过干簧管的通断计算圈数×轮胎周长计算长度,除以时间计算速度
长度可以用来计算累计里程!基本是这样!只要知道了速度、时间你就可以根据物理公式计算加速度等等了!1602的显示比较普通哦!
 
 
 

回复

75

帖子

0

TA的资源

一粒金砂(初级)

9
 
楼主要分两块分析 一个是LCE部分,一个是里程计算
LCD部分 流程很简单,就是初始化LCE(LCD寄存器中写一些命令,具体这些命令,要看LCD控制器的手册)-》判断LCD是否繁忙-》若不忙,可以进行读写操作,如果忙,要等待,只有等LCD不忙的时候,才能响应你的读写操作

在读写操作的时候,写是要写一些命令和地址,然后写入你要显示的数据的ASCII
 
 
 

回复

77

帖子

0

TA的资源

一粒金砂(初级)

10
 
至于算里程,用的单片机定时1 具体算法,注释挺清楚的啊,楼主要耐心分析的
 
 
 

回复

78

帖子

0

TA的资源

一粒金砂(初级)

11
 
高手们,为什么在dispone函数中的传递的实参的只要加上0x30呢,比如dispone(qw+0x30); dispone(bw+0x30);是不是和1602lcd有关啊,但是翻阅了1602LCD的资料后还是不明白,为什么要加上0x30
 
 
 

回复

78

帖子

0

TA的资源

一粒金砂(初级)

12
 
引用 10 楼 zkdceo 的回复:
高手们,为什么在dispone函数中的传递的实参的只要加上0x30呢,比如dispone(qw+0x30); dispone(bw+0x30);是不是和1602lcd有关啊,但是翻阅了1602LCD的资料后还是不明白,为什么要加上0x30


要将计数值转化为ASCII来显示呀!
 
 
 

回复

68

帖子

0

TA的资源

一粒金砂(初级)

13
 
引用 10 楼 zkdceo 的回复:
高手们,为什么在dispone函数中的传递的实参的只要加上0x30呢,比如dispone(qw+0x30); dispone(bw+0x30);是不是和1602lcd有关啊,但是翻阅了1602LCD的资料后还是不明白,为什么要加上0x30


那是转化成ASCII码的
 
 
 

回复

53

帖子

0

TA的资源

一粒金砂(初级)

14
 
谢谢大家啊,大概搞明白了
 
 
 

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

随便看看
查找数据手册?

EEWorld Datasheet 技术支持

相关文章 更多>>
关闭
站长推荐上一条 1/10 下一条

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

About Us 关于我们 客户服务 联系方式 器件索引 网站地图 最新更新 手机版

站点相关: 国产芯 安防电子 汽车电子 手机便携 工业控制 家用电子 医疗电子 测试测量 网络通信 物联网

北京市海淀区中关村大街18号B座15层1530室 电话:(010)82350740 邮编:100190

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved
快速回复 返回顶部 返回列表