河北联合大学轻工学院QINGGONG COLLEGE, HEBEI UNITED UNIVERSITY 《PIC单片机课程设计》学生姓名:肖晓峰学号:201124520121学部:信息科学技术部专业班级:电信1指导教师:曹义2014年7 月 4 日本课程设计是在《PIC单片机原理及应用》及《单片机C语言编程》课程的基础上,通过硬件设计、软件编程及仿真调试的实践,进一步掌握PIC单片机的应用方法,熟练掌握PICC C语言程序的编写与调试,是毕业设计前的一次重要实践,为今后走上工作岗位打下坚实的单片机应用基础。
2.1 设计题目:基于PIC16F877单片机与DS18B20的温度采集与显示2.2 功能实现:实时温度显示,并具有超限报警功能。
输出显示采用LCD1602。
2.3 设计要求:自己设计硬件和程序编程,画出完整的电路原理图,用Multisim或Proteus 仿真,最终可实现脱机运行。
三、设计原理说明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位可编程,直接将温度转换值以二进制数码的方式串行输出。
四、硬件原理图(含原理图、电路仿真图)图2电路仿真图五、软件设计(含流程图、带注释的程序清单)程序设计流程图主文件he//**********************************************/#include<pic.h>__CONFIG(0x3B31);//芯片配置字,看门狗关,上电延时开,掉电检测关,低压编程关,加密,4M晶体HS振荡//宏定义#define DQ RC1 //温度数据口#define DQ_HIGH() TRISC1=1#define DQ_LOW() TRISC1=0;DQ=0#define uchar unsigned char#define uint unsigned int#define RS RA0 //LCD功能选择位#define RW RA1 //读写选择#define EN RA2 //使能//变量定义int temper;char f = 0 ;uchar a1,a2,a3,a4;uchar Prompt[]="P1ress K1 - K3 To Start Demo Prog";//各种申明void init();void DelayMS(uint ms);uchar Busy_Check();void Write_LCD_Command(uchar cmd);void Write_LCD_Data(uchar dat);void Initialize_LCD();void ShowString(uchar x,uchar y,uchar *str);void Showword0(uchar x,uchar y,char word );void Showword1(char word );void write_shuzi(uchar num1,uchar num2,uchar num3,uchar num4);//18b20void delay(uint x);void delayus(uint,uchar);void init();void write_byte(uchar date);uchar read_byte();void get_tem();//***子函数****************************************///系统初始化函数void init(){ADCON1=0X07; //设置A口为普通数字口TRISA =0X00; //设置A口方向为输出TRISB =0x00;OPTION=0x00; //B口电阻上拉TRISC = 1;PORTC = 0x20;TRISD =0X00;TRISD =0x00;}//延时函数void delayus(uint x,uchar y){uint i;uchar j;for(i=x;i>0;i--);for(j=y;j>0;j--);}void delay(uint x){uint a,b;for(a=x;a>0;a--)for(b=110;b>0;b--);}//ds18b20复位函数void reset(){uchar st=1;DQ_HIGH(); //开始于高电平NOP();NOP(); //延时2uswhile(st){DQ_LOW();delayus(70,30); //750DQ_HIGH(); //释放总线delayus(4,4); //等70if(DQ==1) //应答判断st=1;elsest=0;delayus(50,10); //延时450}}//ds18b20写函数void write_byte(uchar date){uchar i,temp;DQ_HIGH(); //开始于高电平NOP();NOP();for(i=8;i>0;i--){temp=date&0x01;//01010101 //分位写入DQ_LOW();delayus(0,0); //15if(temp==1)DQ_HIGH();delayus(2,2); //45DQ_HIGH();date=date>>1;//00101010}}//ds18b20读函数uchar read_byte(){uchar i,date;static bit j;for(i=8;i>0;i--){date=date>>1;DQ_HIGH(); //开始于高电平NOP();NOP();DQ_LOW();NOP();NOP();NOP();NOP();NOP();NOP(); //6DQ_HIGH();NOP();NOP();NOP();NOP(); //4j=DQ; //读取总线if(j==1)date=date|0x80;//1000 0000delayus(1,1); //30 }return (date); //返回函数值}//温度读取处理函数void get_tem(){uchar tem1,tem2,num;float aaa;reset(); //复位write_byte(0xCC);//跳过ROMwrite_byte(0x44);//温度转换reset();write_byte(0xCC); //跳过ROMwrite_byte(0xBE); //温度传递tem1=read_byte(); //读取低8位tem2=read_byte();//读取高8位if(tem2>7) //符号判断{tem2=255-tem2;tem1=255-tem1;f=1;}else {f=0;}aaa=(tem2*256+tem1)*6.25*8; //转化为实际温度值temper=(int)aaa; //强行转化位整数a1=temper/1000; //十进制分位a2=temper%1000/100;a3=temper%100/10;a4=temper%10;if(a1>7||a1<5) RD7=1;else RD7=0;}//延时void DelayMS(uint ms) //毫秒{uchar i;while(ms--) for(i=0;i<120;i++);}//LCD忙检查函数uchar Busy_Check(){uchar LCD_Status;RS=0; //寄存器选择(0指令1数据)RW=1; //读状态寄存器EN=1; //开始读DelayMS(1);LCD_Status=PORTB;EN=0;return LCD_Status;}//写LCD命令函数void Write_LCD_Command(uchar cmd){// while((Busy_Check()&0x80)==0x80); //忙等待RS=0; //选择命令寄存器RW=0; //写EN=0;PORTB=cmd;EN=1;DelayMS(1);EN=0;}//LCD发送数据函数void Write_LCD_Data(uchar dat){// while((Busy_Check()&0x80)==0x80); //忙等待RS=1;RW=0;EN=0;PORTB=dat;EN=1;DelayMS(1);EN=0;}//LCD初始化函数void Initialize_LCD(){Write_LCD_Command(0x38);DelayMS(1); //38:数据长8位,两行显示,字体5*7点阵(80)Write_LCD_Command(0x01);DelayMS(1); //清屏Write_LCD_Command(0x06);DelayMS(1); //字符进入模式:屏幕不动,字符后移Write_LCD_Command(0x0c);DelayMS(1); //显示开,光标关;0x0e 是开光标}//显示字符函数void Showword0(uchar x,uchar y,char word ) //y:行地址,x:列地址{if(y==0) Write_LCD_Command(0x80|x); //设置显示起始位置(x,0)第一行if(y==1) Write_LCD_Command(0xc0|x); // (x,1)第二行Write_LCD_Data(word+0x30); //str[i]等价于*(str+i)}//显示温度函数void write_shuzi(uchar num1,uchar num2,uchar num3,uchar num4){if(f){Showword0(0,0,-3 );} //负号Showword0(1,0,num1 ); //十位Showword0(2,0,num2 );Showword0(3,0,-2 ); //小数点Showword0(4,0,num3 );Showword0(5,0,num4 );DelayMS(5);}//主函数void main(){init(); //调用系统初始化函数Initialize_LCD(); //LCD初始化while (1){ get_tem(); //读取温度write_shuzi(a1,a2,a3,a4 ); //显示}}六、设计总结1 打好基础,清楚硬件工作原理,性能,以便于编程。