cc2430驱动ds18b20
0赞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
