⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ds1820.c

📁 msp430单片机读写温度传感器DS18b20的程序
💻 C
字号:
 //文件名:MC430F14_DEMO_5.c
  //版本: 1.0
  //描述:MC430F14开发板的主程序,MSP430对DS18B20操作,将读取的温度显示在LCD上。
  //编程环境:IAR WE430 3.40A
  //编写: www.microcontrol.cn  DC
  //时期: 2006.10.21.

#include <msp430x14x.h>
 #include "DS1820.h"
 #include "lcd_ch.h"

 #define DQ1 P5OUT|=BIT7              //DQ=1
 #define DQ0 P5OUT&=~BIT7              //DQ=0

 const unsigned char digit[10] = {'0','1','2','3','4','5','6','7',
 '8','9'};

 unsigned char temp_display [9] = {'x','0','0','0','.','0','0','0','\0'};

//将温度值转换成可显示十进制值
//取数范围整数3位,小数点后3位.
void display_number(float f_data)
{ unsigned long value;
  float n;
  n=f_data *1000;
  value = (unsigned long int)n;

  temp_display[1] = digit[value/100000];          //100位
  value = value%100000;

  temp_display[2] = digit[value/10000];           //10位
  value = value%10000;

  temp_display[3] = digit[value/1000];            //1位
  value = value%1000;

  temp_display[5] = digit[value/100];             //0.1位
  value = value%100;

  temp_display[6] = digit[value/10];              //0.01位
  value = value%10;

  temp_display[7] = digit[value/1];               //0.001位
}
//--------------------------------------------------------------------


//说明:实验标题1,应用单实形式发送.
void send_title()           //标题显示
{
  sendCMD(off_cursor);      //关光标
  sendCMD(LCD_L11);
  display(LCD_L11,0xca,0xd4);  //试
  display(LCD_L12,0xd1,0xe9);  //验
  //sendDAT('D');  sendDAT('S'); sendDAT('1'); sendDAT('8');
  //sendDAT('2'); sendDAT('0');
  display(LCD_L13,0xca,0xd2);  //室
  display(LCD_L14,0xb5,0xb1);  //当
  display(LCD_L15,0xc7,0xb0);  //前
  display(LCD_L16,0xce,0xc2);  //温
  display(LCD_L17,0xb6,0xc8);  //度
  //display(LCD_L25,0xce,0xaa);  //为
  sendCMD(LCD_L21);             //显示地址指回处
  sendCMD(off_cursor);                            //关光标
}
//---------------------------------------------------------------------

//MSP430F14初始化
void mcuinit(void)
 {
 P1DIR |=BIT1;                                  //P1.1驱动LED
   P5DIR |=BIT7;                                  //设DQ电时为1
   DQ1;
   initlcm();                                     //LCD初始化
   send_title();                                  //显示实验标题
 }

//---------------------------------------------------------------------

//MC430F14 DS18B20实验主程序
void main(void)
 {
  WDTCTL = WDTPW + WDTHOLD;                       // 停止WDT
  mcuinit();
  while(1)
  {
   GetTemp();                                     //读取温度

   if(symbol==1)
      temp_display[0] = '+';                      //处理正负符合
   else
       temp_display[0] = '-';

   if(Error==1)
   { display(LCD_L26,0xca,0xa7);  //失
     display(LCD_L27,0xb0,0xdc);  //败
   }
   else
   { display(LCD_L26,0xd5,0xfd);  //正
     display(LCD_L27,0xc8,0xb7);  //确
   }
   P1OUT ^= BIT1;
   display_number(Temper);                      //数据变换显示数据
   char_string (temp_display,LCD_L21);
  }
 }
//END--------------------------------------------------------------


//文件名:MC430F14_DEMO_5.h
//版本: 1.0
//描述:程序声明
//编程环境:IAR WE430 3.40A
//编写: www.microcontrol.cn  DC
//时期: 2006.10.21

 //例程解说: 将DS18B20的变量及程序声明,供外部程序使用

//END--------------------------------------------------------------


//文件名:MSP430_DS18B20.c
//版本: 1.0
//描述:MC430F14开发板的MSP430与DS18B20操作主程。
//编程环境:IAR WE430 3.40A
//编写: www.microcontrol.cn  DC
//时期: 2006.10.21

#include <msp430x14x.h>

//定义一个位设置,这样可以简化程序编写
#define DQ1 P5OUT|=BIT7            //DQ=1
#define DQ0 P5OUT&=~BIT7      //DQ=0
#define DQIO_OUT P5DIR|=BIT7    //设为输出
#define DQIO_IN  P5DIR &= ~BIT7 //设为输入

#define positive 0x0f           //正温系数

//定义
unsigned char Error = 0;
float   Temper=0.0;            //真正有效温度值
int     temperature=0;            //读取两字节温度数据
unsigned char symbol = 1 ;      //温度正负符号

//----------------------------------
//功能:us 级别延时
// n=10,则延时10*5+6=56uS
//----------------------------------
void DelayNus(unsigned int n)
 {
    while(n--){};
 }
//-----------------------------------


//功能:写18B20
//-----------------------------------
void Write_18B20(unsigned char n)
{
    unsigned char i;
    for(i=0;i<8;i++)
    {
        DQ0;
        _NOP();_NOP();            //延时5us
        _NOP();_NOP();_NOP();
        if((n&0X01)==0X01)      //DQ=1
          DQ1;
        else
         DQ0;                   //DQ=0
        n=n>>1;                  //下一位
        DelayNus(6);            //延时50us 以上
        DQ1;
    }
}
//------------------------------------


//功能:读取18B20
//------------------------------------
unsigned char Read_18B20(void)
{
    unsigned char i;
    unsigned char temp;
    for(i=0;i<8;i++)
    {
        temp=temp>>1;            //移向下一位
        DQ0;
        _NOP();                  //延时1us
        DQ1;
        _NOP();_NOP();            //延时5us
        _NOP();

        DQIO_IN;            //DQ口设为输入
      if((P5IN&BIT7)==0)      //DQ是否等于0
          {
            temp=temp&0x7F;      //读入DQ为0
          }
      else
        {
         temp=temp|0x80;      //读入DQ为1
        }

      DelayNus(5);            //延时40us
      DQIO_OUT;                    //DQ口设为输出
      DQ1;                  //DQ输出1
    }
    return    temp;            //返回一个数据
}
//-----------------------------------


//复位说明:复位要求主CPU将数据线下拉500us,然后释放,
//当DS18B20收到信号后等待16~60us左右,后发出60~240微秒的存在低脉冲,
//主CPU收到此信号表示复位成功。
//初始化DS18B20
void Init (void)
{
    DQ0;
    DelayNus(50);            //延时500us
    DQ1;
    DelayNus(12);            //延时16~60us

    DQIO_IN;                    //设DQ为输入
    if((P5IN&BIT7)==BIT7)        //1000 0000b=1f,DQ是否为1
     {
     // Error =1;                //失败1
      DQIO_OUT;                    //设DQ为输输出
     }
    else
     {
      Error = 0;            //初始化成功
      DQIO_OUT;                    //设DQ为输输出
      DQ1;
     }
}
//----------------------------------

//指令描述:跳过ROM命令,指定代码为CCH,忽略64位ROM地址,直接向DS1820发温度变换
//命令,适用于单片机工作.
void Skip(void)
{
    Write_18B20(0xcc);
}
//----------------------------------

//指令描述:温度转换命令,指定代码为44H.启动DS1820进行温度转换,12位转换时最长
//为750ms(9位为93.75ms).结果存入内部9字节RAM中.
 void Convert (void)
 {
    Write_18B20(0x44);
  }
//----------------------------------

//指令描述:读暂存器,指定代码为BEH.读内部RAM中9字节的内容.
  void ReadDo (void)
  {
    Write_18B20(0xbe);
  }
//----------------------------------

//读取温度值
void ReadTemp (void)
 {
    char temp_low,  temp_high;      //温度值
    temp_low = Read_18B20();      //读低位
    temp_high = Read_18B20();      //读高位

    if((temp_high|positive)==positive)
        symbol=1;                //测到的温度为正
    else
        symbol=0;                //测到的温度为负

    temperature=(temp_high&0x0f);//屏蔽高4位
    temperature<<=8;            //将temp_high部分数据移到temperature高8位
    temperature|=temp_low;      //将高低两字节内部合并成一个16位数据

    if(symbol==0)                       //是否为负温度
     { temperature = (~temperature)+1;   //将其取反后加1
     }
    Temper=temperature*0.0625;      //计算真实温度值
 }
//----------------------------------

//MCU对DS18B20进行温度转换时,其操作必须满足以下过程:
// 1- 每一次读写之前都要对DS18B20进行复位.
// 2- 完成复位后发送一条ROM命令到DS18B20.
// 3- 最后发送一条RAM命令到DS18B20.
// 以上系列动作是根据DS18B20的通讯协议所得.
//读取温度
void GetTemp(void)
 {
        Init();                  //DS1820初始化
        Skip();                  //跳过64位ROM(ROM命令)
        Convert();            //转换(RAM命令)
        DelayNus(60000);        //60000x5us=0.3s
        DelayNus(60000);        //0.3s
        DelayNus(60000);      //0.3s
        Init();                  //DS1820初始化
        Skip();                  //跳过64位ROM
        ReadDo();            //读暂存器
        ReadTemp();            //读取温度值
 }
//END--------------------------------------------------------------

//LCD型号:KM12232F(ST7920A),连接模式:串口模式,供电:3V.
//KM12232F是内带汉字库,只须提供汉字内码地址给LCD模块即可.
//MCU:TI MSP430F1121. SID-->P4.6,SCK-->P4.7
//C编译器:IAR Embedded Workbench IDE 3.2
//编写日期:2004.7.
//编写提供:DC Huang
# include <msp430x14x.h>

#define SID 0x40                  //串行数据输入端
#define SCK 0x80                  //同步时钟输入端
#define DDRAM_0    0x80           //显示回位
#define off_cursor 0x0c           //关闭光标
#define on_cursor  0x0e           //开光标
#define off_cursor_filsh  0x0e    //光标关闪烁
#define on_cursor_filsh  0x0f     //光标开闪烁

#define GM12232_MINADD_L1 0x80    //第一行第一位地址
#define GM12232_MAXADD_L1 0x87    //第一行最后地址
#define GM12232_MINADD_L2 0x90    //第二行第一位地址
#define GM12232_MAXADD_L2 0x97    //第二行最后地址

//**************************************************
void delay(void)
{ char i;
  for (i = 0;i != 0xff;i++);
}
//**************************************************
void sendBYTE(char dat)       //串行传送一字节数据
{
 char i;
 P4DIR|=SID;                  //设P1.3 SID为输出
 for (i=0;i<8;i++)
   {
    P4OUT&=~SCK;              //SCK=0
    if((dat & 0x80)!=0)
      P4OUT|=SID;             //SID=1
    else
     P4OUT&=~SID;             //SID=0
     P4OUT|=SCK;              //SCK=1;
     dat = dat<<1;
   }
}

//****************************************************
//如果需要改变半字地址,也是用此程序.只需输入地址就可以.
void sendCMD(char dat)        //写控制指令
{
 sendBYTE(0xf8);
 sendBYTE(dat & 0xf0);
 sendBYTE((dat<<4)&0xf0);
}
//****************************************************
void sendDAT(char dat)//写显示数据;也可以写一个单字节字符
{
 sendBYTE(0xfa);
 sendBYTE(dat & 0xf0);
 sendBYTE((dat<<4)&0xf0);
}
//****************************************************
void display(char x_add,char dat,char dat1)
//写汉字到LCD屏指定位置
//x_add显示RAM地址
//dat/dat1显示汉字编码
{
 sendCMD(x_add);
 sendDAT(dat);
 sendDAT(dat1);
}
//*****************************************************
void initlcm(void)//初始化LCM
{
 delay();
 P4DIR|=SCK;   //SCK设为输出
 sendCMD(0x30);//功能设置:一次送8位数据,基本指令集
 sendCMD(0x04);//点设定 :显示字符/ 光标从左到右移位,DDRAM地址加一
 sendCMD(0x0f);//显示设定:开显示 ,显示光标,当前显示位反白闪动
 sendCMD(0x0f);//显示设定:开显示,显示光 标,当前显示位反白 闪动
 sendCMD(0x01);//清DDRAM
 sendCMD(0x02);//*DDRAM 地址归位
}

//****************************************************
//发送半角数字和字母字符串
//*p为字符串指针
//x_add 所要显示的地址
void char_string (unsigned char *p, unsigned char x_add)
{
  unsigned char n;
  if((x_add >= GM12232_MINADD_L1)&&(x_add <GM12232_MAXADD_L1))
    { sendCMD(x_add);
      for (n=0; p[n]!='\0'; n++)
       { sendDAT(p[n]); }
    }
  else if ((x_add >= GM12232_MINADD_L2)&&(x_add <GM12232_MAXADD_L2))
   { sendCMD(x_add);
     for (n=0; p[n]!='\0'; n++)
       { sendDAT(p[n]); }
   }
  else
    return ;
}













⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -