毕业设计自行车测速仪.docx
《毕业设计自行车测速仪.docx》由会员分享,可在线阅读,更多相关《毕业设计自行车测速仪.docx(26页珍藏版)》请在冰豆网上搜索。
![毕业设计自行车测速仪.docx](https://file1.bdocx.com/fileroot1/2023-3/30/eaf03e6d-521b-4e09-9899-2e2599112eeb/eaf03e6d-521b-4e09-9899-2e2599112eeb1.gif)
毕业设计自行车测速仪
#include
#include
#include
#defineGDM12864ADataPortP1//LCD数据线
#defineucharunsignedchar
sbitDI=P2^2;//数据\指令选择
sbitRW=P2^1;//读\写选择
sbitEN=P2^0;//读\写使能
sbitcs1=P2^4;//片选1
sbitcs2=P2^3;//片选2
sbitsclk=P2^5;
sbiti_o=P2^6;
sbitrstb=P2^7;
sbitds18s20_dq=P3^6;
sbitI2C_SCK=P3^3;
sbitI2C_SDA=P3^5;
ucharqq=0,pp=0;//开始/暂停按键,计算机传输过来的数据为8则上传
ucharcodea[]={//16*16
0x10,0x22,0x64,0x0C,0x80,0x00,0xFE,0x92,0x92,0x92,0x92,0x92,0xFF,0x02,0x00,0x00,
0x04,0x04,0xFE,0x01,0x40,0x7E,0x42,0x42,0x7E,0x42,0x7E,0x42,0x42,0x7E,0x40,0x00,
0x00,0x00,0xFC,0x24,0x24,0x24,0xFC,0xA5,0xA6,0xA4,0xFC,0x24,0x34,0x26,0x04,0x00,
0x40,0x20,0x9F,0x80,0x42,0x42,0x26,0x2A,0x12,0x2A,0x26,0x42,0x40,0xC0,0x40,0x00,
0x00,0xFC,0x84,0x84,0x84,0xFE,0x14,0x10,0x90,0x10,0x10,0x10,0xFF,0x10,0x10,0x00,
0x00,0x3F,0x10,0x10,0x10,0x3F,0x00,0x00,0x00,0x23,0x40,0x80,0x7F,0x00,0x00,0x00,
0x00,0xF8,0x01,0x02,0xF6,0x10,0x12,0x12,0x12,0x12,0xFA,0x12,0x02,0xFF,0x02,0x00,
0x00,0xFF,0x00,0x00,0x3F,0x11,0x11,0x11,0x11,0x11,0x3F,0x40,0x80,0x7F,0x00,0x00,
0x40,0x42,0x44,0xCC,0x00,0xF4,0x94,0x94,0x94,0xFF,0x94,0x94,0x94,0xF6,0x04,0x00,
0x00,0x40,0x20,0x1F,0x20,0x51,0x48,0x44,0x42,0x7F,0x42,0x44,0x4C,0x61,0x20,0x00,
0x00,0x00,0xFE,0x12,0x12,0x12,0x12,0xFE,0x12,0x12,0x12,0x12,0xFF,0x02,0x00,0x00,
0x40,0x48,0x49,0x49,0x49,0x49,0x49,0x7F,0x49,0x49,0x49,0x49,0x4D,0x68,0x40,0x00,
0x24,0x24,0xA4,0xFE,0xA3,0x22,0x20,0x7E,0x42,0x42,0x42,0x42,0x42,0x7F,0x02,0x00,
0x08,0x06,0x01,0xFF,0x00,0x43,0x41,0x49,0x49,0x49,0x7F,0x49,0x4D,0x69,0x41,0x00,
0x00,0x00,0xFE,0x82,0x92,0x92,0x92,0xFE,0x92,0x9A,0xD2,0x82,0xFF,0x02,0x00,0x00,
0x40,0x20,0x1F,0x00,0x00,0x7E,0x22,0x22,0x22,0x3F,0x42,0x80,0x7F,0x00,0x00,0x00,
0x80,0x80,0x80,0x80,0xFF,0x80,0x80,0xA0,0x90,0x88,0x84,0x86,0x80,0xC0,0x80,0x00,
0x00,0x00,0x00,0x00,0xFF,0x40,0x40,0x23,0x04,0x08,0x10,0x20,0x60,0x20,0x00,0x00,
0x00,0x06,0x09,0x09,0xE6,0xF0,0x18,0x08,0x08,0x08,0x18,0x30,0x78,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x07,0x0F,0x18,0x30,0x20,0x20,0x20,0x10,0x08,0x00,0x00,0x00,
0x80,0x40,0x20,0xF8,0x47,0x48,0x48,0x48,0xC8,0x7F,0x48,0x48,0x4C,0x68,0x40,0x00,
0x00,0x00,0x00,0xFF,0x00,0x00,0x02,0x0B,0x12,0x62,0xD2,0x0A,0x06,0x02,0x00,0x00
};
ucharcodeb[]={//8*16
0x00,0xF8,0x08,0x08,0x08,0x08,0xF8,0x00,0x00,0x3F,0x20,0x20,0x20,0x20,0x3F,0x00,
0x00,0x00,0x00,0x00,0xF8,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3F,0x00,0x00,0x00,
0x00,0x08,0x08,0x08,0x08,0x08,0xF8,0x00,0x00,0x3F,0x21,0x21,0x21,0x21,0x21,0x00,
0x00,0x08,0x08,0x08,0x08,0x08,0xF8,0x00,0x00,0x21,0x21,0x21,0x21,0x21,0x3F,0x00,
0x00,0xF8,0x00,0x00,0x00,0x00,0xF8,0x00,0x00,0x01,0x01,0x01,0x01,0x01,0x3F,0x00,
0x00,0xF8,0x08,0x08,0x08,0x08,0x00,0x00,0x00,0x21,0x21,0x21,0x21,0x21,0x3F,0x00,
0x00,0xF8,0x08,0x08,0x08,0x08,0x08,0x00,0x00,0x3F,0x21,0x21,0x21,0x21,0x3F,0x00,
0x00,0x08,0x08,0x08,0x08,0x08,0xF8,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3F,0x00,
0x00,0xF8,0x08,0x08,0x08,0x08,0xF8,0x00,0x00,0x3F,0x21,0x21,0x21,0x21,0x3F,0x00,
0x00,0xF8,0x08,0x08,0x08,0x08,0xF8,0x00,0x00,0x01,0x01,0x01,0x01,0x01,0x3F,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3E,0x01,0x01,0x3E,0x01,0x01,0x3E,0x00,
0x00,0x00,0x80,0x80,0x00,0x00,0x00,0x00,0x00,0x13,0x24,0x24,0x19,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x20,0x10,0x08,0x04,0x02,0x01,0x00,
0x00,0x00,0x00,0x30,0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x0C,0x0C,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x30,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x01,0x01,0x01,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0xC0,0x00,0x00,0x80,0x40,0x00,0x00,0x00,0x3F,0x06,0x09,0x10,0x20,0x00,0x00,//17,k
0x00,0xC0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3F,0x02,0x02,0x02,0x3E,0x00,0x00//18,h
};
//延时程序,延时10us
voidDelay_10_uS(void)
{
chari=10;
while(i--);
}
//nmSdelay
voidDelay_N_mS(unsignedintn_milisecond)/*nmSdelay*/
{
unsignedchari;
while(n_milisecond--)
{
i=37;
while(i--);
}
}
//启动传送
bitI2C_Start(void)
{
Delay_10_uS();
I2C_SDA=1;
Delay_10_uS();
I2C_SCK=1;
Delay_10_uS();
if(I2C_SDA==0)return0;
if(I2C_SCK==0)return0;
I2C_SDA=0;
Delay_10_uS();
I2C_SCK=0;
Delay_10_uS();
return1;
}
//停止信号
voidI2C_Stop(void)
{
Delay_10_uS();
I2C_SDA=0;
Delay_10_uS();
I2C_SCK=1;
Delay_10_uS();
I2C_SDA=1;
Delay_10_uS();
}
//无应答的时序,有应答时需要在第9位输出0,没有应答时,第9位为高
voidI2C_Nack(void)
{
Delay_10_uS();
I2C_SDA=1;
Delay_10_uS();
I2C_SCK=1;
Delay_10_uS();
I2C_SCK=0;
Delay_10_uS();
}
//如果发送完成并且在第9个脉冲处得到ack,那么返回0,表示成功
bitI2C_Send_Byte(unsignedchard)
{
unsignedchari=8;
bitbit_ack;
while(i--)
{
Delay_10_uS();
if(d&0x80)I2C_SDA=1;
elseI2C_SDA=0;
Delay_10_uS();
I2C_SCK=1;
Delay_10_uS();
I2C_SCK=0;
d=d<<1;
}
Delay_10_uS();
I2C_SDA=1;
Delay_10_uS();
I2C_SCK=1;
Delay_10_uS();
bit_ack=I2C_SDA;
I2C_SCK=0;
Delay_10_uS();
returnbit_ack;
}
//接收一个8位数据
unsignedcharI2C_Receive_Byte(void)
{
unsignedchari=8,d;
Delay_10_uS();
I2C_SDA=1;
while(i--)
{
d=d<<1;
Delay_10_uS();
I2C_SCK=1;
if(I2C_SDA)d++;
Delay_10_uS();
I2C_SCK=0;
}
returnd;
}
//写EEPROM操作
voidAT24C64_W(void*mcu_address,unsignedintAT24C64_address,unsignedintcount)
{
while(count--)
{
I2C_Start();
I2C_Send_Byte(0xa0);
I2C_Send_Byte(AT24C64_address/256);
I2C_Send_Byte(AT24C64_address%256);
I2C_Send_Byte(*(unsignedchar*)mcu_address);
I2C_Stop();
Delay_N_mS(10);
((unsignedchar*)mcu_address)++;
AT24C64_address++;
}
}
//读EEPROM函数
voidAT24C64_R(void*mcu_address,unsignedintAT24C64_address,unsignedintcount)
{
while(count--)
{
I2C_Start();
I2C_Send_Byte(0xa0);
I2C_Send_Byte(AT24C64_address/256);
I2C_Send_Byte(AT24C64_address%256);
I2C_Start();
I2C_Send_Byte(0xa1);
*(unsignedchar*)mcu_address=I2C_Receive_Byte();
I2C_Nack();
I2C_Stop();
((unsignedchar*)mcu_address)++;
AT24C64_address++;
}
}
//单总线延时
voidds18s20delay(intuseconds)
{
ints;
for(s=0;s}
//单总线复位
uchards18s20reset()
{
ucharpresencesignal;
ds18s20_dq=0;
ds18s20delay(30);
ds18s20_dq=1;
ds18s20delay(3);
presencesignal=ds18s20_dq;
ds18s20delay(30);
returnpresencesignal;
}
//单总线位写入
voidds18s20writebit(charval)
{
ds18s20_dq=0;
if(val==1)
ds18s20_dq=1;
else
ds18s20_dq=0;
ds18s20delay(5);
ds18s20_dq=1;
}
//单总线字节写入
voidds18s20writebyte(charval)
{
uchari;
uchartemp;
for(i=0;i<8;i++)
{
temp=val>>i;
temp&=0x01;
ds18s20writebit(temp);
}
ds18s20delay(5);
}
//单总线位读取
uchards18s20readbit(void)
{
uchari;
ds18s20_dq=0;
ds18s20_dq=1;
for(i=0;i<3;i++)
returnds18s20_dq;
}
//单总线字节读取
uchards18s20readbyte(void)
{
uchari;
ucharvalue=0;
for(i=0;i<8;i++)
{
if(ds18s20readbit())
value|=0x01<
ds18s20delay(7);
}
return(value);
}
//实时时钟复位函数
voidresetds1302()
{
ds18s20delay
(1);
sclk=0;
ds18s20delay
(1);
rstb=0;
ds18s20delay
(1);
rstb=1;
ds18s20delay
(1);
}
//时钟字节读取函数
ucharreadbyteds1302()
{
uchari;
ucharrbyte;
uchartempbyte;
rbyte=0x00;
i_o=1;
ds18s20delay
(1);
for(i=0;i<8;++i)
{
sclk=1;
ds18s20delay
(1);
sclk=0;
ds18s20delay
(1);
tempbyte=(uchar)i_o;
tempbyte<<=7;
rbyte>>=1;
rbyte|=tempbyte;
}
returnrbyte;
}
//时钟字节写入函数
voidwritebyteds1302(ucharw_byte)
{
uchari;
ds18s20delay
(1);
for(i=0;i<8;++i)
{i_o=0;
if(w_byte&0x01)i_o=1;
sclk=0;
ds18s20delay
(1);
sclk=1;
ds18s20delay
(1);
w_byte>>=1;
}
}
//时钟初始化函数
voidinitds1302()
{
resetds1302();
writebyteds1302(0x8e);
writebyteds1302(0);
resetds1302();
writebyteds1302(0x90);
writebyteds1302(0xab);
resetds1302();
writebyteds1302(0xbe);
writebyteds1302(0);
writebyteds1302(0);
writebyteds1302(0);
writebyteds1302(0);
writebyteds1302(0);
writebyteds1302(0);
writebyteds1302(0);
writebyteds1302(0);
writebyteds1302(0);
resetds1302();
}
//时钟字节写入函数
voidwriteclkbyte(ucharadress,uchardate)
{
adress=((adress*2)|0x80);
resetds1302();
writebyteds1302(adress);
writebyteds1302(date);
resetds1302();
}
//状态检查,
voidCheckState()
{
unsignedchardat;
DI=0;
RW=1;
do{
GDM12864ADataPort=0x00;
EN=1;
dat=GDM12864ADataPort;
EN=0;
dat=0x80&dat;//仅当第7位为0时才可操作(判别busy信号)
}while(!
(dat==0x00));
}
//向LCD发送命令
//command:
命令
voidSendCommandToLCD(unsignedcharcommand)
{
CheckState();
RW=0;
GDM12864ADataPort=command;
EN=1;EN=0;
}
//写显示数据
//dat:
显示数据
voidWriteByte(unsignedchardat)
{
CheckState();
DI=1;RW=0;
GDM12864ADataPort=dat;
EN=1;EN=0;
}
//设定行地址(页)--X0-7
voidSetLine(unsignedcharline)
{
line=line&0x07;//0<=line<=7
line=line|0xb8;//10111xxx
SendCommandToLCD(line);
}
//设定列地址--Y0-63
voidSetColumn(unsignedcharcolumn)
{
column=column&0x3f;//0=column=column|0x40;//01xxxxxx
SendCommandToLCD(column);
}
//设定显示开始行--XX
voidSetStartLine(unsignedcharstartline)//0--63
{
startline=startline&0x07;
startline=startline|0xc0;//11000000
SendCommandToLCD(startline);
}
//开关显示
voidSetOnOff(unsignedcharonoff)
{
onoff=0x3e|onoff;//0011111x
SendCommandToLCD(onoff);
}
//选择屏幕
//screen:
0-全屏,1-左屏,2-右屏
voidSelectScreen(unsignedcharscreen)
{//cs1:
1--左;cs2:
1--右
switch(screen)
{case0:
cs1=0;//全屏
_nop_();_nop_();_nop_();
cs2=0;
_nop_();_nop_();_nop_();
break;
case1:
cs1=0;//左屏
_nop_();_nop_();_nop_();
cs2=1;
_nop_();_nop_();_nop_();
break;
case2:
cs1=1;//右屏
_nop_();_nop_();_nop_();
cs2=0;
_nop_();_nop_();_nop_();
break;
}
}
//延时
delay(unsignedintt)
{
unsignedinti=t,m,n;
for(m=0;m
for(n=0;n<100;n++);
}
//清屏
//screen:
0-全屏,1-左屏,2-右?
分屏干嘛,直接全屏不好吗
voidClearScreen(unsignedcharscreen)
{unsignedchari,j;
SelectScreen(screen);
for(i=0;i<8;i++){
SetLine(i);
for(j=0;j<128;j++){
WriteByte