1、404ad21ab450768737a6c64d622a560f.doc 电子科技大学中山学院 机电一体化控制器 课程设计说明书 姓 名: 学 号: 院 别: 机电工程学院 专 业: 机械设计制造及其自动化 题 目: 向“日”葵 目 录 1、 课程设计目的 4 2、 本课程设计的背景知识 4 3、 课程设计内容 4 4、 工具/准备工作 5 5、 设计步骤及原理 5 5.1 单片机控制系统原理......................................5 5.2 单片
2、机主机系统电路......................................5 5.2.1时钟电路..............................................6 5.2.2复位电路..............................................6 5.2.3按键..................................................7 5.3.1数据采集处理电路........................................7 5.3.2 红外传感器的物理摆放位置..
3、7 5.3.3 红外传感器的驱动组.....................................8 5.4温度检测电路..............................................8 5.5时钟模块..................................................9 5.6液晶模块..................................................9 5.7步进电机驱动..........................
4、9 6 系统软件设计.................................................10 6.1温度采集.................................................10 6.2电机驱动................................................ 13 6.3时钟读取................................................ 15 6.4诺基亚5110驱动........................
5、 18 6.5主程序.................................................. 24 7、 设计结果及分析 27 8、 总结及心得体会 28 9、 对本设计过程及方法、手段的改进建议 28 10、 参考文献 28 11、 评价(教师) 29 1、 课程设计目的 1) 通过正确地应用单片机或微型计算机等控制器,培养解决工业领域控制、工业检测等领域具体问题的初步能力。 2) 通过所做课题,熟悉单片微机应用系统开发、研制的过程,软硬件设计的方
6、法、工作内容、工作步骤,完成机电一体化控制器设计。 3) 加强进行基本技能训练,例如组成系统、编程、调试、查阅资料、绘图、编写说明书等;理论联系实际,提高动手能力和分析问题、解决问题的能力,训练基本的工程能力。 2、 本课程设计的背景知识 在现代,人们生活上的消费不仅仅是生活必需品上的消费,随着人们生活水平的提高,在精神娱乐、家居以及办公环境的消费比例也逐步提高。一个好的家居环境和办公环境自然能给人们带来好的心情。随着时代的进步,各种家居摆设层出不穷,一批批生活小玩意涌向市场。然而一批批的静态的摆设远远不能满足人们的需求,一些循环动作的玩意也人们也是司空见惯。本小组就想要一种智能的充满活
7、力的居家办公装饰品,向“日”葵,人就是那朵花心中的太阳。当然此作品不只是用于家居办公的摆设,也可以用于商店、酒店等用于欢迎顾客和欢送顾客的一个工具、甚至可以用于跟踪侦查及检测。 3、 课程设计内容 本论文主要研究单片机控制的向人,分别对人方向的定位以及通过电机控制花朵面向人,附加一些时间以及温度的lcd显示(如果要更进一步可以给花增加一个脾气系统);面向控制技术及系统设备的软、硬件各个部分进行了研究。 主要内容如下: 1.根据红外传感器的特点对人体所在方向进行定位。 2.通过定位所得的信息进行对步进电机的控制,使之面向人。 3. Lcd显示当前温度以及时间。 4、 工
8、具/准备工作 万用表,单片机实验板,选购人体或外传感器,单片机,三极管,诺基亚5110液晶,时钟芯片ds1302,温度芯片ds18b20杜邦线等等。 5、 设计步骤及原理 5.1 单片机控制系统原理 5.2 单片机主机系统电路 AT89C51单片机是51系列单片机的一个成员,是8051单片机的简化版。内部自带2K字节可编程FLASH存储器的低电压、高性能COMS八位微处理器,与Intel MCS-51系列单片机的指令和输出管脚相兼容。由于将多功能八位CPU和闪速存储器结合在单个芯片中,因此,AT89C2051构成的单片机系统是具有结构最简单、造价最低廉、效率最高
9、的微控制系统,省去了外部的RAM、ROM和接口器件,减少了硬件开销,节省了成本,提高了系统的性价比。 单片机系统图 5.2.1时钟电路 单片机的时钟信号用来提供单片机片内各种微操作的时间基准,时钟信号通 常用两种电路形式得到:内部振荡和外部振荡。MCS-51单片机内部有一个用于 构成振荡器的高增益反向放大器,引脚XTALl和XTAL2分别是此放大电器的输 入端和输出端,由于采用内部方式时,电路简单,所得的时钟信号比较稳定,实 际使用中常采用这种方式,如图3所示在其外接晶体振荡器(简称晶振)或陶 瓷谐振器就构成了内部振荡方式,片内高增益反向放
10、大器与作为反馈元件的片外 石英晶体或陶瓷谐振器一起可构成一个自激振荡器并产生振荡时钟脉冲。 图中外接晶体以及电容C2和C1构成并联谐振电路,它们起稳定振荡频 率、快速起振的作用,其值均为30P左右,晶振频率选12M o RESET 5.2.2复位电路 为了初始化单片机内部的某些特殊功能寄存器,必须采用复位的方式,复位 后可使CPU及系统各部件处于确定的初始状态,并从初始状态开始正常工作。 单片机的复位是靠外电路来实现的,在正常运行情况下,只要RST引脚上出现两 个机器周期时间以上的高电平,即可引起系统复位,但如果RST引脚上持续为 高电平,单片机就处于循环复
11、位状态。复位后系统将输入/输出(1/0)端口寄存 器置为FFH,堆栈指针SP置为07H, SBUF内置为不定值,其余的寄存器全部 清0,内部RAM的状态不受复位的影响,在系统上电时RAM的内容是不定的。复 位操作有两种情况,即上电复位和手动(开关)复位。本系统采用上电复位方式。 图中R9和Cl组成上电复位电路,其值R取为1KQ, C取为22uF. 5.2.3电机复位按键 电机复位按键用于电机复位初始化。 5.3.1数据采集处理电路 上图为人体红外传感器模块原理图,调节滑动电阻可以调节测量距离以及是否重复触发。 5.3.2 红外传感器的物理摆放位置 红外
12、传感器的摆放为4摆成一个正方形。用于感应人所在的方位。如图,这种摆放方式能感应出摆个方位的不同,增加传感器的数量可以感应可多方位,如图所示,在非常接近传感器的4个角的方位上要有4个盲区。但盲区非常小一般人不会如此接近传感器,所以可以忽略。 5.3.3 红外传感器的驱动组 5.4温度检测电路 Ds18b20采用一线制通信,检测的最小变化值为0.5度,是一款性价比较高的传感器。 5.5时钟模块 时钟芯片有两个电源端,一个是工作电源,一个是保存数据和掉点时工作的电源 。 5.6液晶模块 诺基亚5110是一款性价比较高的液晶显示器,操作简单。内部电路如下:
13、 采用的是单片的SPI通信,占用端口少。 5.7步进电机驱动 减速电机28BYJ-48是一个5线4向电机,采用ULM2003A驱动,8拍信号可以很精确的控制其角度。 6、 系统软件设计 6.1温度采集 sbit DQ=P1^4;//函数功能:将DS18B20传感器初始化,读取应答信号 bit Init_DS18B20(void) {bit flag; //储存DS18B20是否存在的标志,flag=0,表示存在;flag=1,DQ = 1; //先将数据线拉高 for(time=0;time<2;time++); //略微
14、延时约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++); //延时足够长时间,等待存在脉冲输出完
15、毕 return (flag); //返回检测成功标志 }//函数功能:从DS18B20读取一个字节数据 unsigned char ReadOneChar(void) { unsigned char i=0; unsigned char dat; //储存读出的一个字节数据 for (i=0;i<8;i++) { DQ =1; _nop_(); // 先将数据线拉高 //等待一个机 DQ = 0; _nop_(); //单片机从DS18B20读书据时,将数据线从 DQ = 1; /
16、/将数据线"人为"拉高,为单片机检测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);
17、 //返回读出的十六进制数据 } //函数功能:向DS18B20写入一个字节数据 WriteOneChar(unsigned char dat) { unsigned char i=0; for (i=0; i<8; i++) { DQ =1; _nop_(); // 先将数据线拉高 DQ=0; //将数据线从高拉低时即启动写时序 DQ=dat&0x01; //利用与运算取出要写的某位二进制数据, for(time=0;time<10;time++) ;//延时约
18、30us, DQ=1; //释放数据线 for(time=0;time<1;time++) ;//延时3us,两个写时序间至少需要1us的恢 dat>>=1; //将dat中的各二进制位数据右移1位 } for(time=0;time<4;time++); //稍作延时,给硬件一点反应时间 } //函数功能:做好读温度的准备 void ReadyReadTemp(void) { Init_DS18B20(); //将DS18B20初始化 WriteOneChar(0xCC
19、); // 跳过读序号列号的操作 WriteOneChar(0x44); // 启动温度转换 ys(200); //转换一次需要延时一段时间 Init_DS18B20(); //将DS18B20初始化 WriteOneChar(0xCC); //跳过读序号列号的操作 WriteOneChar(0xBE); //读取温度寄存器,前两个分别是温度的低位和高 } char dwd() //读取温度,返回温度值 { char wd; unsigned char TL,TH,TN,TD; //储存暂存器的
20、温度低位 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
21、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; return wd; //(wd%1)*10为小数位 } 6.2电机驱动 unsigned char dj[]={0x08
22、0x0c,0x04,0x06,0x02,0x03,0x01,0x09}; void ys(unsigned int z) { unsigned int x; unsigned int y; for(x=z;x>0;x--) for(y=114;y>0;y--); } // 电机程序 void djzd(unsigned char k,bit c) //转过的角度=K*16*360/128,c代表正反转 { unsigned char i,j,temp; if(c==1) { for(j=0;j<(k*16);j++) for(i=0
23、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时钟读取 sbit rst=P3^7; sbit clk=P3^3; sbit din=P3^4; //函数功能:延时若干微秒 void delaynus(unsigned char n) { unsigned char
24、 i;
for(i=0;i 25、
SCLK=1; delaynus(2); //上升沿写入数据
SCLK=0; //重新拉低SCLK,形成脉冲
dat>>=1; //将dat的各数据位右移1位,准备写入下一个数
}
}
//函数功能:根据命令字,向1302写一个字节数据
void WriteSet1302(unsigned char Cmd,unsigned char dat)
{
RST=0; //禁止数据传递
SCLK=0; // 26、确保写数居前SCLK被拉低
RST=1; delaynus(2); //启动数据传输 Write1302(Cmd); //写入命令字
Write1302(dat); //写数据
SCLK=1; //将时钟电平置于高电平状态
RST=0; //禁止数据传递
}
//函数功能:从1302读一个字节数据
unsigned char Read1302(void)
{
unsigned char i,dat;
delaynus(2); 27、 //稍微等待,使硬件做好准备
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;
return i; //将 28、读出的数据返回
}
//函数功能:根据命令字,从1302读取一个字节数据
unsigned char ReadSet1302(unsigned char Cmd)
{
unsigned char dat;
RST=0; //拉低RST
SCLK=0; //确保写数居前SCLK被拉低
RST=1; //启动数据传输
Write1302(Cmd); //写入命令字
dat=Read1302(); //读出数据
SCLK=1; 29、 //将时钟电平置于已知状态
RST=0; //禁止数据传递
return dat; //将读出的数据返回
}
/*****************************************************
函数功能: 1302进行初始化设置
***************************************************/
void Init_DS1302(void)
{
unsigned char flag;
WriteSet1302(0 30、x8E,0x00); //根据写状态寄存器命令字,
WriteSet1302(0x80,0x30); //根据写秒寄存器命令字,写入秒的初始值
WriteSet1302(0x82,0x17); //根据写分寄存器命令字,写入分的初始值
WriteSet1302(0x84,0x08); //根据写小时寄存器命令字,写入小时的初始值
WriteSet1302(0x86,0x01); //根据写日寄存器命令字,写入日的初始值
WriteSet1302(0x88,0x07); //根据写月寄存器命令字,写入月的初始值
WriteSe 31、t1302(0x8c,0x13); //根据写年寄存器命令字,写入年的初始值
WriteSet1302(0x8a,0x1); //根据写年寄存器命令字,写入年的初始值
WriteSet1302(0x90,0xa5); //打开充电功能 选择2K电阻充
WriteSet1302(0x8E,0x80); //根据写状态寄存器命令字,写入保
}
6.4诺基亚5110驱动
sbit rst=P3^7;
sbit clk=P3^3;
sbit din=P3^4;
sbit DQ=P1^4;
sbit SCLK=P2^6; //位定 32、义1302芯片的接口,时钟输出端口定义在P1.0引脚
sbit DATA=P2^5; //位定义1302芯片的接口,数据输出端定义在P1.1引脚
sbit RST=P2^4; //位定义1302芯片的接口,复位端口定义在P1.2引脚
void delay_1us(void)
{
unsigned int i;
for(i=0;i<1000;i++);
}
void xdc(unsigned char dcc,bit k) //K=0写命令,k=1写数据
{
unsigned char i;
ce= 33、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; //写入完成后禁止写入
}
void LCD_clear(void)
{
unsigned int i;
xdc(0x0c,0) 34、
xdc(0x80, 0);
for (i=0; i<504; i++)
xdc(0, 1);
}
//函数功能:5110初始化
void csh5110(void)
{
rst=0; // 产生一个让LCD复位的低电平脉冲
delay_1us();
rst=1;
ce=0; // 关闭LCD
delay_1us();
ce=1; // 使能LCD
delay_1us();
xdc(0x21, 0); // 使用扩展命令设置LCD模式
35、 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坐标函数
void LCD_set_XY(unsigned char X, unsigned char Y) 36、
{
xdc(0x40 | Y, 0); // column
xdc(0x80 | X, 0); // row
}
//函数功能:显示英文字符
void LCD_write_char(unsigned char c,unsigned char h,unsigned char l)
{
unsigned char line;
c=c-32;
LCD_set_XY(h,l);
for (line=0;line<6;line++)
xdc(zfb[c][line],1);
}
//显示小四汉字 37、
void hz(unsigned char *c,unsigned char h,unsigned char l)
{
unsigned char line;
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);
}
//显示小五汉字
void xshz(unsigned char *c,unsigned cha 38、r h,unsigned char l)
{
unsigned char line;
LCD_set_XY(h,l);
for (line=0;line<12;line++)
xdc(c[line],1);
LCD_set_XY(h,l+1);
for (line=12;line<24;line++)
xdc(c[line],1);
}
//整个屏幕显示
void display(uchar n,uchar y,uchar r,uchar s,uchar f,uchar z,char wd)
{
unsi 39、gned char ka;
hz(zhou1,0,0);
hz(xingqi+(z-1)*32,16,0);
ka=n/10;
LCD_write_char(ka+48,32,0);
ka=n%10;
LCD_write_char(ka+48,38,0);
LCD_write_char('/',44,0);
ka=y/10;
LCD_write_char(ka+48,50,0);
ka=y%10;
LCD_write_char(ka+48,56,0);
LCD_write_char('/',62,0);
ka 40、r/10;
LCD_write_char(ka+48,68,0);
ka=r%10;
LCD_write_char(ka+48,74,0);
ka=s/10;
LCD_write_char(ka+48,32,1);
ka=s%10;
LCD_write_char(ka+48,38,1);
LCD_write_char(':',44,1);
ka=f/10;
LCD_write_char(ka+48,50,1);
ka=f%10;
LCD_write_char(ka+48,56,1);
if(wd 41、<0)
{
LCD_write_char('-',48,5);
wd=-wd;
}
ka=wd/10;
LCD_write_char(ka+48,60,5);
ka=wd%10;
LCD_write_char(ka+48,66,5);
LCD_write_char('C',78,5);
LCD_write_char(124,72,5);
xshz(hai,0,2);
xshz(fu,12,2);
xshz(wei,26,2);
xshz(xiong,38,2);
xshz(wei 42、52,2);
xshz(jun,64,2);
xshz(xiang,0,4);
xshz(ri,12,4);
xshz(kui,24,4);
}
////////////////////////////////////
6.5主程序
void main()
{
csh5110(); //液晶初始化
ReadyReadTemp(); //温度初始化
Init_DS1302();
dusj();
display(n,y,r,s,f,z,wd1);
IT0=1;
E 43、X0=1;
EA=1;
while(1)
{
if(ks)
{
dusj();
display(n,y,r,s,f,z,wd1);
a1=P2&0x0f;
P3=P2;
for(i2=0;i2<14;i2++) //查表找出人的方位,0初始位置,1+ 45度 {
if(biao[i2]==a1)
break;
}
a2=i2;
if(a2<14) //则有人
{
44、 if(a2>=8&&a<=11)
a2=(a2-8)*2;
else if(a2>=12)
a2=(a2-12)*6;
else
a2=a2;
a2=a2+8;
switch(a2-a)
{
case 1:djzd(1,0);a2=a2-8; a=a2;break;
case 2: djzd(2,0);a2=a2-8; a=a2; break;
case 3: djzd(3,0);a2=a2-8; a=a2; 45、break;
case 4: djzd(4,0);a2=a2-8; a=a2; break;
case 5: djzd(3,1); a2=a2-8; a=a2; break;
case 6: djzd(2,1); a2=a2-8; a=a2;break;
case 7: djzd(1,1); a2=a2-8; a=a2; break;
case 8: break;
case 9: djzd(1,0); a2=a2-8; a=a2; break;
case 10: djzd(2,0);a2=a2-8 46、 a=a2; break;
case 11: djzd(3,0);a2=a2-8; a=a2; break;
case 12: djzd(4,0); a2=a2-8; a=a2; break;
case 13: djzd(3,1); a2=a2-8; a=a2;break;
case 14: djzd(2,1); a2=a2-8; a=a2; break;
case 15: djzd(1,1);a2=a2-8; a=a2; break;
default:break;
}}} }}
voi 47、d aaaa() interrupt 0 //电机位置初始化程序
{
unsigned char i1;
while(!p32)
{
for(i1=0;i1<8;i1++)
{
P1=dj[i1];
ys(5);
}
}
ks=1;
EA=0; }
7、 设计结果及分析
设计结果,电机在初始化位置后能根据人体红外传感器检测出人的位置从而改变转向并面向人。由于传感器模块的电路决定了红外传感器在感应人体进入区域时有最低5S的输出时间,造成单片机判断上有一定的困 48、难,在人体方位确定下来后单片机能在5s后对人的位置能有个准确的判断,在传感器输出结束后有一个封存时间,这封存时间是红外传感器应用的一个很大的优点,其最初目的是为了减少干扰,但在这里的应用确成为了一个缺点。对人位置的判断也通过程序对人的判断得到一定的改良,但是仍不能消除传感器自身特性的影响。传感器摆放成一个正方形,能测出八方人的位置,由于他120度以上的检测角决定了4个传感器的摆放位置以及检测方向的多少。
诺记5110显示当前的温度时间,诺基亚5110液晶显示了时钟芯片的年月日分时周,但是没有显示秒,因为电机不是一种快速反应的的器件,在电机转动工程中有可能存在超过1s的转动,所以秒的显示在 49、这里会出现一定的误差,意义不大。文字的显示在此程序有两种字体,一种的小四(16*16),一种是小五(12*12),
数字及符号的显示采用(6*8)的字符 。这样在排版上具能跟美观,而且比较标准,降低的程序的复杂性。
温度传感器DS18B20是一总线通信,对时间要求比较严格,不同的晶振在通信时要在程序改下不同的数据。
8、 总结心得和体会
通过本学期的单片机课程设计学习研究,从而了解到,首先要有自己小组上独特创意上的设计,要切合自身的实践能力不过高要求自己且严格约束自己。为更好的将理论教学与实践相结合,成功完成试验要求,需要我们对单片机应用系统设计的各 50、种方法有所了解,通过小组成员之间的兴趣进行分工合作,培养成员之间的合作精神,节省时间更大效益的完成。熟悉电子系统设计的全过程;提高对设计课题的分析能力、编程能力及解决实际问题的综合能力。通过本次课程实际的学习,让我们了解到的自身的一些不足。对于基础知识掌握的不够牢固,特别是对于单片机的前项结构设计应用理解及程序编写的不够,反映出模拟电路掌握的不好;对外界硬件认识和市场不了解,使得前期选择硬件有些分歧;在学习中实践少,导致完成设计过程中,动手能力差,时常在一些细节方面有失误;基础知识不够扎实,导致在程序编写上,常常遇到问题。通过本次试验,根据实践得出问题是做系统的一个很重要的能力,善于对程序运行






