课程设计.....老师点的题目没想法.. 写了一个这个...在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
}
}
}
}