基于51单片机电动自行车车速报警系统proteus仿真原理图程序
创始人
2024-04-21 11:47:24

功能:
0.本项目采用STC89C52作为单片机系统的控制MCU
1.LCD1602液晶分三种显示模式
a)显示实时速度和本次里程
b)显示当前时间
c)显示报警速度和总里程
2.超过报警速度将声光报警
3.功能按键介绍
a显示状态下:
'上’键——电机速度+1 '下’键——电机速度-1
'设置’键——电机启动/暂停
'切换’键——切换显示状态
b显示状态下:
'设置’键——进入时间设置
'切换’键——切换显示状态
*时间设置状态
'上’键——加1 '下’键——减1
'左’键/'右’键——更改设置坐标
'切换’键——确定
c显示状态下:
'设置’键——进入速度设置
'切换’键——切换显示状态
*报警速度设置状态
'上’键——加1 '下’键——减1
'左’键/'右’键——更改设置选项
'切换’键——确定
*总里程设置状态
'上’键/'下’键——清零
'左’键/'右’键——更改设置选项
'切换’键——确定
4.采用DC002作为电源接口可直接输入5V给整个系统供电

原理图:
在这里插入图片描述

PCB :
在这里插入图片描述

主程序:

#include 
#include "main.h"#define DIAMETER 20 //直径,单位mmfloat distance = 0; //单位m
float totalDistBuf = 0; //单位m
float rate = 0; //单位km/h
float totalDist = 0; //单位km
unsigned char rateAlarm = 30; //单位km/h
unsigned char second = 0; 
unsigned char minute = 0; 
unsigned long pulseCnt = 0;
bit dispFlag = 1;
bit setTimeFlag = 0;
bit setAlarmFlag = 0;
bit motorFlag = 0;
bit refreshFlag = 0;
bit writeFlag = 0;
bit isNewFlag = 1;
unsigned char pwmValue = 3;
unsigned char setIndex = 0;enum{DISP_RATE_MODE, DISP_TIME_MODE, SET_ALARM_MODE
} dispMode;void main()
{//初始化LCD_Init();DS1302_Init();EEPROM_Init();//EEPROM_WriteByte(IS_NEW_ADDR, 1); //将芯片设为新芯片ReadEEPROM();if (isNewFlag != 0) //新芯片{EEPROM_WriteByte(IS_NEW_ADDR, 0);//给出初始值rateAlarm = 30;totalDist = 0;WriteEEPROM();}DS1302_ReadTime();Timer0_Init();Timer1_Init();EXT1_Init();//开机显示LCD_DispStr(0, 0, "    Welcome!    ");DelayS(2);LCD_Clear();while(1){//每秒钟更新数据if (refreshFlag == 1){distance = distance + DIAMETER * 2 * 3.14 * (float)pulseCnt / 1000 ; //单位mtotalDist = totalDist + DIAMETER * 2 * 3.14 * (float)pulseCnt / 1000; //单位kmrate = 3.6 * DIAMETER * 2 * 3.14 * (float)pulseCnt / 1000; //单位km/hpulseCnt = 0;EX1 = 1;refreshFlag = 0;}//每分钟写一次EEPROMif (writeFlag == 1){if (totalDist != totalDistBuf) //里程是否发生变化{WriteEEPROM();}totalDistBuf = totalDist;writeFlag = 0;}//显示函数if (dispFlag == 1){if (dispMode == DISP_RATE_MODE){DispRate();}else if (dispMode == DISP_TIME_MODE){if (setTimeFlag == 0){DS1302_ReadTime();DispTime(setIndex, setTimeFlag);}}else if (dispMode == SET_ALARM_MODE){if (setAlarmFlag == 0){// ReadEEPROM();if (totalDist != totalDistBuf){WriteEEPROM();}totalDistBuf = totalDist;DispAlarm(setIndex, setAlarmFlag);}}}//超速报警if (rate > rateAlarm){BUZZER = 0;}else{BUZZER = 1;}KeyProcess();}
}void ReadEEPROM(void)
{isNewFlag    = EEPROM_ReadByte(IS_NEW_ADDR);rateAlarm      = EEPROM_ReadByte(IS_NEW_ADDR + 1);totalDist      = EEPROM_ReadByte(IS_NEW_ADDR + 2);totalDist     = ((unsigned int)totalDist << 8) | EEPROM_ReadByte(IS_NEW_ADDR + 3);
}void WriteEEPROM(void)
{EEPROM_WriteByte(IS_NEW_ADDR + 1, rateAlarm);EEPROM_WriteByte(IS_NEW_ADDR + 2, (((unsigned int)totalDist & 0xFF00) >> 8));EEPROM_WriteByte(IS_NEW_ADDR + 3, ((unsigned int)totalDist & 0x00FF));
}void DispAlarm(unsigned char setIndex, bit setAlarmFlag)
{static unsigned char xdata dispRow0[16];static unsigned char xdata dispRow1[16];if (setAlarmFlag == 1){LCD_WriteCommand(0x0F, 0);}else{LCD_WriteCommand(0x0C, 0);LCD_WriteCommand(0x0C, 0);}sprintf(dispRow0, "Alarm:%6.2fkm/h", (float)rateAlarm);sprintf(dispRow1, "Total:%8.2fkm", (float)totalDist / 1000);LCD_DispStr(0, 0, dispRow0);LCD_DispStr(0, 1, dispRow1);switch (setIndex){case 1: LCD_LocateXY(8, 0); break;case 2: LCD_LocateXY(13, 1); break;default: ;}
}void DispRate()
{static unsigned char xdata dispRow0[16];static unsigned char xdata dispRow1[16];sprintf(dispRow0, "Rate:%7.2fkm/h", rate);sprintf(dispRow1, "Dist:%9.2fkm", distance / 1000);LCD_DispStr(0, 0, dispRow0);LCD_DispStr(0, 1, dispRow1);
}void DispTime(unsigned char setIndex, bit setTimeFlag)
{static unsigned char xdata dispRow0[] = "  /  /     ";static unsigned char xdata dispRow1[] = "      :  :      ";if (setTimeFlag == 1){LCD_WriteCommand(0x0F, 0);}else{LCD_WriteCommand(0x0C, 0);LCD_WriteCommand(0x0C, 0);}dispRow0[0] = timeBufDec[1] / 10 +'0';dispRow0[1] = timeBufDec[1] % 10 +'0';dispRow0[3] = timeBufDec[2] / 10 +'0';dispRow0[4] = timeBufDec[2] % 10 +'0';dispRow0[6] = timeBufDec[3] / 10 +'0';dispRow0[7] = timeBufDec[3] % 10 +'0';dispRow1[4] = timeBufDec[4] / 10 +'0';dispRow1[5] = timeBufDec[4] % 10 +'0';  dispRow1[7] = timeBufDec[5] / 10 +'0';dispRow1[8] = timeBufDec[5] % 10 +'0';dispRow1[10] = timeBufDec[6] / 10 +'0';dispRow1[11] = timeBufDec[6] % 10 +'0';LCD_DispStr(0, 0, dispRow0);LCD_DispStr(0, 1, dispRow1);switch (timeBufDec[7]){case 1: LCD_DispStr(10, 0, " Sun. "); break;case 2: LCD_DispStr(10, 0, " Mon. "); break;case 3: LCD_DispStr(10, 0, " Tue. "); break;case 4: LCD_DispStr(10, 0, " Wed. "); break;case 5: LCD_DispStr(10, 0, "Thur. "); break;case 6: LCD_DispStr(10, 0, " Fri. "); break;case 7: LCD_DispStr(10, 0, " Sat. "); break;default: ;}switch (setIndex){case 1: LCD_LocateXY(1 , 0); break;case 2: LCD_LocateXY(4 , 0); break;case 3: LCD_LocateXY(7 , 0); break;case 4: LCD_LocateXY(14, 0); break;case 5: LCD_LocateXY(5 , 1); break;case 6: LCD_LocateXY(8 , 1); break;case 7: LCD_LocateXY(11, 1); break;default: ;}
}void KeyProcess()
{if (!KEY_SET) //设置键按下{DelayMs(10);if (!KEY_SET){if (dispMode == DISP_TIME_MODE){if (setTimeFlag == 0){setTimeFlag = 1;setIndex = 1;DispTime(setIndex, setTimeFlag);}}else if(dispMode == SET_ALARM_MODE){if (setAlarmFlag == 0){setAlarmFlag = 1;setIndex = 1;DispAlarm(setIndex, setAlarmFlag);}}else{motorFlag = ~motorFlag;}}while (!KEY_SET);}if (!KEY_UP) //上键按下{DelayMs(150);if (!KEY_UP){if (dispMode == DISP_TIME_MODE){if (setTimeFlag == 1){switch (setIndex){case 1:{timeBufDec[1]++;if (timeBufDec[1] >= 100){timeBufDec[1] = 0;}break;}case 2:{timeBufDec[2]++;if (timeBufDec[2] >= 13){timeBufDec[2] = 1;}break;}case 3:{timeBufDec[3]++;if (timeBufDec[3] >= YDay(timeBufDec[1], timeBufDec[2]) + 1){timeBufDec[3] = 1;}break;}case 4:{timeBufDec[7]++;if (timeBufDec[7] > 7){timeBufDec[7] = 1;}break;}case 5:{timeBufDec[4]++;if (timeBufDec[4] >= 24){timeBufDec[4] = 0;}break;}case 6:{timeBufDec[5]++;if (timeBufDec[5] >= 60){timeBufDec[5] = 0;}break;}case 7:{timeBufDec[6]++;if (timeBufDec[6] >= 60){timeBufDec[6] = 0;}break;}default:;}DispTime(setIndex, setTimeFlag);}}else if (dispMode == SET_ALARM_MODE){if (setAlarmFlag){switch (setIndex){case 1:rateAlarm++;if (rateAlarm > 200){rateAlarm = 200;}break;case 2:totalDist = 0;break;}DispAlarm(setIndex, setAlarmFlag);}}else{if (pwmValue <= 11){pwmValue++;}}}//while (!KEY_UP);}if (!KEY_DOWN) //下键按下{DelayMs(150);if (!KEY_DOWN){if (dispMode == DISP_TIME_MODE){if (setTimeFlag == 1){switch (setIndex){case 1:{if (timeBufDec[1] == 0){timeBufDec[1] = 100;}timeBufDec[1]--;break;}case 2:{timeBufDec[2]--;if (timeBufDec[2] < 1){timeBufDec[2] = 12;}break;}case 3:{timeBufDec[3]--;if (timeBufDec[3] < 1){timeBufDec[3] = YDay(timeBufDec[1], timeBufDec[2]);}break;}case 4:{timeBufDec[7]--;if (timeBufDec[7] < 1){timeBufDec[7] = 7;}break;}case 5:{if (timeBufDec[4] == 0){timeBufDec[4] = 24;}timeBufDec[4]--;break;}case 6:{if (timeBufDec[5] == 0){timeBufDec[5] = 60;}timeBufDec[5]--;break;}case 7:{if (timeBufDec[6] == 0){timeBufDec[6] = 60;}timeBufDec[6]--;break;}default:;}DispTime(setIndex, setTimeFlag);}}else if (dispMode == SET_ALARM_MODE){if (setAlarmFlag){switch (setIndex){case 1:if (rateAlarm > 0){rateAlarm--;}break;case 2:totalDist = 0;break;}DispAlarm(setIndex, setAlarmFlag);}}else{if (pwmValue > 3){pwmValue--;}}}//while (!KEY_DOWN);}if (!KEY_LEFT) //左键按下{DelayMs(10);if (!KEY_LEFT){if (dispMode == DISP_TIME_MODE){if (setTimeFlag == 1){setIndex--;if (setIndex < 1){setIndex = 7;}DispTime(setIndex, setTimeFlag);}}else if (dispMode == SET_ALARM_MODE){if (setAlarmFlag){setIndex--;if (setIndex < 1){setIndex = 2;}DispAlarm(setIndex, setAlarmFlag);}}}while (!KEY_LEFT);}if (!KEY_RIGHT) //右键按下{DelayMs(10);if (!KEY_RIGHT){if (dispMode == DISP_TIME_MODE){if (setTimeFlag == 1){setIndex++;if (setIndex > 7){setIndex = 1;}DispTime(setIndex, setTimeFlag);}}if (setAlarmFlag){setIndex++;if (setIndex > 2){setIndex = 1;}DispAlarm(setIndex, setAlarmFlag);}}while (!KEY_RIGHT);}if (!KEY_ENTER) //确认键按下{DelayMs(10);if (!KEY_ENTER){if (dispMode == DISP_RATE_MODE){dispMode = DISP_TIME_MODE;setTimeFlag = 0;setIndex = 0;}else if (dispMode == DISP_TIME_MODE){if (setTimeFlag == 1){setTimeFlag = 0;setIndex = 0;DS1302_WriteTime();DispTime(setIndex, setTimeFlag);}else{dispMode = SET_ALARM_MODE;setIndex = 0;}}else if (dispMode == SET_ALARM_MODE){if (setAlarmFlag == 1){setAlarmFlag = 0;setIndex = 0;WriteEEPROM();DispAlarm(setIndex, setAlarmFlag);}else{dispMode = DISP_RATE_MODE;setIndex = 0;}}}while (!KEY_ENTER);}
}void EXT1_Init()
{IT1 = 1; //下降沿触发EX1 = 1; //使能外部中断0EA = 1; //打开总中断
}void EXT1_Interrupt() interrupt 2 using 1
{pulseCnt++;
}void Timer0_Init(void)
{TMOD &= 0xF0; //定时器模式0TMOD |= 0x01;PT0 = 1; //设置T0为高优先级TH0 = RH_10MS(3); //10msTL0 = RL_10MS(3);TR0 = 1; //启动T0计时ET0 = 1; //打开T0中断EA = 1;  //打开总中断
}void Timer0_Intterupt(void) interrupt 1 using 0
{static unsigned int cnt=0;   static unsigned char IN1Count = 0;//    TH0 = 0xF8; //设置定时初值
//    TL0 = 0xCD; //设置定时初值 2msTH0 = 0xFC; //设置定时初值TL0 = 0x66; //设置定时初值 1msIN1Count++;cnt++;if (motorFlag == 1){if (IN1Count < pwmValue) //占空比调节{MOTOR = 0;    }else if ((IN1Count >= pwmValue) && (IN1Count <= 11)) //关闭时间段{MOTOR = 1;}else{IN1Count = 0; //一个周期结束}}else{MOTOR = 1;}if (cnt >= 250) //500ms{dispFlag = ~dispFlag;cnt = 0;}
}void Timer1_Init(void)
{TMOD &= 0x0F; //定时器模式1TMOD |= 0x10;TH1 = RH_10MS(5); //50msTL1 = RL_10MS(5);TR1 = 1; //开启T1计时ET1 = 1; //打开T1中断EA = 1;  //打开总中断
}void Timer1_Intterupt(void) interrupt 3 using 2
{static unsigned int cnt=0;TH1 = RH_10MS(5); //50msTL1 = RL_10MS(5);cnt++;if (cnt >= 20) //1s{EX1 = 0;if (second >= 60){second = 0;minute++;if (minute == 1){writeFlag = 1;minute = 0;}}else{second++;}refreshFlag = 1;cnt = 0;}
}

仿真演示视频:
https://www.bilibili.com/video/BV13R4y1G7k4/

实物演示视频:
https://www.bilibili.com/video/BV1iY411G7AJ/

相关内容

热门资讯

猫咪吃了塑料袋怎么办 猫咪误食... 你知道吗?塑料袋放久了会长猫哦!要说猫咪对塑料袋的喜爱程度完完全全可以媲美纸箱家里只要一有塑料袋的响...
世界上最漂亮的人 世界上最漂亮... 此前在某网上,选出了全球265万颜值姣好的女性。从这些数量庞大的女性群体中,人们投票选出了心目中最美...
demo什么意思 demo版本... 618快到了,各位的小金库大概也在准备开闸放水了吧。没有小金库的,也该向老婆撒娇卖萌服个软了,一切只...
苗族的传统节日 贵州苗族节日有... 【岜沙苗族芦笙节】岜沙,苗语叫“分送”,距从江县城7.5公里,是世界上最崇拜树木并以树为神的枪手部落...