新闻  |   论坛  |   博客  |   在线研讨会
12864显示温度和时间信息(ds1302、ds18b20)
Capture | 2013-08-07 11:29:07    阅读:608   发布文章

 

/***************************************************

名:12864显示温度和时间信息

工程包含:12864.c    12864.h      12864液晶显示

          ds18b20.c   ds18b20.h   温度采集

                   ds1302.c   ds1302.h     时间信息

          delay.h                 延时函数头文件

          main.c

    口:12864液晶

          RS  P3^0 ; RW  P3^1 ; EN  P3^2;数据口 P4

          Ds18b20接口

          DQ   P1^1

          Ds1302接口

          CLK:  P5^0

          DAT:   P5^1

          RST:   P5^2

功能描述:ds18b20采集外界温度,液晶显示。

                      DS1302时钟芯片,12864显示年月日、时分秒

工程内部的 .c  .h 文件可任意移植。

    者: Capture

修改时间:2013 .8.6

***************************************************/

 

 

 

#ifndef __DS1302_H__
#define __DS1302_H__


#include
#include "12864.h"
#include "delay.h"

#define  uint  unsigned int
#define  uchar unsigned char

/**************宏定义***************/
#define DS_SCL  BIT0        //DS_SCL = P5.0
#define DS_SDA  BIT1        //DS_SDA = P5.1
#define DS_RST  BIT2        //DS_RST = P5.2

#define DS_RST_IN  P5DIR &= ~DS_RST
#define DS_RST_OUT P5DIR |= DS_RST
#define DS_RST0    P5OUT &= ~DS_RST
#define DS_RST1    P5OUT |= DS_RST
#define DS_SCL_IN  P5DIR &= ~DS_SCL
#define DS_SCL_OUT P5DIR |= DS_SCL
#define DS_SCL0    P5OUT &= ~DS_SCL
#define DS_SCL1    P5OUT |= DS_SCL
#define DS_SDA_IN  P5DIR &= ~DS_SDA
#define DS_SDA_OUT P5DIR |= DS_SDA
#define DS_SDA0    P5OUT &= ~DS_SDA
#define DS_SDA1    P5OUT |= DS_SDA
#define DS_SDA_BIT P5IN & DS_SDA


//顺序:秒,分,时,日,月,星期,年;格式:BCD
extern unsigned char times[7];
//液晶显示数字编码
extern unsigned char shuzi[] ;

 

void Reset_DS1302(void);
void Write1Byte(unsigned char wdata);
unsigned char Read1Byte(void);
void W_Data(unsigned char addr, unsigned char wdata);
unsigned char R_Data(unsigned char addr);
void BurstWrite1302(unsigned char *ptr);
void BurstRead1302(unsigned char *ptr);
void BurstWriteRAM(unsigned char *ptr);
void BurstReadRAM(unsigned char *ptr);
void Set_DS1302(unsigned char *ptr);
void Get_DS1302(unsigned char *ptr);
void disply_time(void);
void xingqi(uchar a);

#endif

 

 

#include "ds1302.h"

unsigned char times[7];
//液晶显示数字编码
unsigned char shuzi[] = {"0123456789"};
unsigned char h1[9];  //年、月、日、周    
unsigned char h2[8];       
   
/*******************************************
函数名称:Reset_DS1302
功    能:对DS1302进行复位操作
参    数:无
返回值  :无
********************************************/
void Reset_DS1302(void)
{
    DS_RST_OUT;  //RST对应的IO设置为输出状态
    DS_SCL_OUT;  //SCLK对应的IO设置为输出状态
    DS_SCL0;     //SCLK=0
    DS_RST0;     //RST=0
    DelayUs(10);
    DS_SCL1;    //SCLK=1
}
/*******************************************
函数名称:Write1Byte
功    能:对DS1302写入1个字节的数据
参    数:wdata--写入的数据
返回值  :无
********************************************/
void Write1Byte(uchar wdata)
{
    uchar i;

    DS_SDA_OUT;     //SDA对应的IO设置为输出状态
    DS_RST1;        //REST=1;

    for(i=8; i>0; i--)
    {
        if(wdata&0x01)  DS_SDA1;
        else            DS_SDA0;
        DS_SCL0;
        DelayUs(10);
        DS_SCL1;
        DelayUs(10);
        wdata >>=1;
    }
}
/*******************************************
函数名称:Read1Byte
功    能:从DS1302读出1个字节的数据
参    数:无
返回值  :读出的一个字节数据
********************************************/
uchar Read1Byte(void)
{
    uchar i;
    uchar rdata=0X00;

    DS_SDA_IN;  //SDA对应的IO设置为输入状态
    DS_RST1;    //REST=1;

    for(i=8; i>0; i--)
    {
        DS_SCL1;
        DelayUs(10);
        DS_SCL0;
        DelayUs(10);
        rdata >>=1;
        if(DS_SDA_BIT)  rdata |= 0x80;
    }
   
    return(rdata);
}
/*******************************************
函数名称:W_Data
功    能:向某个寄存器写入一个字节数据
参    数:addr--寄存器地址
          wdata--写入的数据
返回值  :无
********************************************/
void W_Data(uchar addr, uchar wdata)
{
    DS_RST0;
    DS_SCL0;  
    _NOP();
    DS_RST1;
    Write1Byte(addr);   //写入地址
    Write1Byte(wdata);  //写入数据
    DS_SCL1;
    DS_RST0;
}
/*******************************************
函数名称:R_Data
功    能:从某个寄存器读出一个字节数据
参    数:addr--寄存器地址
返回值  :读出的数据
********************************************/
uchar R_Data(uchar addr)
{
    uchar rdata;
   
    DS_RST0;
    DS_SCL0;
    _NOP();
    DS_RST1;
    Write1Byte(addr);    //写入地址
    rdata = Read1Byte();  //读出数据
    DS_SCL1;
    DS_RST0;
   
    return(rdata);
}
/*******************************************
函数名称:BurstWrite1302
功    能:以burst方式向DS1302写入批量时间数据
参    数:ptr--指向时间数据存放地址的指针
返回值  :读出的数据
说    明:时间数据的存放格式是:
          秒,分,时,日,月,星期,年,控制
            【7个数据(BCD格式)+1个控制】
********************************************/
void BurstWrite1302(uchar *ptr)
{
    uchar i;
   
    W_Data(0x8e,0x00);      //允许写入    
    DS_RST0;
    DS_SCL0;
    _NOP();
    DS_RST1;
    Write1Byte(0xbe);       // 0xbe:时钟多字节写入命令
    for (i=8; i>0; i--)
    {
        Write1Byte(*ptr++);
    }
    DS_SCL1;
    DS_RST0;
    W_Data(0x8e,0x80);      // 禁止写入
}
/*******************************************
函数名称:BurstRead1302
功    能:以burst方式从DS1302读出批量时间数据
参    数:ptr--指向存放时间数据地址的指针
返回值  :无
说    明:时间数据的存放格式是:
          秒,分,时,日,月,星期,年,控制
            【7个数据(BCD格式)+1个控制】
********************************************/
void BurstRead1302(uchar *ptr)
{
    uchar i;
 
    DS_RST0;
    DS_SCL0;
    _NOP();
    DS_RST1;
    Write1Byte(0xbf);             //0xbf:时钟多字节读命令
    for (i=8; i>0; i--)
    {
       *ptr++ = Read1Byte();
    }
    DS_SCL1;
    DS_RST0;
}
/*******************************************
函数名称:BurstWriteRAM
功    能:以burst方式向DS1302的RAM中写入批量数据
参    数:ptr--指向存放数据地址的指针
返回值  :无
说明    :共写入31个字节的数据
********************************************/
void BurstWriteRAM(uchar *ptr)
{
    uchar i;
   
    W_Data(0x8e,0x00);         //允许写入
    DS_RST0;
    DS_SCL0;
    _NOP();
    DS_RST1;
    Write1Byte(0xfe);          //0xfe:RAM多字节写命令
    for (i = 31; i>0; i--)     //RAM共有31个字节
    {
        Write1Byte(*ptr++);
    }
    DS_SCL1;
    DS_RST0;
    W_Data(0x8e,0x80);          //禁止写入
}
/*******************************************
函数名称:BurstReadRAM
功    能:以burst方式从DS1302的RAM中读出批量数据
参    数:ptr--指向数据存放地址的指针
返回值  :无
说明    :共读出31个字节的数据
********************************************/
void BurstReadRAM(uchar *ptr)
{
    uchar i;
 
    DS_RST0;
    DS_SCL0;
    _NOP();
    DS_RST1;
    Write1Byte(0xff);             //0xff:RAM的多字节读命令
    for (i=31; i>0; i--)
    {
       *ptr++ = Read1Byte();  
    }
    DS_SCL1;
    DS_RST0;
}
/*******************************************
函数名称:Set_DS1302
功    能:设置DS1302内部的时间
参    数:ptr--指向存放数据地址的指针
返回值  :无
说明    :写入数据的格式:
            秒 分 时 日 月 星期 年  【共7个字节】
********************************************/
void Set_DS1302(uchar *ptr)
{
    uchar i;
    uchar addr = 0x80;
   
    W_Data(0x8e,0x00);    //允许写入
   
    for(i =7;i>0;i--)
    {
        W_Data(addr,*ptr++);
        addr += 2;
    }
    W_Data(0x8e,0x80);      //禁止
}
/********************************************************************
*
* 名称: Get_DS1302
* 说明:
* 功能: 读取DS1302当前时间
* 调用: R_Data(uchar addr)
* 输入: ucCurtime: 保存当前时间地址。当前时间格式为: 秒 分 时 日 月 星期 年
* 7Byte (BCD码) 1B 1B 1B 1B 1B 1B 1B
* 返回值: 无
***********************************************************************/
/*******************************************
函数名称:Get_DS1302
功    能:读取DS1302内部的时间
参    数:ptr--指向数据存放地址的指针
返回值  :无
说明    :读出数据的格式:
            秒 分 时 日 月 星期 年  【共7个字节】
********************************************/
void Get_DS1302(uchar *ptr)
{
    uchar i;
    uchar addr=0x81;
   
    for(i=0;i<7;i++)
    {
        ptr[i]=R_Data(addr);
        addr+=2;
    }
}

/*******************************************
函数名称:disply_time
功    能:将DS1302的时间转换成10进制显示
参    数:无
返回值  :无
********************************************/   
void disply_time(void)
{

    h1[0] = shuzi[2];
    h1[1] = shuzi[0];
    h1[2] = shuzi[times[6]>>4];     //年
    h1[3] = shuzi[times[6]&0x0f];

    h1[4] = shuzi[times[4]>>4];     //月
    h1[5] = shuzi[times[4]&0x0f];

    h1[6] = shuzi[times[3]>>4];     //日
    h1[7] = shuzi[times[3]&0x0f];

    h1[8] = shuzi[times[5]];       //周  
   
    h2[0] = shuzi[times[2]>>4];     //时
    h2[1] = shuzi[times[2]&0x0f];
    h2[2] = 0x3a;       //":"
    h2[3] = shuzi[times[1]>>4];     //分
    h2[4] = shuzi[times[1]&0x0f];
    h2[5] = 0x3a;       //":"
    h2[6] = shuzi[times[0]>>4];     //秒
    h2[7] = shuzi[times[0]&0x0f];
 
 Write_com(0x81);
 Write_dat(h1[0]);//显示年
 Write_dat(h1[1]);
 Write_dat(h1[2]);
 Write_dat(h1[3]);
 DelayUs(10);
  
 Write_com(0x84);
 Write_dat(h1[4]);//显示月
 Write_dat(h1[5]);
 DelayUs(10);
 
 Write_com(0x86);
 Write_dat(h1[6]);//显示日
 Write_dat(h1[7]);
 DelayUs(10);
 
// Write_com(0x8c);
// Write_dat(h1[8]);//显示周
// DelayUs(10);
 
 Write_com(0x92);
 Write_dat(h2[0]);//显示时
 Write_dat(h2[1]);
 DelayUs(10);
 
 LCD_WR_Num(h2[2] - 0x30);//显示":"
 DelayUs(10);
 
 Write_dat(h2[3]);//显示分
 Write_dat(h2[4]);
 DelayUs(10);
 
 LCD_WR_Num(h2[5] - 0x30);//显示":"
 DelayUs(10);
 
 Write_dat(h2[6]);//显示秒
 Write_dat(h2[7]);
 DelayUs(10);
 
 xingqi(h1[8] - 0x30);
}

void xingqi(uchar a)
{
 switch( a )
 {
   case 1 :
        Write_com(0x8b);
     lcd_st("一");//显示周一
     break;
  case 2 :
        Write_com(0x8b);
     lcd_st("二");//
     break;
  case 3 :
        Write_com(0x8b);
     lcd_st("三");//显示周三
     h1[8] = 0;
     break;
  case 4 :
        Write_com(0x8b);
     lcd_st("四");//
     break;
  case 5 :
        Write_com(0x8b);
     lcd_st("五");//显示周五

     break;
  case 6 :
        Write_com(0x8b);
     lcd_st("日");//显示周日
     h1[8] = 0;
     break;
  case 7 :
        Write_com(0x8b);
     lcd_st("天");//显示周末

     break;

 }
  
}

 

 

 

#ifndef __DS18B20_H__
#define __DS18B20_H__

#include "MSP430x14x.h"
#include "12864.h"
#include "delay.h"

#define uchar unsigned char
#define uint  unsigned int

#define DQ1 P1OUT |= BIT1
#define DQ0 P1OUT &= ~BIT1
#define DQ_in   P1DIR &= ~BIT1
#define DQ_out  P1DIR |= BIT1
#define DQ_val  (P1IN & BIT1)

uchar Init_18B20(void);
void Write_18B20(uchar wdata);
uchar Read_18B20(void);
void Skip(void) ;
void Convert(void);
void Read_SP(void);
uint ReadTemp(void);
uint Do1Convert(void);
void display(int dat) ;

 


#endif

 

 

 

#include "ds18b20.h"

float tvalue;
uchar tflag;
uchar disdata[4];

/*******************************************
函数名称Init_18B20
功    能对DS18B20进行复位操作
参    数无
返回值  初始化状态标志1--失败0--成功
********************************************/
uchar Init_18B20(void)
{
    uchar Error;
    DQ_out;
    _DINT();
    DQ0;
    DelayUs(500);
    DQ1;
    DelayUs(50);
    DQ_in;
    _NOP();
    if(DQ_val)      
    {
        Error = 1;          //初始化失败
    }
    else
    {
        Error = 0;          //初始化成功
    }
    DQ_out;
    DQ1;
    _EINT();
    DelayUs(400);
    return Error;

}

/*******************************************
函数名称Write_18B20
功    能向DS18B20写入一个字节的数据
参    数wdata--写入的数据
返回值  无
********************************************/
void Write_18B20(uchar wdata)
{
    uchar i;
    _DINT();
    for(i = 0; i < 8;i++)
    {
        DQ0;
        DelayUs(6);            //延时6us
        if(wdata & 0X01)   
   DQ1;
        else               
   DQ0;        
  wdata >>= 1;
        DelayUs(50);           //延时50us
        DQ1;
        DelayUs(10);           //延时10us
    }
    _EINT();
}

/*******************************************
函数名称Read_18B20
功    能从DS18B20读取一个字节的数据
参    数无
返回值  读出的一个字节数据
********************************************/
uchar Read_18B20(void)
{
    uchar i;
    uchar temp = 0;     
    _DINT();
    for(i = 0;i < 8;i++)
    {
        temp >>= 1;
        DQ0;
        DelayUs(6);            //延时6us
        DQ1;
        DelayUs(8);            //延时9us
        DQ_in;
        _NOP();
        if(DQ_val)  
  {
   temp |= 0x80;
  }
        DelayUs(45);           //延时45us
        DQ_out;
        DQ1;
        DelayUs(10);           //延时10us
    }
    _EINT();
    return  temp;
}
/*******************************************
函数名称Skip
功    能发送跳过读取产品ID号命令
参    数无
返回值  无
********************************************/
void Skip(void)
{
    Write_18B20(0xcc);
}

/*******************************************
函数名称Convert
功    能发送温度转换命令
参    数无
返回值  无
********************************************/
void Convert(void)

{
   Write_18B20(0x44);
}

/*******************************************
函数名称Read_SP
功    能发送读ScratchPad命令
参    数无
返回值  无
********************************************/
void Read_SP(void)
{
    Write_18B20(0xbe);
}

/*******************************************
函数名称ReadTemp
功    能从DS18B20的ScratchPad读取温度转换结果
参    数无
返回值  读取的温度数值
********************************************/
uint ReadTemp(void)
{
    uchar temp_low;
    uint  temp;   
    temp_low = Read_18B20(); //读低位
    temp = Read_18B20();     //读高位
    temp = (temp<<8) | temp_low;    
    return  temp;
}

uint Do1Convert(void)
{
    uchar i; 
    uchar temp_low;
    uint  temp;
    do
    {
        i = Init_18B20();
    }
    while(i); //此处的i就是等于前面的Error,Error = 1,就会出现死循环,表示18B20可能坏了
    Write_18B20(0xcc);//送跳过读取产品ID号命令
    Write_18B20(0x44);//发送温度转换命令
    for(i = 20;i > 0;i--)
 {
        DelayUs(60000); //延时800ms以上
 }
    do
    {
        i = Init_18B20();
    }
    while(i); //此处的i就是等于前面的Error,Error = 1,就会出现死循环,表示18B20可能坏了    
    Write_18B20(0xcc);//送跳过读取产品ID号命令     
    Write_18B20(0xbe);//发送读ROM命令
    temp_low = Read_18B20(); //读低位
    temp = Read_18B20();     //读高位
    temp = (temp<<8) | temp_low;    
    if(temp<0x0fff)
    tflag=0;
    else
   {
    temp=~temp+1;
       tflag=1;
   }
   tvalue = temp*(0.625);//温度值扩大10倍精确到1位小数
   return tvalue;
}

void display(int dat)

 disdata[0]=dat/1000;
 disdata[1]=dat%1000/100;
 disdata[2]=dat%100/10;
 disdata[3]=dat%10;
 Write_com(0x9c);
 Write_dat(disdata[0]+0x30);
 Write_dat(disdata[1]+0x30);
 Write_dat(disdata[2]+0x30);
 Write_dat(0x2e);
 Write_dat(disdata[3]+0x30);
 Write_dat('C');
}

 

 

#ifndef __12864_H__
#define __12864_H__

#include "MSP430x14x.h"
#include "delay.h"


#define  RS_1   (P3DIR |= BIT0,P3OUT |=  BIT0)
#define  RS_0   (P3DIR |= BIT0,P3OUT &= ~BIT0)

#define  RW_1   (P3DIR |= BIT1,P3OUT |=  BIT1)
#define  RW_0   (P3DIR |= BIT1,P3OUT &= ~BIT1)

#define  EN_1   (P3DIR |= BIT2,P3OUT |=  BIT2)
#define  EN_0   (P3DIR |= BIT2,P3OUT &= ~BIT2)

#define  Dat_dir_out  P4DIR |= 0xFF
#define  Dat_out      P4OUT

#define  Dat_dir_in   P4DIR &= 0x00
#define  Dat_in       P4IN

#define uchar unsigned char
#define uint  unsigned int

 

void Read_busy(void);
void Write_com(uchar com);
void Write_dat(uchar dat);
void Lcd_init(void);
void Clear_DDRAM(void);
void set_position(uchar x,uchar y);
void lcd_st(uchar *st);
void LCD_WR_Num(uchar num);
void Draw_PM(const uchar *ptr);
void Clear_GDRAM(void);
void LCDStartInterface1();

#endif

 

 

 

#include "12864.h"

/*************************************************
函数名称:void Read_busy(void)
函数功能:检测液晶是否忙碌,如果忙碌
          就不让MSC进行操作,直到液晶
          将内部处理完,才允许MSC进行
          操作
入口参数:无
出口参数:无
**************************************************/
void Read_busy(void)
{
    Dat_dir_out;
    RS_0;
    RW_1;
    EN_1;
    DelayUs(100);
    Dat_dir_in;
    while((Dat_in & 0X80) != 0);
}
/**************************************************
函数名称:void Write_com(uchar com)
函数功能:向液晶中写命令
入口参数:com 命令
出口参数:无
***************************************************/
void Write_com(uchar com)
{
    Read_busy();
    Dat_dir_out;
    RS_0;
    RW_0;
    EN_1;
    DelayUs(100);
    Dat_out = com;
    DelayUs(100);
    EN_0;   
}

/*************************************************
函数名称:void Write_dat(uchar dat)
函数功能:向液晶写数据
入口参数:dat 数据
出口参数:无
**************************************************/
void Write_dat(uchar dat)
{
     Read_busy();
     Dat_dir_out;
     RS_1;
     RW_0;
     EN_1;
     DelayUs(100);
     Dat_out = dat;
//   _NOP();_NOP();_NOP();
  DelayUs(100);
     EN_0;
}   
/**************************************************
函数名称:void Lcd_init(void)
函数功能:液晶初始化
入口参数:无
出口参数:无
***************************************************/
void Lcd_init(void)
{
    Write_com(0X30);
    Delay_ms(50);
    Write_com(0X01);
    Delay_ms(50);
    Write_com(0X02);
    Write_com(0X0C);
    Delay_ms(50);
}
/**************************************************
函数名称:void Clear_DDRAM(void)
函数功能:清除液晶屏幕上的字符和汉字(字符和汉字
          是液晶库里自带的,不是自定义的)
入口参数:无
出口参数:无
***************************************************/
void Clear_DDRAM(void)
{  
    Write_com(0x01);
}
/**************************************************
函数名称:set_position(uchar x,uchar y)
函数功能:汉字显示坐标位置
入口参数:X选择行;Y所在行的位置
出口参数:无
***************************************************/
void set_position(uchar x,uchar y)
{
 uchar postion;
 switch(x)
  {
  case 0 : x = 0x80;break;//第一行
  case 1 : x = 0x90;break;//第二行
  case 2 : x = 0x88;break;//第三行
  case 3 : x = 0x98;break;//第四行
  default:break; //如果传来的值不在以上范围之内则退出循环
  }
  postion = x + y;//显示位置
  Write_com(postion);//写入液晶
}

/**************************************************
函数名称: lcd_st(uchar *st)
函数功能: 显示字符串和汉字
入口参数: st
出口参数:无
***************************************************/
/*********显示字符串和汉字*******/
void lcd_st(uchar *st) 
{
while(*st != '\0')//如果判断一个汉字没结束时,则执行while语句
 {
 Write_dat(*st);
 st++;//每显示一个汉字,地址指针+1,以便显示下一个汉字
 }
}
/**************************************************
 * 函 数 名:LCD_WR_Num
 * 功能描述:液晶写入一个十进制数;
 * 输入参数:num:要写入的数
 * 返 回 值:无
***************************************************/
void LCD_WR_Num(uchar num)
{
   Write_dat(0x30 + num);

/*******************************************
函数名称:Draw_PM
功    能:在整个液晶屏幕上画图
参    数:无
返回值  :无
********************************************/
void Draw_PM(const uchar *ptr)
{
    uchar i,j,k;
   
 Write_com(0x34);        //打开扩展指令集
 i = 0x80;           
 for(j = 0;j < 32;j++)
 {
        Write_com(i++);
        Write_com(0x80);
    for(k = 0;k < 16;k++)
    {
         Write_dat(*ptr++);
    }
 }
 i = 0x80;
  for(j = 0;j < 32;j++)
 {
      Write_com(i++);
        Write_com(0x88);   
    for(k = 0;k < 16;k++)
    {
          Write_dat(*ptr++);
     }
 } 
    Write_com(0x36);        //打开绘图显示
 Write_com(0x30);        //回到基本指令集
}

/**********************************************
函数名称:void Clear_GDRAM(void)
函数功能:清除因液晶产生的随机数而产生的乱点
入口参数:无
出口参数:无
***********************************************/
void Clear_GDRAM(void)
{
    uchar i,j,k;
    Write_com(0X36);
    i = 0X80;
    for(j=0;j<32;j++)
    {
        Write_com(i++);
        Write_com(0X80);
        for(k=0;k<16;k++)
        {
            Write_dat(0X00);
        }
        DelayUs(10);
    }
    i = 0X80;
    for(j=0;j<32;j++)
    {
        Write_com(i++);
        Write_com(0X88);
        for(k=0;k<16;k++)
        {
            Write_dat(0X00);
        }
        DelayUs(10);
    }
    Write_com(0X30);
}

 

 

 

 

 

 

 

 

 

 

*博客内容为网友个人发布,仅代表博主个人观点,如有侵权请联系工作人员删除。

参与讨论
登录后参与讨论
推荐文章
最近访客