基于单片机的创新《向日葵》课程设计说明书.docx
《基于单片机的创新《向日葵》课程设计说明书.docx》由会员分享,可在线阅读,更多相关《基于单片机的创新《向日葵》课程设计说明书.docx(34页珍藏版)》请在冰豆网上搜索。
![基于单片机的创新《向日葵》课程设计说明书.docx](https://file1.bdocx.com/fileroot1/2023-2/1/d2c1afa1-c202-4a5e-89ac-334334dee1e1/d2c1afa1-c202-4a5e-89ac-334334dee1e11.gif)
基于单片机的创新《向日葵》课程设计说明书
电子科技大学中山学院
机电一体化控制器
课程设计说明书
姓名:
学号:
院别:
机电工程学院
专业:
机械设计制造及其自动化
题目:
向“日”葵
5.2单片机主机系统电路......................................5
5.2.1时钟电路..............................................6
5.2.2复位电路..............................................6
5.2.3按键..................................................7
5.3.1数据采集处理电路........................................7
5.3.2红外传感器的物理摆放位置...............................7
5.3.3红外传感器的驱动组.....................................8
5.4温度检测电路..............................................8
5.5时钟模块..................................................9
5.6液晶模块..................................................9
5.7步进电机驱动..............................................9
6系统软件设计.................................................10
6.1温度采集.................................................10
6.2电机驱动................................................13
6.3时钟读取................................................15
6.4诺基亚5110驱动.........................................18
6.5主程序..................................................24
1、课程设计目的
1)通过正确地应用单片机或微型计算机等控制器,培养解决工业领域控制、工业检测等领域具体问题的初步能力。
2)通过所做课题,熟悉单片微机应用系统开发、研制的过程,软硬件设计的方法、工作内容、工作步骤,完成机电一体化控制器设计。
3)加强进行基本技能训练,例如组成系统、编程、调试、查阅资料、绘图、编写说明书等;理论联系实际,提高动手能力和分析问题、解决问题的能力,训练基本的工程能力。
2、本课程设计的背景知识
在现代,人们生活上的消费不仅仅是生活必需品上的消费,随着人们生活水平的提高,在精神娱乐、家居以及办公环境的消费比例也逐步提高。
一个好的家居环境和办公环境自然能给人们带来好的心情。
随着时代的进步,各种家居摆设层出不穷,一批批生活小玩意涌向市场。
然而一批批的静态的摆设远远不能满足人们的需求,一些循环动作的玩意也人们也是司空见惯。
本小组就想要一种智能的充满活力的居家办公装饰品,向“日”葵,人就是那朵花心中的太阳。
当然此作品不只是用于家居办公的摆设,也可以用于商店、酒店等用于欢迎顾客和欢送顾客的一个工具、甚至可以用于跟踪侦查及检测。
3、课程设计内容
本论文主要研究单片机控制的向人,分别对人方向的定位以及通过电机控制花朵面向人,附加一些时间以及温度的lcd显示(如果要更进一步可以给花增加一个脾气系统);面向控制技术及系统设备的软、硬件各个部分进行了研究。
主要内容如下:
1.根据红外传感器的特点对人体所在方向进行定位。
2.通过定位所得的信息进行对步进电机的控制,使之面向人。
3.Lcd显示当前温度以及时间。
4、工具/准备工作
万用表,单片机实验板,选购人体或外传感器,单片机,三极管,诺基亚5110液晶,时钟芯片ds1302,温度芯片ds18b20杜邦线等等。
5、设计步骤及原理
5.1单片机控制系统原理
5.2单片机主机系统电路
AT89C51单片机是51系列单片机的一个成员,是8051单片机的简化版。
内部自带2K字节可编程FLASH存储器的低电压、高性能COMS八位微处理器,与IntelMCS-51系列单片机的指令和输出管脚相兼容。
由于将多功能八位CPU和闪速存储器结合在单个芯片中,因此,AT89C2051构成的单片机系统是具有结构最简单、造价最低廉、效率最高的微控制系统,省去了外部的RAM、ROM和接口器件,减少了硬件开销,节省了成本,提高了系统的性价比。
单片机系统图
5.2.1时钟电路
单片机的时钟信号用来提供单片机片内各种微操作的时间基准,时钟信号通
常用两种电路形式得到:
内部振荡和外部振荡。
MCS-51单片机内部有一个用于
构成振荡器的高增益反向放大器,引脚XTALl和XTAL2分别是此放大电器的输
入端和输出端,由于采用内部方式时,电路简单,所得的时钟信号比较稳定,实
际使用中常采用这种方式,如图3所示在其外接晶体振荡器(简称晶振)或陶
瓷谐振器就构成了内部振荡方式,片内高增益反向放大器与作为反馈元件的片外
石英晶体或陶瓷谐振器一起可构成一个自激振荡器并产生振荡时钟脉冲。
图中外接晶体以及电容C2和C1构成并联谐振电路,它们起稳定振荡频
率、快速起振的作用,其值均为30P左右,晶振频率选12Mo
RESET
5.2.2复位电路
为了初始化单片机内部的某些特殊功能寄存器,必须采用复位的方式,复位
后可使CPU及系统各部件处于确定的初始状态,并从初始状态开始正常工作。
单片机的复位是靠外电路来实现的,在正常运行情况下,只要RST引脚上出现两
个机器周期时间以上的高电平,即可引起系统复位,但如果RST引脚上持续为
高电平,单片机就处于循环复位状态。
复位后系统将输入/输出(1/0)端口寄存
器置为FFH,堆栈指针SP置为07H,SBUF内置为不定值,其余的寄存器全部
清0,内部RAM的状态不受复位的影响,在系统上电时RAM的内容是不定的。
复
位操作有两种情况,即上电复位和手动(开关)复位。
本系统采用上电复位方式。
图中R9和Cl组成上电复位电路,其值R取为1KQ,C取为22uF.
5.2.3电机复位按键
电机复位按键用于电机复位初始化。
5.3.1数据采集处理电路
上图为人体红外传感器模块原理图,调节滑动电阻可以调节测量距离以及是否重复触发。
5.3.2红外传感器的物理摆放位置
红外传感器的摆放为4摆成一个正方形。
用于感应人所在的方位。
如图,这种摆放方式能感应出摆个方位的不同,增加传感器的数量可以感应可多方位,如图所示,在非常接近传感器的4个角的方位上要有4个盲区。
但盲区非常小一般人不会如此接近传感器,所以可以忽略。
5.3.3红外传感器的驱动组
5.4温度检测电路
Ds18b20采用一线制通信,检测的最小变化值为0.5度,是一款性价比较高的传感器。
5.5时钟模块
时钟芯片有两个电源端,一个是工作电源,一个是保存数据和掉点时工作的电源。
5.6液晶模块
诺基亚5110是一款性价比较高的液晶显示器,操作简单。
内部电路如下:
采用的是单片的SPI通信,占用端口少。
5.7步进电机驱动
减速电机28BYJ-48是一个5线4向电机,采用ULM2003A驱动,8拍信号可以很精确的控制其角度。
6、系统软件设计
6.1温度采集
sbitDQ=P1^4;//函数功能:
将DS18B20传感器初始化,读取应答信号
bitInit_DS18B20(void)
{bitflag;//储存DS18B20是否存在的标志,flag=0,表示存在;flag=1,DQ=1;//先将数据线拉高
for(time=0;time<2;time++);//略微延时约6微秒
DQ=0;//再将数据线从高拉低,要求保持480~960us
for(time=0;time<200;time++);//略微延时约600微秒
DQ=1;//释放数据线(将数据线拉高)
for(time=0;time<10;time++);//延时约30us(释放总线后需等待15~60us让
flag=DQ;//让单片机检测是否输出了存在脉冲(DQ=0表示存在)
for(time=0;time<200;time++);//延时足够长时间,等待存在脉冲输出完毕return(flag);//返回检测成功标志
}//函数功能:
从DS18B20读取一个字节数据
unsignedcharReadOneChar(void)
{
unsignedchari=0;
unsignedchardat;//储存读出的一个字节数据
for(i=0;i<8;i++)
{
DQ=1;_nop_();//先将数据线拉高//等待一个机DQ=0;_nop_();//单片机从DS18B20读书据时,将数据线从
DQ=1;//将数据线"人为"拉高,为单片机检测DS18B20的输出
for(time=0;time<2;time++);//延时约6us,使主机在15us内采样
dat>>=1;
if(DQ==1)
dat|=0x80;//如果读到的数据是1,则将1存入dat
else
dat|=0x00;//如果读到的数据是0,则将0存入dat
for(time=0;time<8;time++);//延时3us,两个读时序之间
}
return(dat);//返回读出的十六进制数据
}
//函数功能:
向DS18B20写入一个字节数据
WriteOneChar(unsignedchardat)
{
unsignedchari=0;
for(i=0;i<8;i++)
{
DQ=1;_nop_();//先将数据线拉高
DQ=0;//将数据线从高拉低时即启动写时序
DQ=dat&0x01;//利用与运算取出要写的某位二进制数据,
for(time=0;time<10;time++);//延时约30us,
DQ=1;//释放数据线
for(time=0;time<1;time++);//延时3us,两个写时序间至少需要1us的恢
dat>>=1;//将dat中的各二进制位数据右移1位
}
for(time=0;time<4;time++);//稍作延时,给硬件一点反应时间
}
//函数功能:
做好读温度的准备
voidReadyReadTemp(void)
{
Init_DS18B20();//将DS18B20初始化
WriteOneChar(0xCC);//跳过读序号列号的操作
WriteOneChar(0x44);//启动温度转换
ys(200);//转换一次需要延时一段时间
Init_DS18B20();//将DS18B20初始化
WriteOneChar(0xCC);//跳过读序号列号的操作
WriteOneChar(0xBE);//读取温度寄存器,前两个分别是温度的低位和高
}
chardwd()//读取温度,返回温度值
{
charwd;
unsignedcharTL,TH,TN,TD;//储存暂存器的温度低位
flag=0;
ReadyReadTemp();//读温度准备
TL=ReadOneChar();//先读的是温度值低位
TH=ReadOneChar();//接着读的是温度值高位
if((TH&0xf8)!
=0x00)//判断高五位得到温度正负标志
{
flag=1;
TL=~TL;//取反
TH=~TH;//取反
tltemp=TL+1;//低位加1
TL=tltemp;
if(tltemp>255)TH++;//如果低8位大于255,向高8位进1
TN=TH*16+TL/16;//实际温度值=(TH*256+TL)/16,即:
TD=(TL%16)*10/16;//计算温度的小数部分,
}
TN=TH*16+TL/16;//实际温度值=(TH*256+TL)/16,即:
TD=(TL%16)*10/16;//计算温度的小数部分,将余数乘以10再除以16
wd=TN+TD/10.0;
if(flag==1)
wd=-wd;
returnwd;//(wd%1)*10为小数位
}
6.2电机驱动
unsignedchardj[]={0x08,0x0c,0x04,0x06,0x02,0x03,0x01,0x09};
voidys(unsignedintz)
{
unsignedintx;
unsignedinty;
for(x=z;x>0;x--)
for(y=114;y>0;y--);
}
//电机程序
voiddjzd(unsignedchark,bitc)//转过的角度=K*16*360/128,c代表正反转
{
unsignedchari,j,temp;
if(c==1)
{for(j=0;j<(k*16);j++)
for(i=0;i<8;i++)
{
P1=dj[i];
ys(5);
}
}
Else
{
for(j=0;j<(k*16);j++)
for(i=8;i>0;i--)
{
temp=i-1;
P1=dj[temp];
ys(5);
}
}
}
6.3时钟读取
sbitrst=P3^7;
sbitclk=P3^3;
sbitdin=P3^4;
//函数功能:
延时若干微秒
voiddelaynus(unsignedcharn)
{
unsignedchari;
for(i=0;i}
//函数功能:
向1302写一个字节数据
voidWrite1302(unsignedchardat)
{
unsignedchari;
SCLK=0;//拉低SCLK,为脉冲上升沿写入数据做好准备
delaynus
(2);//稍微等待,使硬件做好准备
for(i=0;i<8;i++)//连续写8个二进制位数据
{
DATA=dat&0x01;delaynus
(2);//取出dat的第0位数据写入1302
SCLK=1;delaynus
(2);//上升沿写入数据
SCLK=0;//重新拉低SCLK,形成脉冲
dat>>=1;//将dat的各数据位右移1位,准备写入下一个数
}
}
//函数功能:
根据命令字,向1302写一个字节数据
voidWriteSet1302(unsignedcharCmd,unsignedchardat)
{
RST=0;//禁止数据传递
SCLK=0;//确保写数居前SCLK被拉低
RST=1;delaynus
(2);//启动数据传输Write1302(Cmd);//写入命令字
Write1302(dat);//写数据
SCLK=1;//将时钟电平置于高电平状态
RST=0;//禁止数据传递
}
//函数功能:
从1302读一个字节数据
unsignedcharRead1302(void)
{
unsignedchari,dat;
delaynus
(2);//稍微等待,使硬件做好准备
for(i=0;i<8;i++)//连续读8个二进制位数据
{dat>>=1;
if(DATA==1)//如果读出的数据是1
dat|=0x80;//将1取出,写在dat的最高位
SCLK=1;delaynus
(2);//将SCLK置于高电平,为下降沿读出
SCLK=0;delaynus
(2);//拉低SCLK,形成脉冲下降沿
}
i=dat/16;
i=i*10+dat%16;
returni;//将读出的数据返回
}
//函数功能:
根据命令字,从1302读取一个字节数据
unsignedcharReadSet1302(unsignedcharCmd)
{
unsignedchardat;
RST=0;//拉低RST
SCLK=0;//确保写数居前SCLK被拉低
RST=1;//启动数据传输
Write1302(Cmd);//写入命令字
dat=Read1302();//读出数据
SCLK=1;//将时钟电平置于已知状态
RST=0;//禁止数据传递
returndat;//将读出的数据返回
}
/*****************************************************
函数功能:
1302进行初始化设置
***************************************************/
voidInit_DS1302(void)
{
unsignedcharflag;
WriteSet1302(0x8E,0x00);//根据写状态寄存器命令字,
WriteSet1302(0x80,0x30);//根据写秒寄存器命令字,写入秒的初始值
WriteSet1302(0x82,0x17);//根据写分寄存器命令字,写入分的初始值
WriteSet1302(0x84,0x08);//根据写小时寄存器命令字,写入小时的初始值
WriteSet1302(0x86,0x01);//根据写日寄存器命令字,写入日的初始值
WriteSet1302(0x88,0x07);//根据写月寄存器命令字,写入月的初始值
WriteSet1302(0x8c,0x13);//根据写年寄存器命令字,写入年的初始值
WriteSet1302(0x8a,0x1);//根据写年寄存器命令字,写入年的初始值
WriteSet1302(0x90,0xa5);//打开充电功能选择2K电阻充
WriteSet1302(0x8E,0x80);//根据写状态寄存器命令字,写入保
}
6.4诺基亚5110驱动
sbitrst=P3^7;
sbitclk=P3^3;
sbitdin=P3^4;
sbitDQ=P1^4;
sbitSCLK=P2^6;//位定义1302芯片的接口,时钟输出端口定义在P1.0引脚
sbitDATA=P2^5;//位定义1302芯片的接口,数据输出端定义在P1.1引脚
sbitRST=P2^4;//位定义1302芯片的接口,复位端口定义在P1.2引脚
voiddelay_1us(void)
{
unsignedinti;
for(i=0;i<1000;i++);
}
voidxdc(unsignedchardcc,bitk)//K=0写命令,k=1写数据
{
unsignedchari;
ce=0;//片选选通
if(k==0)//命令
dc=0;
else
dc=1;//数据
for(i=0;i<8;i++)
{
if(dcc&0x80)
din=1;
else
din=0;
clk=0;
dcc=dcc<<1;//放在这里的主要原因是等待一点时间
clk=1;
}
ce=1;//写入完成后禁止写入
}
voidLCD_clear(void)
{
unsignedinti;
xdc(0x0c,0);
xdc(0x80,0);
for(i=0;i<504;i++)
xdc(0,1);
}
//函数功能:
5110初始化
voidcsh5110(void)
{
rst=0;//产生一个让LCD复位的低电平脉冲
delay_1us();
rst=1;
ce=0;//关闭LCD
delay_1us();
ce=1;//使能LCD
delay_1us();
xdc(0x21,0);//使用扩展命令设置LCD模式
xdc(0xBF,0);//设置液晶偏置电压可调节屏幕的对比度
xdc(0x06,0);//温度校正
xdc(0x13,0);//1:
48
xdc(0x20,0);//使用基本命令,V=0,水平寻址
LCD_clear();//清屏
xdc(0x0c,0);//设定显示模式,正常显示
ce=0;//关闭LCD
}
//函数功能:
设置LCD坐标函数
voidLCD_set_XY(unsignedcharX,unsignedcharY)
{
xdc(0x40|Y,0);//column
xdc(0x80|X,0);//row
}
//函数功能:
显示英文字符
voidLCD_write_char(unsignedcharc,unsignedcharh,unsignedcharl)
{
unsignedcharline;
c=c-32;
LCD_set_XY(h,l);
for(line=0;line<6;line++)
xdc(zfb[c][line],1);
}
//显示小四汉字
voidhz(unsignedchar*c,unsignedcharh,unsignedcharl)
{
unsignedcharline;
LCD_set_XY(h,l);
for(line=0;line<16;line++)
xdc(c[line],1);
LCD_set_XY(h,l+1);
for(line=16;line<32;line++)
xdc(c[line],1);
}
//显示小五汉字
voidxshz(unsignedchar*c,unsignedcharh,unsignedcharl)
{
unsignedcharline;
LCD_set_XY