PIC单片机课程设计报告_第1页
PIC单片机课程设计报告_第2页
PIC单片机课程设计报告_第3页
PIC单片机课程设计报告_第4页
PIC单片机课程设计报告_第5页
已阅读5页,还剩12页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

.z......资料....NORTHCHINAUNIVERSITYOFSCIENCEANDTECHNOLOGY单片机课程设计报告学生:王文帅学 号:5学 院:信息工程学院专业班级:12级电信四班指导教师:博2015年 06 月 21日一、课程设计目的本课程设计是在《PIC单片机原理及应用》及《单片机C语言编程》课程的基础上,通过硬件设计、软件编程及仿真调试的实践,进一步掌握PIC单片机的应用方法,熟练掌握PICCC语言程序的编写与调试,是毕业设计前的一次重要实践,为今后走上工作岗位打下坚实的单片机应用基础。二、设计题目及要求2.1设计题目:基于PIC16F877单片机的多功能电子时钟2.2功能实现:实时时钟显示,时间可调;实时温度显示,并具有超限报警功能。输出显示采用LCD1602或LED七段数码显示器。2.3设计要求:自己设计硬件和程序编程,画出完整的电路原理图,用Multisim或Proteus仿真,最终可实现脱机运行。三、设计原理说明3.1时钟模块DS1307是美国DALLAS公司推出的I2C总线接口实时时钟芯片,它可独立于CPU工作,不受CPU主晶振及其电容的影响,且计时准确,月累积误差一般小于10秒。芯片还具有主电源掉电情况下的时钟保护电路,DS1307的时钟靠后备电池维持工作,拒绝CPU对其读出和写入访问。同时还具有备用电源自动切换控制电路,因而可在主电源掉电和其它一些恶劣环境场合中保证系统时钟的定时准确性。DS1307具有产生秒、分、时、日、月、年等功能,且具有闰年自动调整功能。同时,DS1307芯片部还集成有一定容量、具有掉电保护特性的静态RAM,可用于保存一些关键数据。3.2显示模块如用LCD1602作为显示设备,要求显示屏分两行显示,第一行显示日期(年-月-日)和星期,第二行显示时间(时:分:秒)和温度。显示秒由00一直加到59,分钟数也由00加到59,小时采用24小时制,由00加到23,如此循环显示。3.3按键模块按键用来作为时间调整。要求至少设计4个按键,按键1作为设置键;按键2、按键3分别为增加、减少键,在设置键按下时,此两个按键方有效;按键4是确定键,在设置键按下时方才有效。3.4温度采集模块DS18B20是美国DALLAS公司推出的单总线数字温度传感器。DS18B20部集成了温敏元件、数据转换芯片、存储器芯片和计算机接口芯片等多功能模块。其主要技术特点有:具有独特的单线接口方式;可以通过数据线供电,具有超低功耗工作方式;测温围为-55℃~125℃,测温精度为0.5℃;温度转换精度9~12位可编程,直接将温度转换值以二进制数码的方式串行输出。四、硬件原理图(含原理图、电路仿真图)时间显示:按下温度键temp后显示温度:五、软件设计(含流程图、带注释的程序清单)*include<pic.h>*include<string.h>*include<stdio.h>*define_*TAL_FREQ1000000UL*definespeakRC3*defineON0*defineOFF1*defineDQRB5//设置数据方向*defineDQ_IN()TRISB5=1//输入*defineDQ_OUT()TRISB5=0//输出//DS1302引脚定义*defineIORA1*defineSCLKRA0*defineRSTRA2//DS1302端口数据读写方向*defineSET_IO_RD()TRISA1=1*defineSET_IO_WR()TRISA1=0*defineLCD_CLS0*01*defineLCD_HOME0*02*defineLCD_SETMODE0*04*defineLCD_SETVISIBLE0*08*defineLCD_SHIFT0*10*defineLCD_SETFUNCTION0*20*defineLCD_SETCGADDR0*40*defineLCD_SETDDADDR0*80*definePORT_LCD_DATPORTD*definePORT_LCD_CTLPORTC*defineTRIS_LCD_DATTRISD*defineTRIS_LCD_CTLTRISC*defineRSRC5*defineRWRC6*defineERC7e*ternunsignedcharDateTime[];e*terncharWEEK[][4]={"SUN","MON","TUS","WEN","THU","FRI","SAT"};//0,1,2,3,4,5,6分别对应周日,周一至周六//所读取的日期时间(秒,分,时,日,月,星期,年)unsignedinttemper;unsignedintsettempe=570;unsignedcharDateTime[7];unsignedchartmp[]="0000";//向DS1302写入一个字节unsignedcharRB1_FLAG=0;constunsignedchartone[]={108,102,91,86,77,68,61,57};//发声的频率常数voiddelay18us(unsignedchar*) //18us,每次加1,增加9us{ unsignedchari; for(;*>0;*--){ for(i=0;i<1;i++);}}voiddelay1ms(unsignedint*){ unsignedchari; for(;*>0;*--) for(i=0;i<165;i++); }voidwrite_byte_to_DS1302(unsignedchar*){unsignedchari;SET_IO_WR();for(i=0*01;i!=0*00;i<<=1) { if(*&i)IO=1;elseIO=0; SCLK=0;SCLK=1;__delay_us(10); }}//从DS1302读取1字节unsignedcharget_byte_form_DS1302(){unsignedchari,dat=0*00;SET_IO_RD();for(i=0;i<8;i++){ SCLK=1;SCLK=0; if(IO)dat|=(0*01<<i);__delay_us(10);}return(dat>>4)*10+(dat&0*0F);}//从DS1302指定位置读数据unsignedcharread_data(unsignedcharaddr){unsignedchardat;RST=1;write_byte_to_DS1302(addr);dat=get_byte_form_DS1302();RST=0;returndat;}//向DS1302指定地址写数据voidWrite_DS1302(unsignedcharaddr,unsignedchardat){RST=1; write_byte_to_DS1302(addr);write_byte_to_DS1302(dat);RST=0;}voidport_init(){ ADCON1=0*06;//RA设置为普通IO口 TRISA=0*00;//端口A设置为输出 OPTION=0*00;//端口B弱上拉使能 TRISB=0*FF;PORTC=0*00;TRISC=0*00;//端口C设置为输出PORTD=0*00; TRISD=0*00;//端口D设置为输出speak=0;}voidsong(unsignedchar*){ unsignedchari,j; for(i=0;i<60;i++) { for(j=0;j<3;j++) { speak=1; delay18us(tone[*]); speak=0;//翻转发声 delay18us(tone[*]); } } }voidkeyscan() {unsignedchara,b;DateTime[0]=0;Write_DS1302(0*8E,0*00);//Write_DS1302(0*80,0*80);//if(RB2==0)//小时+1{ DateTime[2]=DateTime[2]+1;//第三个元素小时+1 if(DateTime[2]==24)DateTime[2]=0;//当变为24H时,小时位归零 a=DateTime[2]/10*16+DateTime[2]%10;//变成16进制数据 Write_DS1302(0*84,a);}if(RB3==0){ DateTime[1]=DateTime[1]+1;//第二个元素分钟+1 if(DateTime[1]==60)DateTime[1]=0;//当变为60min时,小时位归零 b=DateTime[1]/10*16+DateTime[1]%10;//变成16进制数据 Write_DS1302(0*82,b); }if(RB4==0){ song(3); while(RB4==ON); Write_DS1302(0*80,0*00);//调整完毕后启动时钟运行 Write_DS1302(0*8E,0*00);//禁止写 RB1_FLAG=0;//将RB1按下后产生的标志清除}}//DS1302初始化voidinit_DS1302(){unsignedcharsecond_REG;second_REG=read_data(0*81);//读取秒寄存器当前值//如果高位CH为1,则表示当前DS1302振荡器出于待机状态//这时需要将CH(clockhaltflag)位设为0,打开振荡器使时钟运行if((second_REG&0*80)==0*80){Write_DS1302(0*8E,0*00);//写控制字节,取消写保护Write_DS1302(0*80,second_REG&0*7F);//0*80地址不变,设高位CH=0 Write_DS1302(0*8E,0*80);//加保护}}//读取当前日期voidgetDateTime(){//Write_DS1302(0*8E,0*00);//允许写操作unsignedchari,addr=0*81; for(i=0;i<7;i++){ DateTime[i]=read_data(addr); addr+=2; }}//********LCD显示子函数***********************////**********结束LCD子函数********************//voidLCD_BUSY_WAIT()//忙等待{unsignedcharstatus;TRIS_LCD_DAT=0*FF;RS=0;RW=1;do{E=1;NOP();status=PORT_LCD_DAT;E=0;}while(status&0*80);}voidWrite_LCD_mand(unsignedcharcmd)//写LCD命令{TRIS_LCD_DAT=0*00;PORT_LCD_DAT=cmd;PORT_LCD_CTL=TRIS_LCD_CTL=0*00;RS=0;RW=0;E=1;NOP();E=0;LCD_BUSY_WAIT();}voidWrite_LCD_Data(unsignedchardat)//写LCD寄存器数据{TRIS_LCD_DAT=0*00;PORT_LCD_DAT=dat;RS=1;RW=0;E=1;NOP();E=0;LCD_BUSY_WAIT();}voidLCD_Initialize(){Write_LCD_mand(0*38);__delay_ms(2);Write_LCD_mand(0*01);__delay_ms(2);Write_LCD_mand(0*06);__delay_ms(2);Write_LCD_mand(0*0C);__delay_ms(2);}voidLCD_ShowString(unsignedcharr,unsignedcharc,char*str){unsignedchari=0;if(r==0)Write_LCD_mand(0*80|c);elseif(r==1)Write_LCD_mand(0*C0|c);for(i=0;i<16&&str[i]!='\0';i++)Write_LCD_Data(str[i]);}voiddisplay_str(unsignedcharline,unsignedcharlocation,unsignedcharstr)//line行,location列,str字符{ RS=0; RW=0; E=1; delay1ms(1); if(line==0) //line=0,第一行 PORT_LCD_DAT=0*80+location; if(line==1) //line=1,第二行 PORT_LCD_DAT=0*C0+location; E=0; LCD_BUSY_WAIT(); Write_LCD_Data(str);}voidSet_LCD_POS(unsignedcharr,unsignedcharc)//设置显示起始位置{if(r==0)Write_LCD_mand(0*80|c);elseif(r==1)Write_LCD_mand(0*C0|c);}//********18B20子程序********////包括函数:voidWait_18B20();////voiddelay15us(unsignedint*) //*必须大于0{ do {*--;} while(*); }voidreset(){ unsignedcharstate_DQ=1; while(state_DQ) { DQ_OUT(); delay15us(64); //延时721us DQ_IN(); delay15us(5); //延时61us if(DQ) state_DQ=1; //若DS18B20无应答,循环检查 else state_DQ=0; //检测到DS18B20应答低电平信号 delay15us(43); //延时490us } }voidwrite_one_byte(unsignedchardata){ unsignedchari,tmp; for(i=0;i<8;i++) { tmp=data&0*01; data>>=1; if(tmp) //tmp=1时 { DQ_OUT(); NOP();NOP(); DQ_IN(); delay15us(5); //延时61us } else { DQ_OUT(); delay15us(5); //延时61us DQ_IN(); NOP();NOP(); } }}unsignedcharread_one_byte(){ unsignedchari,data; for(i=0;i<8;i++) { data>>=1; DQ_OUT(); NOP(); DQ_IN(); NOP();NOP(); if(DQ==1) data=data|0*80; delay15us(5); //延时61us } return(data); }unsignedintget_temperature(){ unsignedchartmpA,tmpB; //定义读出RAM的高低位变量 reset(); write_one_byte(0*cc); //写跳过ROM命令,因为总线上只有一个DS18B20 write_one_byte(0*44); //启动DS18B20温度转换命令 delay1ms(800); reset(); //如果再写命令必须再次复位 write_one_byte(0*cc); //写跳过ROM命令,因为总线上只有一个DS18B20 write_one_byte(0*be); //读部RAM中9字节的容命令 tmpA=read_one_byte(); //读部RAM低八位温度 tmpB=read_one_byte(); //读部RAM高八位温度 temper=tmpB*256+tmpA; return(temper);}voidtemp(){unsignedchartmpB,tmpA;unsignedintresults; display_str(1,10,tmp[0]);//在指定位置显示百位/负号display_str(1,11,tmp[1]);//在指定位置显示十位display_str(1,12,tmp[2]);//在指定位置显示个位display_str(1,13,'.');//在指定位置显示小数点位display_str(1,14,tmp[3]);//在指定位置显示十分位位display_str(1,15,0*DF);//在指定位置显示°display_str(1,16,'C');//在指定位置显示C delay1ms(200); //tmp[21]...222325 results=get_temperature(); if(results>=0*1000) { results=results^0*FFFF; results++; tmpB=results/256; tmpA=(unsignedchar)results; results>>=4; tmp[0]=0*2D; //负号 } else { tmpB=results/256; //高八位 tmpA=(unsignedchar)results; //低八位 results>>=4; tmp[0]=results/100+0*30; //百 } tmp[1]=results/10%10+0*30; //十 tmp[2]=results%10+0*30; //个 tmpA<<=4; tmpA>>=4; results=625*tmpA; tmp[3]=results/1000+0*30;//if(results>40)//speak=0;//song(0);}charLCD_disp_buff[17];voidpro_key_scan(){if(RB1==1) { getDateTime(); }if(RB1==0){song(0); while(RB1==ON); __delay_ms(

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论