冒泡..贴个改+写的单片机程序...

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


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值