




免费预览已结束,剩余20页可下载查看
下载本文档
版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
基于PIC16F887单片机的温度、时钟显示以及闹钟功能一、课程设计的目的 PIC 单片机课程设计是电气工程及其自动化专业及相近专业的一门重要的专业实践课,本课程在PIC 单片机课程的基础上,通过硬件设计与软件编程与调试的实践,进一步掌握PIC 单片机的 应用方法,熟练PIC 单片机的C 程序的编写与调试,是毕业设计前的一次重要的实践,为今后走上工作岗位打下坚实的单片机应用基础。 二、设计内容 1 Proteus 线路图绘制 根据所设计的线路图,绘制与之一致的,能用于仿真的Proteus 线路图。要求所绘的线路图美观、紧凑,参数要与课设 一致。 2、 软件编制与调试 根据所设计的线路图 制相应的单片机C 程序,要求所 制的程序符合C 语言格式并加上注解。每编一段即进行 译,有错及时修改,并先在Proteus 上仿真,基本正确后再用PICkit3 在线调试,最后应脱机运行。 3、 设计目标 1该设计包括数字钟及数字温度计:按键的使用.LCD.蜂鸣器 时钟芯片DS1307和温度传感器TC74。2功能;此设计可以感测环境的温度,显示当前的时间,及闹钟。温度与时间都显示在LCD显示屏上,以及如何调整闹钟界面四硬件设计及说明1 复位按键2时钟芯片DS1307及附属接线时钟芯片DS1307用于产生时间,它提供了秒、分、时、日、年、和星期等数据,能算只瑞年2100年,时钟的晶振是典型的32.768Hz。(1)其引脚作用如下: 2(2)DS1307的读写如下;1写DS1307 的步骤如下: a) 发送启始位; b) 发送DS1307 的7位地址+0 (写),即0b11010000; c) 发送要写入DS1307 的地址,地址见图16,如要修改分,此值为1; d) 发送要写入DS1307 的数,如要把分修改为十进制数37,则此数为0x37; e) 发送停止位; 2读DS1307 的步骤如下: a) 发送启始位; b) 发送DS1307 的7位地址+0 (写),即0b11010000; c) 发送要读的DS1307 的起始地址,如要从秒读起,为0; d) 发送停止位; e) 发送重新开始位; f) 发送DS1307 的7位地址+1 (读),即0b11010001; g) 发送读使能位,接收一个数据,单片机发送应答位; h) 发送读使能,接收下一个数据(地址会自动+1),单片机发送应答位,直到读数完成,接收最后 一个数时单片机不发送应答位; i) 发送停止位; 注意在DS1307仿真的时候七位地址为0b1001101 而实际为0b1001000 ;(3) 功能是;提供时间通过pic16F877送入LCD中显示。3 振荡方式4时钟控制按键及闹钟电路(1)按键1可以再时钟界面和闹钟界面切换(2)按键2可以通过光标移动设置时间和闹钟(3)按键3,4可以修改时机(4)三极管用于电流的放大,以致驱动喇叭。5 LM016L 液晶显示屏LM016L是字符型的LCD液晶显示屏其内部控制芯片是HD44780或KS0066之类是16X2的字符型的LCD对其使用时(1)要初始化;(2)在LCD显示前,要对显示位置进行定位,既写位置命令(3)把该命令写入到DDRAM中 (4)在用写数据命令,显示要显示的字符五 软件设计及说明程序大体说明,1. 设单片机上电,屏幕上显示welcome!和hello!2. 上述界面延迟一段时间后,自动进入时间界面,通过程序的运行,单片机自动同DS1307和TC74芯片中读取时间和温度并显示在LCD上3.通过不断的按键扫面,当(1)按键1可以再时钟界面和闹钟界面切换(2)按键2可以通过光标移动设置时间和闹钟(3)按键3,4可以修改时间,分别加减4.当切换到闹钟界面,通过设置好时间后,在时间界面星期旁边会显示一个A提示我们闹钟已经开启,当到了设置的时间点,蜂鸣器会自动响,延迟一段时间会自动关掉,或者我们可以用通过按键4人为关掉它#include_CONFIG(0x20F1);#define uchar unsigned char#define uint unsigned int#define ds1307 0b1101000#define TC74 0b1001000#define RTR 0b00000000#define FMQ RC1#define LCD_RS RD4#define LCD_RW RD5#define LCD_E RD6#define S1 RB0#define S2 RB1#define S3 RB2#define S4 RB3#define DAT 1#define COM 0#define LINE1 0b10000000#define LINE2 0b11000000#define YEAR LINE1+2#define MONTH LINE1+5#define DAY LINE1+8#define WEEK DAY+3#define HOUR LINE2+1#define MINUTE LINE2+4#define SECOND LINE2+7#define WENDU SECOND+4 /函数声明void DELAY(uint n);void DELAY_A(uint n);void DELAY_US(char n);void CSH();void DS1307_CSH();void KEYSCAN();void LCD_CSH();void LCD_BUSY();void LCD_CLR();void LCD_GD();void READ();void DSweek(char);void LCD_WRITE(char,char);void LCD_WRITE_4(char,char);void TIME();void TIME_UP();void TIME_DOWN();void TIME_UPDATE();void DISL1();void DISL2();void DISL5();void BCD(uint);void DISP_T(signed char);void IIC_CSH();void IIC_SEND(char R);void IIC_WRITE(char,char);void ALARM_CLOCK();void ALARM_KG();char LCD_READ();char IIC_READ(char addr);char flag,flag_A,A;char m=0,f=0,s=0,x,r,y,n;char A_m=0,A_f=0,A_s=0,A_x=0;char shi,ge;char BW,SW,GW;signed char T_READ();uchar num1=0,num2=0,num3;const uchar table0= WELCOME! ;const uchar table01= HELLO! ;const uchar table04= SET TIME ;const uchar table=20 - - ;const uchar table1= : : ;/BCD码转换,R1双字节转换为十进制数void BCD(uint R1) BW=0;SW=0;GW=0; while(R1=100) R1-=100;BW+; while(R1=10) R1-=10;SW+; GW=R1;/清屏void LCD_CLR() LCD_WRITE(0b00000001,COM); DELAY(2);/延时子程序void DELAY(uint n) uint j; char k; for(j=0;j0;k-)NOP();/关闹钟void DELAY_A(uint n) uint j; char k; for(j=0;j0;k-) NOP(); if(S4=0) DELAY(20); if(S4=0) break; void DELAY_US(char n) char j; j=n; while(j0) j-; NOP();NOP();NOP(); NOP(); /初始化void CSH()TRISC=0b00011000;TRISD=0X00;ANSELH=0b000000;TRISB=0b11111111;RBPU=0; /B口上拉使能WPUB=0b11111111; /887必须设置PORTB=0XFF; RC1=0; RD7=1;LCD_CSH();IIC_CSH(); DISL1(); DISL2();DELAY(500);LCD_CLR(); LCD_GD();DS1307_CSH();/LCD模块初始化void LCD_CSH()DELAY(20);/延时20msLCD_WRITE_4(0b0011,COM);/发送控制序列DELAY(1);/延时1msLCD_WRITE_4(0b0011,COM);/发送控制序列DELAY_US(10);/延时100usLCD_WRITE_4(0b0011,COM);/发送控制序列DELAY_US(10);/延时100usLCD_WRITE_4(0b0010,COM);/4位数据格式LCD_BUSY();/LCD忙检测LCD_WRITE(0b00101000,COM);/4位数据格式,2行(实际上4行!),57点阵LCD_WRITE(0b00001100,COM);/D(d2)=1:打开显示,C(d1)=1:光标打开,B(d0)=1:光标闪烁LCD_CLR();LCD_WRITE(0b00000110,COM);/输入模式,I/D(d1)=1:地址加1,S(d0)=1:显示移位关闭/LCD_GD /固定显示void LCD_GD()char i;LCD_WRITE(LINE1,COM);for(i=0;i11;i+)LCD_WRITE(tablei,DAT);DELAY(1);LCD_WRITE(LINE2+1,COM);for(i=0;i8;i+)LCD_WRITE(table1i,DAT);/=DISL1=void DISL1()char i;LCD_WRITE(0X80,COM);for(i=0;i15;i+)LCD_WRITE(table0i,DAT);/=DISL2=void DISL2()char i;LCD_WRITE(0Xc0,COM);for(i=0;i15;i+)LCD_WRITE(table01i,DAT);/=DISL5=void DISL5()char i;LCD_WRITE(0x80,COM);for(i=0;i15;i+)LCD_WRITE(table04i,DAT);/LCD_READ /读LCD状态char LCD_READ()unsigned char R1;LCD_RS=0;/寄存器选择LCD_RW=1;NOP();/读为1LCD_E=1;NOP();/使能R1=0;/短延时R1=PORTD;/读数据的高4位给R1的高4位,低4位清0R1=(R14;/取高4位LCD_WRITE_4(R2,FLAG);/先写高4位R2=R1&0X0F;/高4位清0,取低4位LCD_WRITE_4(R2,FLAG);/再送低4位DELAY_US(10);/延时100us/检测LCD是否忙void LCD_BUSY()unsigned char R1;doR1=LCD_READ();while(R1&0X80);/发送数R并等待发送完成,收到从机的应答信号208void IIC_SEND(char R)SSPBUF=R;/发送while (RW=1);/在主动模式下,判断发送是否完成while (SSPIF=0);/等待发送完成while (ACKSTAT=1);/等待从机发送应答信号/IIC初始化208void IIC_CSH()TRISC&=0b00011000;/SDA,SCL设置为输入!SSPCON=0b00101000;/同步串口使能(SSPEN),主控方式SMP=0;/使能高速模式(400 kHz) 的压摆率控制SSPADD=4;/主控模式为波特率值,每位时间T=(SSPADD+1)/Tcy=5us/IIC_READ读char IIC_READ(char addr)char iicr;SEN=1; while(SEN=1);/发送起始位IIC_SEND(0b11010000);/DS1307在总线上的地址:0b11010000IIC_SEND(addr);/读取的首地址RSEN=1; while(RSEN=1);/发送重新起始位IIC_SEND(0b11010001);/读数据SSPIF=0;RCEN=1;while(SSPIF=0);/等待读完成iicr=SSPBUF;ACKDT=1; ACKEN=1; while(ACKEN=1); PEN=1; /发送停止位 while(PEN=0); return(iicr);/IIC_WRITE写void IIC_WRITE(char addr,char data) SEN=1; while(SEN=1);IIC_SEND(0b11010000);IIC_SEND(addr);IIC_SEND(data);PEN=1; while(PEN=1);/DS1307初始化时间并显示时间void DS1307_CSH() IIC_WRITE(0,0x45); /00秒 IIC_WRITE(1,0x00); /00分 IIC_WRITE(2,0x10); /00时 IIC_WRITE(3,0x06); /星期日 IIC_WRITE(4,0x05); /1日 IIC_WRITE(5,0x05); /1月 IIC_WRITE(6,0x12); /12年void READ() LCD_WRITE(SECOND,COM); shi=IIC_READ(0)4; ge=IIC_READ(0)&0x0f; LCD_WRITE(0x30+shi,DAT); LCD_WRITE(0x30+ge,DAT); LCD_WRITE(MINUTE,COM); shi=IIC_READ(1)4; ge=IIC_READ(1)&0x0f; LCD_WRITE(0x30+shi,DAT); LCD_WRITE(0x30+ge,DAT); LCD_WRITE(HOUR,COM); shi=IIC_READ(2)4; ge=IIC_READ(2)&0x0f; LCD_WRITE(0x30+shi,DAT); LCD_WRITE(0x30+ge,DAT); LCD_WRITE(DAY,COM); shi=IIC_READ(4)4; ge=IIC_READ(4)&0x0f; LCD_WRITE(0x30+shi,DAT); LCD_WRITE(0x30+ge,DAT); DSweek(IIC_READ(3); LCD_WRITE(MONTH,COM); shi=IIC_READ(5)4; ge=IIC_READ(5)&0x0f; LCD_WRITE(0x30+shi,DAT); LCD_WRITE(0x30+ge,DAT); LCD_WRITE(YEAR,COM); shi=IIC_READ(6)4; ge=IIC_READ(6)&0x0f; LCD_WRITE(0x30+shi,DAT); LCD_WRITE(0x30+ge,DAT); DELAY(100); DISP_T(T_READ(); if(A=1) LCD_WRITE(WEEK+4,COM); LCD_WRITE(A,DAT); if(A!=1) LCD_WRITE(WEEK+4,COM); LCD_WRITE( ,DAT); void DSweek(char num) LCD_WRITE(WEEK,COM); switch(num)case 1:LCD_WRITE(M,DAT);LCD_WRITE(0,DAT);LCD_WRITE(N,DAT);break;case 2:LCD_WRITE(T,DAT);LCD_WRITE(U,DAT);LCD_WRITE(E,DAT);break;case 3:LCD_WRITE(W,DAT);LCD_WRITE(E,DAT);LCD_WRITE(D,DAT);break;case 4:LCD_WRITE(T,DAT);LCD_WRITE(H,DAT);LCD_WRITE(U,DAT);break;case 5:LCD_WRITE(F,DAT);LCD_WRITE(R,DAT);LCD_WRITE(T,DAT);break;case 6:LCD_WRITE(S,DAT);LCD_WRITE(A,DAT);LCD_WRITE(T,DAT);break;case 7:LCD_WRITE(S,DAT);LCD_WRITE(U,DAT);LCD_WRITE(N,DAT);break;/*温度模块*/读温度值signed char T_READ()signed char R1;SEN=1; while(SEN=1);/发送起始位IIC_SEND(0b10010000);/TC74在总线上的地址:0b10010000 IIC_SEND(RTR);RSEN=1; while(RSEN=1);/发送重新起始位IIC_SEND(0b10010001);/读数据RCEN=1;while(RCEN=1);/等待读完成R1=SSPBUF;PEN=1; /发送停止位 while(PEN=0);return(R1);/显示温度void DISP_T(signed char R1) char R2; LCD_WRITE(0b00001100,COM); if(R1=0) BCD(R1); else R2=R1+1; BCD(R2); LCD_WRITE(WENDU,COM); if(R10) LCD_WRITE(0x30+SW,DAT); LCD_WRITE(0x30+GW,DAT); LCD_WRITE(0xDF,DAT); LCD_WRITE(C,DAT);/闹钟void ALARM_CLOCK() PR2=249; CCPR2L=0x25; CCP2CON=0B00001100; T2CON=0b00000101; /*按键*/按键扫描void KEYSCAN() if(S1=0) DELAY(20); if(S1=0) while(!S1); num1+; switch(num1) case 1: num2=0; /调闹钟,先读最初值为0 m=A_m; f=A_f; s=A_s; x=A_x; LCD_CLR(); DISL5(); LCD_WRITE(SECOND,COM); LCD_WRITE(0x30+m/16,DAT); LCD_WRITE(0x30+m%16,DAT); LCD_WRITE(MINUTE,COM); LCD_WRITE(0x30+f/16,DAT); LCD_WRITE(0x30+f%16,DAT); LCD_WRITE(:,DAT); LCD_WRITE(HOUR,COM); LCD_WRITE(0x30+s/16,DAT); LCD_WRITE(0x30+s%16,DAT); LCD_WRITE(:,DAT); LCD_WRITE(WEEK,COM); ALARM_KG(); break; case 2: num2=0;/调整后的时间读进去 num1=0; A_m=m; A_f=f; A_s=s; A_x=x; LCD_WRITE(0x0c,COM); flag=0; LCD_CLR(); LCD_GD(); break; /读暂停时的时间void TIME() m=IIC_READ(0); f=IIC_READ(1); s=IIC_READ(2); x=IIC_READ(3); r=IIC_READ(4); y=IIC_READ(5); n=IIC_READ(6);/时间更新void TIME_UPDATE() IIC_WRITE(0,m); IIC_WRITE(1,f); IIC_WRITE(2,s); IIC_WRITE(4,r); IIC_WRITE(5,y); IIC_WRITE(6,n);/闹钟开关void ALARM_KG() if(x!=1) A=0; LCD_WRITE(WEEK,COM); LCD_WRITE(O,DAT); LCD_WRITE(F,DAT); LCD_WRITE(F,DAT); x=0; if(x=1) A=1; LCD_WRITE(O,DAT); LCD_WRITE(N,DAT); LCD_WRITE( ,DAT); /光标移动void KEYMOVE() if(S2=0) DELAY(10); if(S2=0) while(!S2); num2+; if(num1!=1)/调整时间 switch(num2) case 1:flag=1; TIME(); LCD_WRITE(SECOND+1,COM); LCD_WRITE(0x0f,COM); break; case 2:LCD_WRITE(MINUTE+1,COM); break; case 3:LCD_WRITE(HOUR+1,COM); break; case 4:LCD_WRITE(WEEK,COM); break; case 5:LCD_WRITE(DAY+1,COM); break; case 6:LCD_WRITE(MONTH+1,COM); break; case 7:LCD_WRITE(YEAR+1,COM); break; case 8:LCD_WRITE(0x0c,COM); flag=0; TIME_UPDATE(); num2=0; break; if(num1=1)/设置闹钟 switch(num2) case 1: LCD_WRITE(SECOND+1,COM); LCD_WRITE(0x0f,COM); break; case 2:LCD_WRITE(MINUTE+1,COM); break; case 3:LCD_WRITE(HOUR+1,COM); break; case 4:LCD_WRITE(WEEK,COM); break; case 5:LCD_WRITE(0x0c,COM); num2=0; break; if(S3=0) DELAY(20); if(S3=0) while(!S3); TIME_UP(); if(S4=0) DELAY(20); if(S4=0) while(!S4); TIME_DOWN(); /加时间void TIME_UP() switch(num2) case 1:m+; if(m%16=10) m=(m&0xf0)+0x10; if(m=0x60) m=0; LCD_WRITE(SECOND,COM); shi=m4; ge=m&0x0f; LCD_WRITE(0x30+shi,DAT); LCD_WRITE(0x30+ge,DAT); LCD_WRITE(SECOND+1,COM); break; case 2:f+; if(f%16=10) f=(f&0xf0)+0x10; if(f=0x60) f=0; LCD_WRITE(MINUTE,COM); shi=f4; ge=f&0x0f; LCD_WRITE(0x30+shi,DAT); LCD_WRITE(0x30+ge,DAT); LCD_WRITE(MINUTE+1,COM); break; case 3:s+; if(s%16=10) s=(s&0xf0)+0x10; if(s=0x24) s=0; LCD_WRITE(HOUR,COM); shi=s4; ge=s&0x0f; LCD_WRITE(0x30+shi,DAT); LCD_WRITE(0x30+ge,DAT); LCD_WRITE(HOUR+1,COM); break; case 4:x+; if(x=0x08) x=1; if(num1!=1) IIC_WRITE(3,x); DSweek(IIC_READ(3); LCD_WRITE(WEEK,COM); if(num1=1) ALARM_KG(); break; case 5:r+; if(r%16=10) r=(r&0xf0)+0x10; if(r=0x32) r=1; LCD_WRITE(DAY,COM); shi=r4;
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 海事船长考试题及答案
- 光纤接续考试题及答案
- 企业财务管理报表生成标准化工具
- 企业运营发展信用保障承诺函8篇
- 雨中的那一抹彩虹色彩记叙文12篇
- 饭局礼仪考试题及答案
- (正式版)DB15∕T 3680-2024 《气候适宜度评价 荞麦》
- 小学生关于蚂蚁的想象作文400字10篇
- 企业内部标准化管理制度汇编
- 节能减排科技成果保证承诺书6篇范文
- 人才服务合同书
- 2025-2026学年统编版八年级上册道德与法治教学计划含教学进度表
- 2025年工会入职考试试题及答案
- 2025年中国电力投资集团校园招聘笔试题型分析及备考策略
- 旅游服务安全知识培训课件
- 公司章程制定合同协议书范本模板
- 2024人教PEP版三年级英语上册全册教案
- 立体车库应急预案范文
- 体彩专管员专业知识培训课件
- 严重腹部创伤院内救治专家共识(2024)解读
- 房内走廊改造方案(3篇)
评论
0/150
提交评论