课程设计.....老师点的题目没想法.. 写了一个这个...在LCD上交替显示当前时间和当前温度...单片机小白整了2天整出来的程序..能跑....
芯片是STC89C52 , LCD用的1602 , 温度传感器用的18B20...
总线路图:
Program:
/*----------------------------------------------- 名称:LCD显示当前时间与当前温度 编写:zzy_Jacob 日期:2013.1 内容:在LCD上交替显示时间和温度 ------------------------------------------------*/ #include<reg52.h> #include<math.h> #include<INTRINS.H> #include<stdio.h> //标准输入输出 #include<intrins.h> #define uchar unsigned char #define uint unsigned int #define Data P0//数据端口 sbit RS = P2^4; //Pin4 sbit RW = P2^5; //Pin5 sbit E = P2^6; //Pin6 #define Data P0//数据端口 char data TimeNum[]=" "; char data Test[]=" "; uchar StrTime[6],StrTemper[8]; sbit DQ=P1^3;//ds18b20 端口 sfr dataled=0x80;//显示数据端口 uint temp; uchar TempH,TempL; uchar flag_get,hour=12,minute=30,second=0; void delay(unsigned int i) //延时函数 { while(i--); } void DelayUs(unsigned char us)//delay us { unsigned char uscnt; uscnt=us>>1; /*12MHz频率*/ while(--uscnt); } void DelayMs(unsigned char ms) //毫秒函数声明 { while(--ms) { DelayUs(250); DelayUs(250); DelayUs(250); DelayUs(250); } } void WriteCommand(unsigned char c) //写入命令函数 { DelayMs(5);//操作前短暂延时,保证信号稳定 E=0; RS=0; RW=0; _nop_(); E=1; Data=c; E=0; } void WriteData(unsigned char c) //写入数据函数 { DelayMs(5); //操作前短暂延时,保证信号稳定 E=0; RS=1; RW=0; _nop_(); E=1; Data=c; E=0; RS=0; } void ShowChar(uchar pos,uchar c) //写入字节函数 { uchar p; if (pos>=0x10) p=pos+0xb0; //是第二行则命令代码高4位为0xc else p=pos+0x80; //是第二行则命令代码高4位为0x8 WriteCommand (p);//写命令 WriteData (c); //写数据 } void ShowString (uchar line,char *ptr) // 写入字符串 { unsigned char l,i; l=line<<4; for (i=0;i<16;i++) ShowChar (l++,*(ptr+i));//循环显示16个字符 } void InitLcd() // 初始化LCD { DelayMs(15); WriteCommand(0x38); //display mode WriteCommand(0x38); //display mode WriteCommand(0x38); //display mode WriteCommand(0x06); //显示光标移动位置 WriteCommand(0x0c); //显示开及光标设置 WriteCommand(0x01); //显示清屏 } void Init_DS18B20() //初始化 { uchar x=0; DQ=1; //DQ复位 delay(8); //稍做延时 DQ=0; //单片机将DQ拉低 delay(80); //精确延时 大于 480us DQ=1; //拉高总线 delay(10); x=DQ; //稍做延时后 如果x=0则初始化成功 x=1则初始化失败 delay(5); } unsigned char ReadOneChar(void) // 读一个字节 { uchar i=0; uchar dat = 0; for (i=8;i>0;i--) { DQ = 0; // 给脉冲信号 dat>>=1; DQ = 1; // 给脉冲信号 if (DQ) dat|=0x80; delay(5); } return(dat); } void WriteOneChar(uchar dat) //写一个字节 { uchar i=0; for (i=8; i>0; i--) { DQ = 0; DQ = dat&0x01; delay(5); DQ = 1; dat>>=1; } delay(5); } unsigned int ReadTemperature(void) //读取温度 { uchar a=0; uint b=0; uint t=0; Init_DS18B20(); WriteOneChar(0xCC); // 跳过读序号列号的操作 WriteOneChar(0x44); // 启动温度转换 delay(200); Init_DS18B20(); WriteOneChar(0xCC); //跳过读序号列号的操作 WriteOneChar(0xBE); //读取温度寄存器等(共可读9个寄存器) 前两个就是温度 a=ReadOneChar(); //低位 b=ReadOneChar(); //高位 b<<=8; t=a+b; return(t); } void DisplayTemperPro() //显示温度处理函数 { uchar TempH,TempL; if(flag_get==1) //定时读取当前温度 { temp=ReadTemperature(); if(temp&0x8000) { StrTemper[0]='-';//负号标志 temp=~temp; // 取反加1 temp+=1; } } else StrTemper[0]=' '; TempH=temp>>4; TempL=temp&0x0F; TempL=TempL*6/10;//小数近似处理 flag_get=0; StrTemper[1]=TempH/100+'0'; //十位温度 StrTemper[2]=(TempH%100)/10+'0'; //十位温度 StrTemper[3]=(TempH%100)%10+'0'; StrTemper[4]='.'; StrTemper[5]=TempL+'0'; StrTemper[6]='C'; //显示C符号 } void DisplayTimePro( ) //显示时间处理函数 { StrTime[0]=hour/10+'0'; //显示小时 StrTime[1]=hour%10+'0'; StrTime[2]='-'; //显示"-" StrTime[3]=minute/10+'0'; //显示分钟 StrTime[4]=minute%10+'0'; StrTime[5]='-'; //显示"-" StrTime[6]=second/10+'0'; //显示秒 StrTime[7]=second%10+'0'; } int main() // 主函数 { static uchar times,i; int ChangeTime; TMOD|=0x01;//定时器设置 TH0=0xd8; TL0=0xf0; ET0=1; TR0=1; EA =1; DisplayTemperPro(); InitLcd(); //初始化LCD DelayMs(15); //延时保证信号稳定 while(1) { times++; if (times==200) { times=0; if (ChangeTime==0) { DisplayTimePro(); sprintf(Test,"Time: "); ShowString(0,Test); sprintf(Test,StrTime); for (i=8;i<16;i++) Test[i]=' '; ShowString(1,Test); } if (ChangeTime==3000) { DisplayTemperPro(); sprintf(Test,"Temperature: "); ShowString(0,Test); sprintf(Test,StrTemper); for (i=7;i<16;i++) Test[i]=' '; ShowString(1,Test); } ChangeTime++; if (ChangeTime>6000) ChangeTime=0; } } return 0; } void tim(void) interrupt 1 using 1//定时器0中断 { static uchar num,count; TH0=0xd8;//定时器重装值 TL0=0xf0; num++; if (num==50) { num=0; flag_get=1;//标志位有效 } count++; if (count==100) { count=0; second++; //秒加1 if(second==60) { second=0; minute++; //分加1 if(minute==60) { minute=0; hour=(hour+1)%24; //时加1 } } } }