430 F149 DS18B20数码管温度计设计

来源:互联网 发布:c语言全排列函数 编辑:程序博客网 时间:2024/04/27 18:34

基于 149芯片的简易温度计设计,  使用18B20可以精确到小数点后2位,理论上不止。18B20的最小单位是0.0625摄氏度,那么精确没必要,根据实际需要我们设计为2位小数就可以了。 18B20对时序要求非常严格,这里采用定时器定时比较精确。主时钟设置为8M,SMCLK8分频,选用SMCLK时钟为定时器时钟源,即得到1M,定时为us级别的。

贴下代码。

18B20程序:#include <msp430x14x.h>
#include "DS18B20.h"
extern void Delay(unsigned int dly);
unsigned char tem[]={0,0},Neg_flag;
/*******************************************************************************
* Function Name  : void Delayus(unsigned int dly)
* Description    : 延时 dly us
* Input          : dly
* Output         : None
* Return         : None
*******************************************************************************/
void Delayus(unsigned int dly)
{
  CCR0  = dly;
  TACTL|= MC_1;
  while(!(TACTL&BIT0));           //等待时间到
  TACTL &= ~MC_1;                 //停止计数   ??????
  TACTL &= ~BIT0;                 //清中断标志
}
/*******************************************************************************
* Function Name  : unsigned char Init_DS18B20(void)
* Description    : IO 初始化
* Input          : void
* Output         : None
* Return         : None
*******************************************************************************/
unsigned char Init_DS18B20(void)
{
  unsigned char tp;
  DQ_OUT;
  DQ_0;                     //MCU 拉低最少480us 再释放等待DS拉高
  Delayus(500);             //480us~960us
  DQ_1;
  DQ_IN;                    //释放总线
  Delayus(55);              //等15~60us
  _NOP();
  if(DQ_val==BIT6) tp=1;    //初始失败
  else tp=0;                //初始成功
  Delayus(100);             //延时60~240us
  return tp;
}
/*******************************************************************************
* Function Name  : void Write_DS18B20(unsigned char data)
* Description    : 向18B20写数据
* Input          : void
* Output         : None
* Return         : None
*******************************************************************************/
void Write_DS18B20(unsigned char data)
{
  unsigned char i;
  DQ_OUT;
  DQ_1;
  for(i=0;i<8;i++)
  {
    DQ_0;                   //下降沿
    Delayus(10);            //15~60us 等待18B20采样
    if(data&0x01)           //写从低到高位
    {
      DQ_1;
    }   
    else
    {
      DQ_0;
    }
    Delayus(40); 
    DQ_1;
    data>>=1;
    Delayus(2);
  }
}
/*******************************************************************************
* Function Name  : unsigned char Read_DS18B20(void);
* Description    : 读18B20数据
* Input          : void
* Output         : None
* Return         : 18B20数据
*******************************************************************************/
unsigned char Read_DS18B20(void)
{
  unsigned int i, rdata=0;
  DQ_OUT;
  DQ_1;
  for(i=0;i<8;i++)
  {
    rdata>>=1;
    DQ_0;               
    Delayus(2);          //下降沿
    DQ_1;
    DQ_IN;               //释放总线
    Delayus(12);         //15 us内读数据有效
    if(DQ_val==BIT6)
    {
      rdata |= 0x80;     //读从低位开始
    }
    Delayus(45);  
    DQ_OUT;
    DQ_1;
    Delayus(2);
  }
  return rdata; 
}
/*******************************************************************************
* Function Name  : unsigned int Convert_18B20(void);
* Description    : 18B20转换
* Input          : void
* Output         : None
* Return         : None
*******************************************************************************/
void Convert_18B20(void)
{
  unsigned char n;
  do
    n = Init_DS18B20();           //复位
  while(n);
  Write_DS18B20(0xCC);            //跳过 ROm指令
  Write_DS18B20(0x44);            //温度转换 RAM指令
  Delayus(6000);                   //等待750us温度转换完成
  do 
    n = Init_DS18B20();           //复位
  while(n);
  Write_DS18B20(0xCC);            //跳过ROM
  Write_DS18B20(0xBE);;           //读存储器指令 读数据
  tem[0] = Read_DS18B20();        //
  tem[1] = Read_DS18B20();
  Init_DS18B20();
}
/*******************************************************************************
* Function Name  : unsigned int Compute_18B20(unsigned char data);
* Description    : 计算18B20转换后的温度值
* Input          : 16进制的温度值
* Output         : None
* Return         : 十进制的温度值
*******************************************************************************/
unsigned int Compute_18B20()
{
  unsigned int temper=0;
  if(tem[1]&0xF0)
  {
    Neg_flag = 1;                        //负数标志
    temper = tem[0]+tem[1]*256;
    temper = (~temper+1)*0.0625*100;               //取反加一
  }
  else
  {
    temper = (tem[0]+tem[1]*256)*0.0625*100;
  }
  return temper;
}

主函数:

void main(void)
{
  float Te;
  WDTCTL = WDTPW + WDTHOLD;                 // Stop watchdog timer
   /*下面六行程序关闭所有的IO口*/
  P1DIR = 0XFF;P1OUT = 0XFF;
  P2DIR = 0XFF;P2OUT = 0XFF;
  P3DIR = 0XFF;P3OUT = 0XFF;
  P4DIR = 0XFF;P4OUT = 0XFF;
  P5DIR = 0XFF;P5OUT = 0XFF;
  P6DIR = 0XFF;P6OUT = 0XFF;
  P1IES = 0xFF;P1IFG = 0x00;
  Clock_Init();                  // 主频1M
  TACTL|= TASSEL_2+ID_3;
  Display_Init();
  _EINT();
  while(1)
  {
    Convert_18B20();
    Te = Compute_18B20();
    Display(Te,1,4,2);
  }
}