文章目录
- 前言
- 资料获取
- 设计介绍
- 功能介绍
- 设计程序
- 具体实现截图
- 目 录
- 设计获取
前言
💗博主介绍:✌全网粉丝10W+,CSDN特邀作者、博客专家、CSDN新星计划导师,一名热衷于单片机技术探索与分享的博主、专注于 精通51/STM32/MSP430/AVR等单片机设计 主要对象是咱们电子相关专业的大学生,希望您们都共创辉煌!✌💗
👇🏻 精彩专栏 推荐订阅👇🏻
单片机设计精品实战案例✅
感兴趣的可以先收藏起来,还有大家在毕设选题,项目以及论文编写等相关问题都可以给我留言咨询,希望帮助更多的人
资料获取
文章底部名片,详细资料联系我。
设计介绍
随着科学技术与物联网的发展,推动着智能化产品逐渐从无到有再到快速发展,智能科技逐渐改变社会发展方式,过去很多无法想象的科学技术或者生活方式,现在利用先进和智能化逐一解决,而过去普通自行车智能辅助系统已经不能科学的需求。为了设计一款基于单片机自行车智能辅助系统控制器,此设计利用51系列单片机,很好设计出一款智能化自行车智能辅助控制系统的要求。
本设计的完整的系统主要包括STC系列单片机最小系统、 速度采集电路、液晶显示电路、按键电路、光照采集电路、语音播放电路、温度采集电路和电源电路等组成。
本设计软件系统采用模块设计思想,采用C语言作为程序设计语言,通过Keil C51完成程序设计,使用仿真器下载软件完成程序的烧录和在线调试。 本文中设计了各个模块运行流程图和程序运行思想。
在系统硬件和软件系统都完成后,经过相应的软硬件测试后,通过搭建实验平台,逐步验证系统功能。最后,经过实际试验,验证了本系统具有很好的实用性和稳定性。
功能介绍
该系统的电路原理图是使用Altium Designer原理图绘制软件完成的。该款软件是PORTEL公司20世纪后期研发出的一款绘制原理图软件。采用标准库应用方式,能进行网络设计,这款软件有数据处理能力很快和开源系统及three D 仿真能力,是一个32位的常用软件,可以完成大多数系统图的制作,要你看看编译器生成的汇编代码,你将能够体验到此款软件的使用非常方便的,大部分语句生系统原理图板设计和PL器件制作等工作,能制作信号层最多32个,16个信号源。此款绘图软件的特色如下所示:
(1)可以很容易的画出好几十种的原理图链接方式;
(2)强大的全局编辑功能;
(3)此款绘图软件含有很大的定则原理,在编译窗口下,可以满足在在线编译和其它编译方法;
(4)此款绘图软件含有自动铺铜性能,而且另外具有全自动铺铜功能;
(5)软件所占内存很小,而且兼容性很好的。
本设计的原理图是通过网络标号进行走线连接了,这样看起来更加清晰,不易混乱,而且查错非常简便。
本设计由STC89C52单片机电路+液晶1602显示电路+时钟DS1302显示电路+霍尔测速电路组成。
通过液晶1602实时显示时间、速度、温度和光强。
串口更新时间命令:2019032718235503 (位数必须正好)
表示:2018年03月27日18时23分55秒 周03
设计程序
#include "main.h"
/*-----------------------------------------------
名称:IIC协议 PCF8591 AD/DA转换
内容:使用4路AD中的4路检测外部模拟量输入
------------------------------------------------*/
#define AddWr 0x90 //写数据地址
#define AddRd 0x91 //读数据地址
extern bit ack;
/*------------------------------------------------
读AD转值程序
输入参数 Chl 表示需要转换的通道,范围从0-3
返回值范围0-255
------------------------------------------------*/
unsigned char ReadADC(unsigned char Chl)
{
unsigned char Val;
Start_I2c(); //启动总线
SendByte(AddWr); //发送器件地址
if(ack==0)return(0);
SendByte(Chl); //发送器件子地址
if(ack==0)return(0);
Start_I2c();
SendByte(AddRd);
if(ack==0)return(0);
Val=RcvByte();
NoAck_I2c(); //发送非应位
Stop_I2c(); //结束总线
return(Val);
}
/*------------------------------------------------
写入DA转换数值
输入参数:dat 表示需要转换的DA数值,范围是0-255
------------------------------------------------*/
/*bit WriteDAC(unsigned char dat)
{
Start_I2c(); //启动总线
SendByte(AddWr); //发送器件地址
if(ack==0)return(0);
SendByte(0x40); //发送器件子地址
if(ack==0)return(0);
SendByte(dat); //发送数据
if(ack==0)return(0);
Stop_I2c();
}*/
sbit key_set = P3^5;
sbit key_LED = P3^6;
sbit key_BEEP = P3^7;
sbit LED1 = P2^4;
sbit LED2 = P2^3;
sbit music1 = P1^0;
sbit music2 = P1^1;
sbit music3 = P1^2;
sbit music4 = P1^3;
sbit music5 = P1^4;
char state = 0;
char i;
#define CIRCLE 180 //宏定义 车轮的周长(这个要根据实际的车轮进行设置)
sbit Signal = P2^2; //这里的Signal表示的是霍尔传感器的信号引脚
unsigned int PluNum = 0; //脉冲数
bit dealSuduFlag =0; //处理速度标志
uint speed = 0 ; //定义速度变量
uint length = 0 ;//定义路程变量
uint time_20ms,time_2m;
uchar light_data;
int Temp_data;
uchar Speed_Limit = 25;
unsigned char xdata dis0[16];//定义显示区域临时存储数组
unsigned char uart_i =0; //串口计数
unsigned char ReadTimeFlag= 0;//读取时间标志
unsigned char night_flag= 0;//读取时间标志
unsigned char off_flag= 0;//读取时间标志
unsigned char SetFlag =0; //时间设置标志
unsigned char time_buf2[17]; //时间暂存
unsigned char dis_time_buf[16] = {0};
/*------------------------------------------------
定时器初始化子程序
------------------------------------------------*/
void ConfigTimer0()
{
TMOD &= 0xF0; //清零T0的控制位
TMOD |= 0x01; //配置T0为模式1
TH0=(65536-10000)/256; //重新赋值 10ms
TL0=(65536-10000)%256;
ET0 = 1; //使能T0中断
TR0 = 1; //启动T0
EA = 1;
}
/*------------------------------------------------
定时器中断子程序
------------------------------------------------*/
void Timer0_isr(void) interrupt 1
{
TH0=(65536-20000)/256; //重新赋值 20ms
TL0=(65536-20000)%256;
time_20ms++;
if(time_20ms%30==0) //定时读取时间标志
{
if(state==0)
{
ReadTimeFlag=1;
}
}
if(time_20ms==100) //定时处理速度
{
dealSuduFlag =1; //处理速度标志置位
time_20ms =0;
if((night_flag==1)&&(speed==0))
time_2m++;
else time_2m = 0;
if(time_2m == 60)
{
time_2m=0;
if((night_flag==1)&&(speed==0))
off_flag =1;
else
off_flag = 0;
}
}
}
/*------------------------------------------------
显示子程序
------------------------------------------------*/
void Display()
{
if(state==0)
{
LcdShowStr(3, 0, "Temp:"); //Temperature显示到液晶屏上
LCD_set_position(8,0);
LCD_WriteData(0X30+TN/10);
LCD_WriteData(0X30+TN%10);
LCD_WriteData('.');
LCD_WriteData(0X30+TD);
LCD_WriteData(0XDF);//显示°
LCD_WriteData('C');
LcdShowStr(3, 1, "Light:"); //light intensity显示到液晶屏上
LCD_set_position(9,1);
LCD_WriteData(0X30+light_data/100);
LCD_WriteData(0X30+light_data%100/10);
LCD_WriteData(0X30+light_data%10);
LcdShowStr(12, 1, "Lux");
}
if(state==1)
{
LCD_WriteCom(0x02 + 0x80); //表示第一行
LCD_WriteData(2 + 0X30);
LCD_WriteData(0 + 0X30);
LCD_WriteData(dis_time_buf[2] + 0X30); //年
LCD_WriteData(dis_time_buf[3] + 0X30);
LCD_WriteData('/');
LCD_WriteData(dis_time_buf[4] + 0X30); //月
LCD_WriteData(dis_time_buf[5] + 0X30);
LCD_WriteData('/');
LCD_WriteData(dis_time_buf[6] + 0X30); //日
LCD_WriteData(dis_time_buf[7] + 0X30);
LCD_WriteData(' ');
LCD_WriteData(dis_time_buf[14] + 0X30); //星期
LCD_WriteCom(0x44 + 0x80); //表示第二行
LCD_WriteData(dis_time_buf[8] + 0X30); //时
LCD_WriteData(dis_time_buf[9] + 0X30);
LCD_WriteData(':');
LCD_WriteData(dis_time_buf[10] + 0X30); //分
LCD_WriteData(dis_time_buf[11] + 0X30);
LCD_WriteData(':');
LCD_WriteData(dis_time_buf[12] + 0X30); //秒
LCD_WriteData(dis_time_buf[13] + 0X30);
}
if(state==2)
{
//第一行,显示速度
LcdShowStr(2,0,"Speed:"); //设定液晶的写入位置为第一行第一格
LCD_WriteData(speed/100 +0x30); //显示速度的整数部分
LCD_WriteData('.');
LCD_WriteData(speed%100/10 +0x30); //显示速度的小数第一位
LCD_WriteData(speed%10 +0x30); //显示速度的小数第二位
LCD_WriteData('m');
LCD_WriteData('/');
LCD_WriteData('s');
//第二行,显示里程
LcdShowStr(2,1,"Length:"); //设定液晶的写入位置为第二行第一格
LCD_WriteData(length/10000+0x30); //显示里程的万位
LCD_WriteData(length%10000/1000+0x30); //显示里程的千位
LCD_WriteData(length%1000/100+0x30); //显示里程的百位
LCD_WriteData(length%100/10+0x30); //显示里程的十位
LCD_WriteData(length%10+0x30); //显示里程的个位
LCD_WriteData('m');
}
}
/*------------------------------------------------
按键控制子程序
------------------------------------------------*/
void ScanContrl()
{
if(!key_set)
{
delayms(10);
if(!key_set)
{
state++;
LCD_WriteCom(0x01);
while(!key_set);
if(state>2)
state=0;
}
}
if(!key_LED)
{
delayms(10);
if(!key_LED)
{
music2 = 0;
}
while(!key_LED);
music2 = 1;
}
if(!key_BEEP)
{
delayms(10);
if(!key_BEEP)
{
LED1 = ~LED1;
LED2 = ~LED2;
if(LED1==1)
music3 = 1;
else
music3 = 0;
}
while(!key_BEEP);
music3 = 1;
}
}
/*------------------------------------------------
数据读取子程序
------------------------------------------------*/
void ReadData()
{
/****************第一路AD**********************/
for(i=0;i<5;i++) //连续读5次,输入通道后多读几次,取最后一次值,以便读出稳定值
light_data = 255-ReadADC(0); //采集第一路AD值 0-255
light_data = light_data*250/255;
if(light_data<30)
night_flag = 1;
else night_flag = 0;
/****************第二路路AD**********************/
//for(i=0;i<5;i++) //连续读5次,输入通道后多读几次,取最后一次值,以便读出稳定值
// = 255-ReadADC(1); //采集第二路AD值 0-255
/****************第三路AD**********************/
//for(i=0;i<5;i++) //连续读5次,输入通道后多读几次,取最后一次值,以便读出稳定值
//num=ReadADC(2); //采集第三路AD值 0-255
/****************第四路AD**********************/
//for(i=0;i<5;i++) //连续读5次,输入通道后多读几次,取最后一次值,以便读出稳定值
//num=ReadADC(3); //采集第四路AD值 0-255
ReadTemp();
if(1) //定时读取ds1302 定时时间到 则标志位置1,处理过时间参数标志位清零
{
ReadTimeFlag=0; //标志位清零
Ds1302_Read_Time();//读取时间参数
dis_time_buf[0] = (time_buf[0] >> 4); //年
dis_time_buf[1] = (time_buf[0] & 0x0f);
dis_time_buf[2] = (time_buf[1] >> 4);
dis_time_buf[3] = (time_buf[1] & 0x0f);
dis_time_buf[4] = (time_buf[2] >> 4); //月
dis_time_buf[5] = (time_buf[2] & 0x0f);
dis_time_buf[6] = (time_buf[3] >> 4); //日
dis_time_buf[7] = (time_buf[3] & 0x0f);
dis_time_buf[14] = (time_buf[7] & 0x07); //星期
//第2行显示
dis_time_buf[8] = (time_buf[4] >> 4); //时
dis_time_buf[9] = (time_buf[4]& 0x0f);
dis_time_buf[10] = (time_buf[5] >> 4); //分
dis_time_buf[11] = (time_buf[5] & 0x0f);
dis_time_buf[12] = (time_buf[6] >> 4); //秒
dis_time_buf[13] = (time_buf[6] & 0x0f);
}
}
/*------------------------------------------------
响应子程序
------------------------------------------------*/
void WarnBuzzer()
{
if(length > 0)
{
if(length %5000 == 0)
music5 = 0;
else music5 = 1;
}
else music5 = 1;
if(speed>800)
music4 = 0;
else
music4 = 1;
if(night_flag)
{
if(speed>0)
{
off_flag=0;
LED1 = 0;
LED2 = 0;
}
if(off_flag==1)
{
LED1 = 1;
LED2 = 1;
}
}
else
{
LED1 = 1;
LED2 = 1;
}
}
void UART_Init(void)
{
SCON = 0x50; // SCON: 模式 1, 8-bit UART, 使能接收
TMOD |= 0x20; // TMOD: timer 1, mode 2, 8-bit 重装
TH1 = 0xFD; // TH1: 重装值 9600 波特率 晶振 11.0592MHz
TL1 = TH1;
TR1 = 1; // TR1: timer 1 打开
EA = 1; //打开总中断
ES = 1; //打开串口中断
}
void uartSendByte(unsigned char dat)
{
unsigned char time_out;
time_out=0x00;
SBUF = dat; //将数据放入SBUF中
while((!TI)&&(time_out<100)) //检测是否发送出去
{time_out++;delayus(10);} //未发送出去 进行短暂延时
TI = 0; //清除ti标志
}
void uartSendStr(unsigned char *s,unsigned char length)
{
unsigned char NUM;
NUM=0x00;
while(NUM<length) //发送长度对比
{
uartSendByte(*s); //放松单字节数据
s++; //指针++
NUM++; //下一个++
}
}
void UART_SER (void) interrupt 4 //串行中断服务程序
{
unsigned char uart_buf;
if(RI) //判断是接收中断产生
{
RI=0; //标志位清零
uart_buf=SBUF; //读入缓冲区的值
time_buf2[uart_i]=uart_buf&0x0F;
uart_i++;
if(uart_i>=16) //连续接收16个字符信息
{
uart_i=0;
SetFlag=1; //接收完成标志位置1
}
SBUF = uart_buf; //把接收到的值再发回电脑端
}
if(TI) //如果是发送标志位,清零
TI=0;
}
/*------------------------------------------------
主程序
------------------------------------------------*/
void main()
{ music1 = 0;
InitLcd();//初始化液晶函数
//Init_DS18B20();
Ds1302_Init();
ConfigTimer0();
UART_Init();
LcdShowStr(0, 0, " Welcome ");
LcdShowStr(0, 1, " Bicycle System");
delayms(3000);
delayms(3000);
LCD_WriteCom(0x01);
uartSendStr("ready ok !",10);
music1 = 1;
while(1)
{
if(SetFlag==1) //如果接收到串口信息则更新时钟
{
for(i=0;i<8;i++)
{
time_buf1[i]=time_buf2[2*i]*10+time_buf2[2*i+1];//数据整合,如2个数 1和5整合成15
}
Ds1302_Write_Time();//接收更新的时间然后写入ds1302
SetFlag=0; //时钟信息更新后标志位清零
}
if(Signal)
{
delayms(10);
if(Signal)
{
PluNum++;
length += CIRCLE/100.0 ; //路程加一个车轮周期
}
while(Signal);
}
if(dealSuduFlag == 1)
{
speed=(uint)(CIRCLE *PluNum/2.0); //m/s
PluNum=0;
dealSuduFlag=0;
}
ReadData();//读取传感器数据
ScanContrl();//按键控制
Display(); //数据显示
WarnBuzzer();//蜂鸣器报警
}
}
具体实现截图
目 录
第1章 绪论 3
1.1本文研究背景和意义 3
1.2自行车智能辅助控制系统发展趋势 3
1.3本文研究内容 4
第2章 控制系统总体方案设计 5
2.1控制系统功能分析 5
2.2单片机芯片的选择 5
第3章 系统的硬件平台设计 6
3.1系统总体框架设计 6
3.2控制中心电路设计 6
3.2.1最小系统电路设计 6
3.2.2电源转换电路 7
3.3主要信号采集与处理电路设计 8
3.3.1霍尔测试电路设计 8
3.3.2按键电路设计 9
3.3.3 语音播放电路设计 9
3.3.4光照采集电路设计 10
3.3.5温度测量电路设计 11
3.3.6 LCD1602显示电路设计 12
3.3.7时钟电路设计 13
3.4系统总体电路设计 13
第4章 系统软件平台设计 15
4.1开发环境软件介绍 15
4.1.1 Keil简介 15
4.1.2程序在Keil中的调试 15
4.2主程序设计 16
4.3主要系统信号采集与处理程序设计 16
4.3.1 LCD1602程序设计 16
4.3.2按键检测程序设计 17
4.3.3光照强度采集程序设计 18
4.3.4温度传感器程序设计 19
第5章 硬件组装与调试 21
5.1元器件的选择与测量 21
5.2元件的焊接与组装 21
5.3电路的调试 22
5.3.1 调试方法 22
5.3.2 调试步骤 22
第6章 总结 24
致 谢 25
参考文献 26
设计获取
文章下方名片联系我即可~
精彩专栏推荐订阅:在下方专栏👇🏻
毕业设计精品实战案例
收藏关注不迷路!!
🌟文末获取设计🌟