自动打铃控制器资料.docx
- 文档编号:23656587
- 上传时间:2023-05-19
- 格式:DOCX
- 页数:37
- 大小:171.32KB
自动打铃控制器资料.docx
《自动打铃控制器资料.docx》由会员分享,可在线阅读,更多相关《自动打铃控制器资料.docx(37页珍藏版)》请在冰豆网上搜索。
自动打铃控制器资料
第1章引言
单片机又称单片微控制器,它不是完成某一个逻辑功能的芯片,而是把一个计算机系统集成到一个芯片上。
相当于一个微型的计算机,和计算机相比,单片机只缺少了I/O设备。
概括的讲:
一块芯片就成了一台计算机。
它的体积小、质量轻、价格便宜、为学习、应用和开发提供了便利条件。
同时,学习使用单片机是了解计算机原理与结构的最佳选择。
单片机内部也用和电脑功能类似的模块,比如CPU,内存,并行总线,还有和硬盘作用相同的存储器件,不同的是它的这些部件性能都相对我们的家用电脑弱很多,不过价钱也是低的,一般不超过10元即可用它来做一些控制电器一类不是很复杂的工作足矣了。
我们现在用的全自动滚筒洗衣机、排烟罩、VCD等等的家电里面都可以看到它的身影!
它主要是作为控制部分的核心部件。
可以说,二十世纪跨越了三个“电”的时代,即电气时代、电子时代和现已进入的电脑时代。
不过,这种电脑,通常是指个人计算机,简称PC机。
它由主机、键盘、显示器等组成。
还有一类计算机,大多数人却不怎么熟悉。
这种计算机就是把智能赋予各种机械的单片机(亦称微控制器)。
顾名思义,这种计算机的最小系统只用了一片集成电路,即可进行简单运算和控制。
因为它体积小,通常都藏在被控机械的“肚子”里。
它在整个装置中,起着有如人类头脑的作用,它出了毛病,整个装置就瘫痪了。
现在,这种单片机的使用领域已十分广泛,如产品未使用单片机或其它可编程逻辑器件上智能控制、实时工控、通讯设备、导航系统、家用电器等。
各种产品一旦用上了单片机,就能起到使产品升级换代的功效,常在产品名称前冠以形容词——“智能型”,如智能型洗衣机等。
今天我利用单片机控制学校的打铃系统,下面是我的设计思路
第2章设计要求
用单片机、数字温度传感器、实时时钟芯片、点阵液晶模块设计一个简易的自动打铃系统,系统工作时,在LCD显示器的第一行用16×16点阵的汉字显示“自动打铃系统”,第二行显示当前时间,第三行显示当前温度值,在随后的四行显示一页最近的打铃时间,即将要打铃的时间用黑底白字显示,如果该页的最后一个时间打过铃后,自动翻页,将下一页的4个打铃时间显示出来;用户可以通过按键修改当前时间或打铃时间;用户可以通过按指定键获知各键的功能。
总体设计思想
用TG12864B液晶模拟块设计一个简易的自动打铃系统,系统正常工作是,在LCD显示器的第一行用16*16的点阵的汉字显示“自动打铃系统”,第二行显示当前时间,第三行显示当前温度,在随后的四行显示一页的最近的打铃时间,即将要打铃的时间用黑底白字显示,如果该页的最后一个时间打过铃后,自动翻页,将下一个的4个打铃时间显示出来;用户可以通过按键修改当前时间或打铃时间。
利用KDOWN键进入HELP功能;打铃时用音乐声代替。
第3章硬件电路设计
分析:
自动打铃系统的本质就是电子钟,如果当前的时间与打铃时间相同,就控制蜂鸣器发出打铃声。
虽然利用单片机本身的定时器也能够实现走时功能,但精度不够高,程序也比较复杂,而实时时钟芯片PCF8563能够轻松的解决以上问题。
由于打铃时间可能多达数十个,如果用户设置完打铃时间后将其保存在片内RAM中,一旦断电或重新启动,打铃时间又必须重新设置,为此可利用串行E²PROM器件24C02来保存打铃时间。
另外用4个按键来设置当前时间和打铃时间。
系统正常工作时,按KDOWN键进入帮助菜单;按KSET键进入当前时间的设置,长按KSET键则进入打铃时间的设置;进入设置方式后,按KSET键移动光标,用黑底白字指示当前正在修改的时、分、秒,KINC,KDEC键分别对当前的修改对象加、减1,如果是修改的打铃时间,用KDOWN键对下一个打铃时间进行设置,长按KSET键退出当前时间或打铃时间的设置方式,回到正常状态。
电子钟是一个以“分”,“秒”显示于人的视觉器官的计时装置。
它的计时周期为24小时,显示满刻度为23时59分59秒,另外应有校时功能和一些显示星期、报时、停电查看时间等附加功能。
因此,一个基本的数字钟电路主要由译码显示器、“时”,“分”,“秒”,“星期”计数器、校时电路、报时电路和振荡器组成。
干电路系统由秒信号发生器、“时、分、秒、星期”计数器、译码器及显示器、校时电路、整点报时电路组成。
秒信号产生器是整个系统的时基信号,它直接决定计时系统的精度,一般用石英晶体振荡器加分频器来实现。
将标准秒信号送入“秒计数器”,“秒计数器”采用60进制计数器,每累计60秒发出一个“分脉冲”信号,该信号将作为“分计数器”的时钟脉冲。
“分计数器”也采用60进制计数器,每累计60分钟,发出一个“时脉冲”信号,该信号将被送到“时计数器”。
“时计数器”采用24进制计时器,可实现对一天24小时的累计。
每累计24小时,发出一个“星期脉冲”信号,该信号将被送到“星期计数器”,“星期计数器” 采用7进制计时器,可实现对一周7天的累计。
译码显示电路将“时”、“分”、“秒”、“星期”计数器的输出状态送到七段显示译码器译码,通过七位LED七段显示器显示出来。
整点报时电路时根据计时系统的输出状态产生一脉冲信号,然后去触发一音频发生器实现报时。
校时电路时用来对“时”、“分”、“秒”、“星期”显示数字进行校对调整的。
晶振用一种能把电能和机械能相互转化的晶体在共振的状态下工作,以提供稳定,精确的单频振荡。
在通常工作条件下,普通的晶振频率绝对精度可达百万分之五十。
高级的精度更高。
有些晶振还可以由外加电压在一定范围内调整频率,称为压控振荡器(VCO)
晶体振荡器电路给数字钟提供一个频率稳定准确的32768Hz的方波信号,此外还有一校正电容可以对温度进行补偿,以提高频率准确度和稳定度,使稳定度优于10-4,可保证数字钟的走时准确及稳定,下面我画出硬件电路图
硬件电路图
3.1PCB图
PCB电路图
3.2程序流程图
3.3程序清单
文件I2C.C的清单如下:
#include
#include
#defineucharunsignedchar
#definedelay1us()_nop_()
#definedelay5us()_nop_();_nop_();_nop_();_nop_();_nop_()
sbitSDA=P1^7;//P1.1模拟I2C总线的SDA
sbitSCL=P1^6;//P1.0模拟I2C总线的SCL
bitack_mk;//应答标志位,有应答为1,无应答为0
voidStart()/始信号/产生起
{
SDA=1;//将SDA、SCL置为1
SCL=1;
delay5us();//起始条件建立时间大于4.7us,故延时5us
SDA=0;//SCL为高时,SDA由高变低,发送起始信号
delay5us();//延时5us
SCL=0;//SCL变低,准备发送或接收数据
}
voidStop()//产生停止信号
{
SDA=0;//将SDA清0,SCL置1
SCL=1;
delay5us();//结束条件建立时间大于4.7us,所以延时5us
SDA=1;//当SCL为高电平时,SDA由低变高,产生结束信号
delay5us();//延时5us
SCL=0;
}
voidAck(void)//产生应答信号
{
SDA=0;//SDA先清0,发应答信号
SCL=1;//SCL由低变高,产生一个时钟
delay5us();//延时5us
SCL=0;//时钟线SCL恢复到低电平,以便继续接收
}
voidNAck(void)//产生非应答信号
{
SDA=1;//SDA先置1,发非应答信号
SCL=1;//SCL由低变高,产生一个时钟
delay5us();//延时5us
SCL=0;//时钟线SCL清恢复到低电平,以便继续接收
}
voidSendByte(ucharc)//向I2C总线发送一个字节
{
ucharn;
for(n=0;n<8;n++)//一字节为8位,循环8次
{
if(c&0x80)SDA=1;//根据发送位将数据线SDA置为1或清0
elseSDA=0;
SCL=1;//置SCL为高,通知被控从机开始接收数据位
delay5us();//延时5us
SCL=0;//SCL变低电平,准备发送下一位数据
c=c<<1;//将下一位要发送的数据移到最高位,先高后低
}
delay5us();//延时5us
SDA=1;//一字节发送完后释放数据线,准备接收应答位
delay5us();
SCL=1;//SCL由低变高,产生一个时钟,读取SDA的状态
delay5us();//延时5us
if(SDA==1)
ack_mk=0;//如果SDA=1,则发送失败,将ack_mk清0
else
ack_mk=1;//否则发送成功,将ack_mk置1
SCL=0;//SCL变低
}
ucharRcvByte()//接收一个字节
{
ucharc;
ucharn;
for(n=0;n<8;n++)//一字节为8位,循环8次
{SDA=1;//置数据线SDA为输入方式,进入接收方式
SCL=1;//SCL由低变高,产生一个时钟
if(SDA==0)//根据数据线SDA的状态,将c的最高位清0或置1
c=c&0x7f;
else
c=c|0x80;
c=_crol_(c,1);//将c循环左移一位,先接收高位,后接收低位
SCL=0;//时钟线SCL清0
}
return(c);
}
/*从指定器的的子地址开始写入多个字节*/
bitISendStr(ucharsla,ucharsuba,uchar*s,ucharno)
{
uchari;
Start();//启动总线
SendByte(sla);/*发送器件地址*/
if(ack_mk==0)return(0);
SendByte(suba);/*发送器件子地址*/
if(ack_mk==0)return(0);
for(i=0;i { SendByte(*s);/*发送数据*/ if(ack_mk==0)return(0); s++; } Stop();/*结束总线*/ return (1); } /*从指定器的的子地址开始读取多个字节*/ bitIRcvStr(ucharsla,ucharsuba,uchar*s,ucharno) { uchari; Start();/*启动总线*/ SendByte(sla);/*发送器件地址*/ if(ack_mk==0)return(0); SendByte(suba);/*发送器件子地址*/ if(ack_mk==0)return(0); Start(); SendByte(sla+1); if(ack_mk==0)return(0); for(i=0;i { *s=RcvByte();/*发送数据*/ Ack();/*发送就答位*/ s++; } *s=RcvByte(); NAck();/*发送非应位*/ Stop();/*结束总线*/ return (1); } 文件LCD12864IO.C的清单如下: #include #include #include #defineucharunsignedchar #defineuintunsignedint sbitLCD_RST=P3^7;//液晶屏复位脚定义 sbitDI=P3^4;//DI引脚定义 sbitRW=P3^5;//RW引脚定义 sbitCS=P3^3;//片选信号定义 sbitEN=P3^6;//使能信号定义 sbitRDY=P0^7;//对应状态信息中的BF位 sfrLCD=0x80;//P0口作为数据口 #defineLCD_DISPON0x3f//打开LCD显示 #defineLCD_STARTROW0xc0 //设置起始行,可用LCD_STARTROW+x设置起始行(x<64) #defineLCD_ADDRSTRY0xb8 //页起始地址,可用LCD_ADDRSTRX+x设置当前页(x<8) #defineLCD_ADDRSTRX0x40 //列起始地址,可用LCD_ADDRSTRY+x设置当前列(x<64) #defineCS10//左半屏选择 #defineCS21//右半屏选择 //命令字cmd送左半屏(port=0)/右半屏(port=1)命令口 voidLCD_WrCmd(bitport,ucharcmd) {EN=0; CS=port; DI=0;//选择命令寄存器 RW=0; EN=1; LCD=cmd;//命令码送总线 EN=0; } //数据wrdata送左半屏(port=0)/右半屏(port=1)数据口 voidLCD_WrDat(bitport,ucharwrdata) {EN=0; CS=port; DI=1;//选择命令寄存器 RW=0; EN=1; LCD=wrdata;//命令码送总线 EN=0; } //以filldata充填液晶屏 voidLCD_DispFill(ucharfilldata) {ucharx,y; LCD_WrCmd(CS1,LCD_STARTROW);//设置左半屏显示起始行为0 LCD_WrCmd(CS2,LCD_STARTROW);//设置右半屏显示起始行为0 for(y=0;y<8;y++)//循环充填8页 {LCD_WrCmd(CS1,LCD_ADDRSTRY+y);//设置左半屏页地址 LCD_WrCmd(CS1,LCD_ADDRSTRX);//设置左半屏列地址 LCD_WrCmd(CS2,LCD_ADDRSTRY+y);//设置右半屏页地址 LCD_WrCmd(CS2,LCD_ADDRSTRX);//设置右半屏列地址 for(x=0;x<64;x++)//充填每页的64个单元(列) {LCD_WrDat(CS1,filldata); LCD_WrDat(CS2,filldata); } } } //液晶模块初始化 voidLCD_DispIni(void) {uinti; LCD_RST=0;//复位驱动芯片 for(i=0;i<500;i++); LCD_RST=1; LCD_WrCmd(CS1,LCD_DISPON);//打开显示 LCD_WrCmd(CS1,LCD_STARTROW);//设置显示起始行为0 LCD_WrCmd(CS2,LCD_DISPON); LCD_WrCmd(CS2,LCD_STARTROW); LCD_DispFill(00);//清屏 LCD_WrCmd(CS1,LCD_ADDRSTRY+0);//设置页(字符行)地址 LCD_WrCmd(CS1,LCD_ADDRSTRX+0);//设置列地址 LCD_WrCmd(CS2,LCD_ADDRSTRY+0); LCD_WrCmd(CS2,LCD_ADDRSTRX+0); } //在液晶屏的cy(0-7)行、cx(0-15)列显示字符dispdata voidLCD_DispChar(bitcolor,ucharcy,ucharcx,chardispdata) {ucharcode*pch; uchari; bitport; cy=cy&0x07;//参数过滤 cx=cx&0x0f; pch=&ASCII_TAB[(dispdata-0X20)*5];//指向字符起始列的点阵码 if((cx&0x08)==0)//列号cx<8,在左半屏显示 {port=CS1; i=cx<<3; } else {port=CS2; i=(cx&0x07)<<3; } LCD_WrCmd(port,LCD_ADDRSTRX+i);//设置当前列地址 LCD_WrCmd(port,LCD_ADDRSTRY+cy);//设置当前页地址 for(i=0;i<5;i++);//延时 if(color==0) LCD_WrDat(port,0x00);//显示一列空格 else LCD_WrDat(port,0xff);//显示一列空格 for(i=0;i<5;i++)//送出字符的5列点阵码 {if(color==0) LCD_WrDat(port,*pch); else LCD_WrDat(port,~*pch); pch++; } if(color==0) LCD_WrDat(port,0x00);//显示一列空格 else LCD_WrDat(port,0xff);//显示一列空格 for(i=0;i<5;i++); if(color==0) LCD_WrDat(port,0x00);//显示一列空格 else LCD_WrDat(port,0xff);//显示一列空格 } //在液晶屏的cy(0-7)行、cx(0-15)列显示字符disp_str voidLCD_DispStr(bitcolor,ucharcy,ucharcx,char*disp_str) {while(*disp_str! ='\0') {cy=cy&0x07;//参数过滤 cx=cx&0x0f; LCD_DispChar(color,cy,cx,*disp_str);//显示字符 disp_str++;//指向下一字符数据 cx++; if(cx>15)cy++;//指向下一显示行 } } //在液晶屏的cy(0-3)行、cx(0-7)列显示汉字字符dispdata voidLCD_DispHZ(ucharcy,ucharcx,uchardispdata) {ucharcode*pdat; uchari,s,page; bitport; cy=cy&0x03;//参数过滤 cx=cx&0x07; pdat=&HZTAB[dispdata*32]; if((cx&0x04)==0)//如果在左半屏显示 {port=0; s=cx<<4;//求出该汉字在屏幕上的起始列 } else//在右半屏上显示 {port=1; s=(cx<<4)-64;//求出该汉字在屏幕上的起始列 } for(page=0;page<2;page++)//每个汉字2页 {LCD_WrCmd(port,LCD_ADDRSTRX+s);//设置当前列地址 LCD_WrCmd(port,LCD_ADDRSTRY+(cy<<1)+page);//设置当前页地址 for(i=0;i<5;i++); for(i=0;i<16;i++)//每个汉字16列 {LCD_WrDat(port,*pdat);//发送数据 pdat++; } for(i=0;i<5;i++); } } //在液晶屏的cy(0-3)行、cx(0-7)列显示汉字字符串disp_str voidLCD_DispHZStr(ucharcy,ucharcx,uchar*disp_str) {while(*disp_str! =0xff) {cy=cy&0x03;//参数过滤 cx=cx&0x07; LCD_DispHZ(cy,cx,*disp_str);//显示汉字 disp_str++;//指向下一汉字 cx++;//列号加1 if(cx>7) {cy++;//指向下一显示行 cx=0; } } } voidHelp(void) { Help2(); while (1) {k=GetKey(); if(k==KINC) { m++; if(m%2==0) { Help2(); } else { Help1(); } } elseif(k==KDOWN) { break; } } } bitreset(void)//初始化DS18B20 {biterr; DQ=0;//在数据线上产生600us的低电平 delay15(40); DQ=1;//数据线拉高 delay15(4);//延时60us err=DQ;//读取数据线状态,err=0: 复位成功 delay15(18);//err=1: 复位失败 return(err); } voidwrbyte(uchard)//向DS18B20写入一个字节 {uchari; dat=d; for(i=8;i>0;i--)//循环写8位(先低位,后高位) {DQ=0;//产生15us的负脉冲 delay15 (1); DQ=dat0;//将当前数据位送数据线 dat=dat>>1;//将下一位要写入的数据移到最低位 delay15 (1);//延时15us DQ=1;//数据线拉高,为写入下一位做准备 } } ucharrdbyte(void)//从DS18B20读取一个字节 {uchari; dat=0;//读出数据初值为0 for(i=8;i>0;i--)//循环读8位(先低位,后高位) {dat=dat>>1;//读出数据先右移一位 DQ=0;//产生1us的负脉冲 _nop_(); DQ=1;//数据总线拉高 delay15 (1);//延时15us dat7=DQ;//读取数据 dela
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 自动 打铃 控制器 资料