zyh_126

cc2430驱动ds18b20

0
阅读(15783)

2430驱动其他设备时输入输出口转换的问题,即2430的IO口不是像51那样直接做输入输出用,而是用PXDIR随时作输出/输 入的转换吗? 本来是说昨天在这里报告的,结果有些事情耽误了,今天在这里报告一下,驱动成功了,用了

#define P00_OUT       P0DIR|=0x01//设置为输出口
#define    P00_IN        P0DIR&=0xfe//设置为输入口

在每次要用输入或者输出前加上,因为晶振很快(CC2430不做设定,默认为16Mhz)所以对时序影响还是蛮小的。

另外本人的程序是借鉴了如下两位的程序,在此贴出来网址,希望能对大家有用,由于刚出来,所以我的程序还没有整理,不过整理后会发上来。
 

网上有很多关于ds18b20的程序,但是就是没有找到在cc2430上的,今天奉上吧。

其中的delay函数参考了ti zstack中的MicroWait函数.最后数据显示在128*64的液晶上。

void Delay_nus(uint16 s) {
  while (s--)
  {
    asm("NOP");
    asm("NOP");
    asm("NOP");
  }
}

/********************************************************************* 
*文件名:18B20.c
*功能:DS18B20温度采集
* @data:2009.4.24
* by mchen
*********************************************************************/ 
#include "18b20.h"
#include "LCD128_64.h"

unsigned char id[8];
unsigned char sensor_data_value[2];
unsigned char flag;

void Delay_nus(uint16 s) {
  while (s--)
  {
    asm("NOP");
    asm("NOP");
    asm("NOP");
  }
}
void write_1820(unsigned char x) 
{  unsigned char m;   
    SET_OUT;
    for(m=0;m<8;m++) 
    { 
       CL_DQ;
       if(x&(1<<m))    //写数据,从低位开始 
       SET_DQ;
       else 
       CL_DQ; 
       Delay_nus(40);   //15~60us 
       SET_DQ; 
    }
    //SET_OUT;
    SET_DQ; 

unsigned char read_1820() 
{   unsigned char temp,k,n;   
    temp=0; 
    for(n=0;n<8;n++) 
       { 
      CL_DQ;    
      SET_DQ;
      SET_IN; 
      k=IN_DQ;    //读数据,从低位开始 
      if(k) 
      temp|=(1<<n); 
      else 
      temp&=~(1<<n); 
      Delay_nus(70); //60~120us     
      SET_OUT;

   } 
   return (temp); 

//搜索ID
void get_id()
{    
     init_1820();        //resert
     write_1820(0x33);
   
     for(unsigned char ii=0;ii<8;ii++)
     {id[ii]=read_1820();
     }
}
/*功能匹配*/
BYTE match_rom(unsigned char *rom)
{
 unsigned char i;
 init_1820();
 write_1820(0x55);
 for(i=8;i>0;i--)
 {
          write_1820(*(rom+i-1));
 }
 return 1;
}

BYTE init_1820(void)
{
   //cli();
  SET_OUT;
  SET_DQ;//输出1
  CL_DQ;
  Delay_nus(550);//拉低一段时间
  SET_DQ;//释放
  SET_IN;//输入
  Delay_nus(40); //释放总线后等待15-60us
  while(IN_DQ)  {;}//等待回复
  Delay_nus(240);//回复的低电平在60到240us 
  SET_OUT;
  SET_DQ;//回到初始DQ=1;
  return 1;
 }
 
 void read_data(unsigned char *serial)
 {
    unsigned int j;
    unsigned char temh,teml;
    unsigned char a,b,c;
 
    init_1820();  //复位18b20 
    write_1820(0xcc);   // 发出转换命令 搜索器件
    write_1820(0x44);     //启动
    for(j=20;j>1;j--) 
    Delay_nus(50000);
    init_1820(); 
   // write_1820(0xcc);
    match_rom(serial);   //匹配
    write_1820(0xbe);
        
    teml=read_1820();  //读数据 
    temh=read_1820(); 
    if(temh&0x80)//判断正负
    {
      flag=1;
      c=0;
      c=c|temh;
      c=c&0x00ff;
      c=c<<8;
      a=c;
 
      a=c|teml;
 
      a=(a^0xffff);//异或
      a=a+1;  //取反加1
      teml=a&0x0f;
      temh=a>>4;
    }
    else
    {
      flag=0;   //为正
      a=temh<<4;
      a+=(teml&0xf0)>>4; //得到高位的值
      b=teml&0x0f;
      temh=a;
      teml=b&0x00ff;
    }
    sensor_data_value[0]=teml;
    sensor_data_value[1]=temh;
 }

   
////////////处理数据部分/////////////////
 void DataChange(unsigned char Temp_channel)
 {
   unsigned char temh,teml;
   unsigned char ch[9];
   unsigned int num;
   unsigned i;
  
   teml=sensor_data_value[0];
   temh=sensor_data_value[1];
   i=(Temp_channel-0x31)*2;
   ch[0]=Temp_channel;//当前显示的传感器的编号
   ch[1]=' ';
   num=teml*625;          //小数部分的取值每位代表0.0625(精度)
   if(flag==1)            //判断正负温度
   {
     ch[2]='-';              //+0x2d 为变"-"ASCII码
   }
   else ch[2]='+';  
   if(temh/100==0)
     ch[3]=' ';
   else ch[3]=temh/100+0x30;      //+0x30 为变 0~9 ASCII码
   if((temh/10%10==0)&&(temh/100==0))
     ch[4]=' ';
   else ch[4]=temh/10%10+0x30;
   ch[5]=temh%10+0x30;
   ch[6]='.';
   ch[7]=num/1000+0x30;//忽略小数点后1位的数
   ch[8]='\0';
   Print(i,15,ch,1);   //显示温度值
   Print(i,80,"℃",1); //显示摄氏度标示  ℃
 }
void ds18b20_main()
{
  unsigned char i=0;
  while(1){
    read_data(get_serial+i*8);// 读取温度
    DataChange(i+0x31); //数据处理
    i++ ;
    if(i==4) i=0;
  }
}

// **************************************************
//
// * @this is 18B20 driver code head
// * @data:2009.4.24
// * by mchen
// **************************************************

#ifndef b20_H
#define b20_H

#include "ioCC2430.h"
#include "hal.h"

#define CL_DQ  P0_4=0
#define SET_DQ P0_4=1
#define SET_OUT P0DIR|=0x10
#define SET_IN  P0DIR&=~0x10
#define IN_DQ  P0_4

 extern unsigned char id[8];

 static unsigned char get_serial[]={
  0x1C,0x00,0x00,0x02,0x02,0x68,0xd8,0x28,
  0x9E,0x00,0x00,0x02,0x02,0x93,0x34,0x28,
  0xE4,0x00,0x00,0x02,0x02,0x66,0x4D,0x28,
  0xE6,0x00,0x00,0x02,0x02,0x93,0x9B,0x28
  //0xF7,0x00,0x00,0x02,0x02,0x75,0xE1,0x28
 };

 extern unsigned char sensor_data_value[2];
 //void Delay_1us(void);
 void Delay_nus(uint16 n) ;
 void write_1820(unsigned char x) ;
 unsigned char read_1820(void); 
 void init_1820(void) ;
 void read_data(unsigned char *serial);
 void get_id(void);
 void ds18b20_main(void);
#endif