当前位置:文档之家› 自行车测速仪设计报告

自行车测速仪设计报告

嵌入式系统设计自行车车速报警系统摘要本课题实验主要是利用STC89C52RC、12864液晶、24C02E^2PROM、霍尔传感器和加速度倾角传感器来实现自行车测速功能。

通过霍尔传感器来采集信号,经过单片机处理后,由12864液晶显示其总里程,分里程,速度,加速度;信号经过加速度倾角传感器读出坡度值,并在12864液晶中显示出来;然后由数学公式计算出消耗的卡路里值。

12864显示页面一共有三面。

按键具有调控展现的页面,清除分里程数据,保存总里程数据的功能,利用24C02实现断电不消失的功能。

发光二极管模块,利用MOS管的特性可以实现在暗处自动点亮。

关键词:自行车测速仪;霍尔传感器A3144;加速度倾角传感器MMA7455;12864LCD目录1设计要求................................2设计方案................................2.1 芯片的选择...............................2.2 霍尔传感器与单片机的通信..............2.3 12864液晶屏与单片机..................2.4 单片机与24C02 ........................2.5 单片机与MMA7455 ......................2.6 单片机下载程序........................3总体方案................................3.1工作原理.............................3.2总体设计.............................4系统硬件设计............................4.1STC89C52RC单片机最小系统.............4.2各部分电路电路图.....................4.3整体电路.............................5系统软件设计............................5.1主程序流程...........................参考文献....................................附录........................................1设计要求1.1 发光二极管模块在暗处自动点亮功能。

1.2 利用霍尔传感器采集信号,由单片机处理后控制外围设备工作。

1.3 利用单片机控制12864液晶屏显示。

1.4 将指定的数据放入24C02中,达到断电不丢失的效果。

1.5 用Keil uVision3编写C程序,利用单片机最小系统烧写程序到单片机。

1.6 利用传感器模块计算倾角(坡度),由12864液晶显示。

2设计方案2.1 芯片的选择自行车测速仪按系统功能实现要求,决定控制系统采用STC89C52RC单片机,采集信号的霍尔传感器采用A3144,保存信息的E^2PROM 24C02,计算倾角的加速度倾角传感器MMA7455,用于显示的12864液晶。

2.2 霍尔传感器与单片机之间的通信将霍尔传感器的信号输出端和单片机的某一个I/O口相连(本板子中使用P2^3),通过检测P2^3电平的下降沿和上升沿来编写程序,以达到计数的功能。

2.3 12864液晶屏与单片机将12864液晶屏按照其操作指南正确连接在电路中,编写程序,由单片机控制12864液晶显示各种数据。

2.4 单片机与24C02程序编写中,要求保存功能的按键按下时,总里程的数据写入到24C02芯片中,达到断电不丢失的功能。

将24C02按照操作手册正确连接到电路中,由单片机控制,当检查到按键按下时,执行程序:经总里程数据写入24C02中,保存起来。

2.5 单片机与MMA7455此模块是用集成工艺制作好的商品。

按照操作手册正确连接到电路中,根据芯片资料和示例程序可以使其输出角度值,然后在12864中显示出来。

2.6单片机下载程序利用单片机最小系统和串口(配合MAX232转电平芯片),借助STC下载器完成程序的烧写。

3 总体方案3.1 工作原理本实验主要是利用STC89C52RC、12864液晶、24C02E^2PROM、霍尔传感器和加速度倾角传感器来实现自行车测速功能。

通过霍尔传感器来采集信号,经过单片机处理后,由12864液晶显示其总里程,分里程,速度,加速度;信号经过加速度倾角传感器读出坡度值,并在12864液晶中显示出来;然后由数学公式计算出消耗的卡路里值。

12864显示页面一共有三面。

按键具有调控展现的页面,清除分里程数据,保存总里程数据的功能,利用24C02实现断电不消失的功能。

发光二极管模块,利用MOS管的特性可以实现在暗处自动点亮。

3.2设计总体框图4 系统硬件设计4.1 STC89C52RC单片机最小系统4.1.1最小系统包括晶体振荡电路、复位开关和电源部分。

4.2各部分电路4.2.1 主要控制部分(STC89C52RC)4.2.2 12864液晶部分4.2.3 24C02部分电路4.2.4 串口及MAX232部分4.2.5 倾角传感器MMA74554.2.6 霍尔传感器部分4.2.7 发光二极管独立显示模块4.3整体电路5 系统软件设计主程序流程图参考文献[1] 沈红卫《基于单片机结构的智能系统设计与实现》电子工业出版社[2] 黄惠媛《单片机原理与接口技术》海洋出版社[3] 周平伍云辉《单片机应用技术》电子科技大学出版社[4] 吴金戌沈金阳郭庭吉《8051单片机实践与应用》清华大学出版社[5] 黄正谨等《电子设计竞赛赛题解析》东南大学出版社附录程序:/*************河北大学电信学院***********//*******************李炜*****************//***********自行车测速仪程序**************/#include<reg52.h>#include<intrins.h>#define uchar unsigned char#define uint unsigned int/**********液晶屏相关部分*****************/#define lcd_port P0 //液晶屏指令、数据通信接口sbit rs=P2^7; //液晶屏寄存器选择接口(rs=0时选择指令寄存器,rs=1时选择数据寄存器)sbit rw=P2^6; //液晶屏读写选择接口(rw=0时选择写入,rw=1时选择读出)sbit en=P2^5; //液晶屏使能接口(en=0时通信接口中断,en=1时通信接口接通)sbit ret=P2^4; //液晶屏主复位引脚/*********子函数部分*****************/void delayms_lcd(uint ms); //延时子函数,时间为1msvoid delay_n10_us(uint n); //10微秒延时函数(n*10us)void lcd_wr_command(uchar com); //向液晶屏输入命令子函数void lcd_wr_data(uchar dat); //向液晶屏输入数据单字节子函数void lcd_int(); //LCD初始化void picture_show0(); //12864画面0void picture_show1(); //12864画面1void picture_show2(); //12864画面2void picture_select(); //12864画面选择void key_select(); //按键相关判断void interrupt_set(); //中断函数参数设定void start_24C02(); //24C02起始信号void write_one_char(uchar x); //写入一个字节void wait_ack(); //等待应答uchar read_one_char(); //读出一个字节void stop_24C02(); //24C02终止信号void read_total_distance(); //读出24C02中数据并且赋值给total_distancevoid write_total_distance(); //写入24C02中total_distance数据void write_total_distance1(); //写入24C02中total_distance数据void forbid_data(); //限制所有变量的取值/*********24C02相关部分****************/sbit SCL=P1^5; //串口时钟引脚sbit SDA=P1^4; //串口数据引脚/**********相关数组部分***********/uchar code data1[]="欢迎使用";uchar code data2[]="自行车测速仪";uchar code data3[]="制作人";uchar code data4[]="李炜";uchar code data5[]="赵向辉";uchar code data6[]="总里程";uchar code data7[]="分里程";uchar code data8[]="速度";uchar code data9[]="加速度";uchar code data10[]="坡度";uchar code data11[]="卡路里";uchar code data12[]="请注意安全";uchar code data_show[]="0123456789" ;/***********相关变量部分************/uint new_total_distance=0,old_total_distance=0; //四位数据uint new_part_distance=0,old_part_distance=0; //三位数据uint old_speed=0,new_speed=0; //两位数据uint old_acceleration=0,new_acceleration=0; //两位数据uint old_ascent=0,new_ascent=0; //三位数据uint calorie=0; //三位数据uchar old_j=0,new_j=0,part_flag=0,write_flag=0,show_flag=0,control_flag=0; static uint time=0;/*******按键相关**************/sbit key1=P1^0; //页面上翻sbit key2=P1^1; //手动保存sbit key3=P1^2; //页面下翻sbit key4=P1^3; //清除分里程数据/*********霍尔传感器相关部分**********/sbit A3145_OUT=P2^3;/***********************************/void main(){read_total_distance();lcd_int(); //LCD初始化picture_show0();delayms_lcd(2000);lcd_int();picture_show1();delayms_lcd(2000);lcd_int();picture_show2();delayms_lcd(2000);interrupt_set();A3145_OUT=1;while(1){key_select();picture_select();if(control_flag==0)new_total_distance=new_part_distance;if(show_flag==1){if(old_j==1)picture_show1();if(old_j==2)picture_show2();}if(part_flag==1){while(A3145_OUT==0) ;ET0=0;TR0=0;new_speed=250/time;new_acceleration=(new_speed-old_speed)*50/time;time=0;ET0=1;TR0=1;new_part_distance+=5;calorie=(calorie+5);part_flag=0;show_flag=1;}forbid_data();}}/************限制所有变量的取值************/void forbid_data(){if((old_total_distance+new_total_distance)>9999){new_total_distance=old_total_distance=0;}if(new_part_distance>999){new_part_distance=0;write_total_distance();read_total_distance();}if(new_speed>99)new_speed=0;if(new_acceleration>99)new_acceleration=0;if(calorie>999)calorie=0;}/***********LCD显示画面0********************/ void picture_show0(){uchar i;i=0;lcd_wr_command(0x82); //设置液晶屏的显示位置while(data1[i]!=0){lcd_wr_data(data1[i]);i++;}i=0;lcd_wr_command(0x91);while(data2[i]!=0){lcd_wr_data(data2[i]);i++;}i=0;lcd_wr_command(0x8A);while(data3[i]!=0){lcd_wr_data(data3[i]);i++;}i=0;lcd_wr_command(0x99);while(data4[i]!=0){lcd_wr_data(data4[i]);i++;}i=0;lcd_wr_command(0x9C);while(data5[i]!=0){lcd_wr_data(data5[i]);i++;}}/**************LCD画面1********************/ void picture_show1(){uchar i,flag=0;uint temp;i=0;lcd_wr_command(0x81); //设置液晶屏的显示位置while(data6[i]!=0){lcd_wr_data(data6[i]);i++;}lcd_wr_command(0x84);temp=(new_total_distance+old_total_distance);if(temp/1000==0)lcd_wr_data(' ');else{lcd_wr_data(data_show[temp/1000]); //显示数据(字符)flag=1;}temp%=1000;if((temp/100)!=0||flag==1){lcd_wr_data(data_show[temp/100]); //显示数据(字符)flag=1;}elselcd_wr_data(' ');temp%=100;if((temp/10)!=0||flag==1){lcd_wr_data(data_show[temp/10]); //显示数据(字符)flag=1;}elselcd_wr_data(' ');temp%=10;lcd_wr_data(data_show[temp]); //显示数据(字符)lcd_wr_command(0x86);lcd_wr_data('m');i=0;flag=0;lcd_wr_command(0x91);while(data7[i]!=0){lcd_wr_data(data7[i]);i++;}lcd_wr_command(0x94);temp=new_part_distance;if(temp/100==0)lcd_wr_data(' ');else{lcd_wr_data(data_show[temp/100]); //显示数据(字符)flag=1;}temp%=100;if((temp/10)!=0||flag==1){lcd_wr_data(data_show[temp/10]); //显示数据(字符)flag=1;}elselcd_wr_data(' ');temp%=10;lcd_wr_data(data_show[temp]); //显示数据(字符)lcd_wr_command(0x96);lcd_wr_data('m');i=0;flag=0;lcd_wr_command(0x89);while(data8[i]!=0){lcd_wr_data(data8[i]);i++;}lcd_wr_command(0x8B);temp=new_speed;if(temp/10==0)lcd_wr_data(' ');elselcd_wr_data(data_show[temp/10]); //显示数据(字符)temp%=10;lcd_wr_data(data_show[temp]); //显示数据(字符)lcd_wr_command(0x8C);lcd_wr_data('m');lcd_wr_data('/');lcd_wr_data('s');i=0;old_speed=new_speed;lcd_wr_command(0x99);while(data12[i]!=0){lcd_wr_data(data12[i]);i++;}}/**************LCD画面2********************/void picture_show2(){uchar i,flag=0;uint temp;i=0;lcd_wr_command(0x81);while(data9[i]!=0){lcd_wr_data(data9[i]);i++;}lcd_wr_command(0x84);temp=new_acceleration;if(temp/10==0)lcd_wr_data(' ');elselcd_wr_data(data_show[temp/10]); //显示数据(字符)temp%=10;lcd_wr_data(data_show[temp]); //显示数据(字符)lcd_wr_command(0x85);lcd_wr_data('m');lcd_wr_data('/');lcd_wr_data('s');lcd_wr_data('2');i=0;flag=0;lcd_wr_command(0x91);while(data10[i]!=0){lcd_wr_data(data10[i]);i++;}lcd_wr_command(0x93);temp=new_ascent;if(temp/100==0)lcd_wr_data(' ');else{lcd_wr_data(data_show[temp/100]); //显示数据(字符)flag=1;}temp%=100;if((temp/10)!=0||flag==1){lcd_wr_data(data_show[temp/10]); //显示数据(字符)flag=1;}elselcd_wr_data(' ');temp%=10;lcd_wr_data(data_show[temp]); //显示数据(字符)lcd_wr_command(0x95);lcd_wr_data(0x09);i=0;flag=0;lcd_wr_command(0x89);while(data11[i]!=0) {lcd_wr_data(data11[i]);i++ ;}lcd_wr_command(0x8C);temp=calorie;if(temp/100==0)lcd_wr_data(' ');else{lcd_wr_data(data_show[temp/100]);flag=1;}temp%=100;if((temp/10)!=0||flag==1){lcd_wr_data(data_show[temp/10]); //显示数据(字符)flag=1;}elselcd_wr_data(' ');temp%=10;lcd_wr_data(data_show[temp]); //显示数据(字符)lcd_wr_command(0x8E);lcd_wr_data('k');i=0;flag=0;lcd_wr_command(0x99);while(data12[i]!=0){lcd_wr_data(data12[i]);i++ ;}}/***************LCD初始化************************/void lcd_int(){ret=0; //液晶屏复位delayms_lcd(2);ret=1;delayms_lcd(2);lcd_wr_command(0x30); //启动液晶屏基本指令集并开启绘图显示功能lcd_wr_command(0x0c); //开显示,关光标,不闪烁lcd_wr_command(0x06); //字符进入模式为:字符不动,光标右移,地址加一lcd_wr_command(0x01); //清屏delayms_lcd(2); //等待清屏完成}/**********向液晶屏写入命令子函数******************/void lcd_wr_command(uchar com){en=0;//关闭通信,为设置参数做准备rs=0;//选择指令寄存器rw=0;//写入液晶en=1;//为开始通信做准备lcd_port=com;delay_n10_us(8);//大于72us的延时(根据手册)en=0;//数据送如液晶屏并关闭通信(en的下降沿液晶屏接收数据)}/********向液晶屏输入数据子函数************/void lcd_wr_data(uchar dat){en=0;//关闭通信,为设置参数做准备rs=1;//选择数据寄存器rw=0;//写入液晶en=1;//为开始通信做准备lcd_port=dat;delay_n10_us(8);//大于72us的延时(根据手册)en=0;//数据送如液晶屏并关闭通信(en的下降沿液晶屏接收数据) }/***********毫秒延时函数,延时1ms***********/void delayms_lcd(uint ms){uchar i;while(ms--){for(i=0;i<121;i++);}}/***********10微秒延时函数(n*10us)***********/void delay_n10_us(uint n){while(n--){_nop_();_nop_();}}/*************LCD显示画面选择********************/void picture_select(){if(old_j==new_j) ;else{switch(new_j){case 1 :lcd_int();picture_show1();old_j=new_j;break;case 2 :lcd_int();picture_show2();old_j=new_j;break;}}}/*************按键相关判断********************/void key_select(){if(key1==0){delayms_lcd(7);if(key1==0){new_j=2;while(key1==0);}}if(key2==0){delayms_lcd(7);if(key2==0){old_total_distance+=new_total_distance;new_total_distance=0;write_total_distance();control_flag=1;while(key2==0);}}if(key3==0){delayms_lcd(7);if(key3==0){new_j=1;while(key3==0);}}if(key4==0){delayms_lcd(7);if(key4==0){old_total_distance+=new_total_distance;new_part_distance=0;while(key4==0);}}}/*************中断函数参数设定**************/void interrupt_set(){TMOD=0x11; //0001 0001 T1、T0工作在定时方式1TH1=(65536-10000)/256; //T1定时时间为10毫秒(10000微秒)TL1=(65536-10000)%256;TH0=(65536-20000)/256;TL0=(65536-20000)%256;ET1=1; //启动T1中断允许位ET0=1;EA=1; //启动总中断允许位TR1=1; //启动T1TR0=1;}/*************T1中断函数**************/void timer1() interrupt 3 using 1{ET1=0; //关闭T1中断允许位TH1=(65536-10000)/256; //重设T1定时时间为10毫秒(10000微秒)TL1=(65536-10000)%256;if(A3145_OUT==0){part_flag=1;}ET1=1; //开启T1中断允许位}/*************T0中断函数**************/void timer2() interrupt 1 using 2{TH0=(65536-20000)/256;TL0=(65536-20000)%256;time++;}/*************写入24C02中数据************/void write_total_distance(){start_24C02();write_one_char(0xa0);wait_ack();write_one_char(0x01);wait_ack();write_one_char(old_total_distance/256);wait_ack();stop_24C02();delayms_lcd(100);start_24C02();write_one_char(0xa0);wait_ack();write_one_char(0x02);wait_ack();write_one_char(old_total_distance%256);wait_ack();stop_24C02();delayms_lcd(100);}/*************读出24C02中total_distance数据****************/ void read_total_distance(){start_24C02();write_one_char(0xa0);wait_ack();write_one_char(0x01);wait_ack();start_24C02();write_one_char(0xa1);wait_ack();old_total_distance=read_one_char()*256;stop_24C02();delayms_lcd(100);start_24C02();write_one_char(0xa0);wait_ack();write_one_char(0x02);wait_ack();start_24C02();write_one_char(0xa1);wait_ack();old_total_distance+=read_one_char();stop_24C02();delayms_lcd(100);}/*************24C02启动程序****************/void start_24C02(){SCL=0;_nop_();SDA=1;_nop_();SCL=1;_nop_();SDA=0;_nop_();SCL=0;}/***********24C02写入一个字节*************/ void write_one_char(uchar x)//写入一个字节{uchar i;for(i=0;i<8;i++){x<<=1;SCL=0;_nop_();SDA=CY;_nop_();SCL=1;_nop_();}SCL=0;_nop_();}/**********24C02等待应答***********/void wait_ack(){SCL=0;_nop_();SDA=1;//释放数据线_nop_();SCL=1;_nop_();while(SDA==1);SCL=0;_nop_();}/*************24C02读出一个字节**********/ uchar read_one_char()//读出一个字节{uchar i,temp=0;SCL=0;_nop_();SDA=1;//释放数据线_nop_();for(i=0;i<8;i++){SCL=1;_nop_();temp<<=1;temp=temp|SDA;SCL=0;_nop_();}return(temp);}/*************24C02终止程序*************/ void stop_24C02(){SCL=0;_nop_();SDA=0;_nop_();SCL=1;_nop_();SDA=1;_nop_();SCL=0;//当总线多个器件时必须SCL=1;}。

相关主题