cc2538之ds18b20
来源:互联网 发布:语言翻译软件 编辑:程序博客网 时间:2024/04/29 14:52
18b20,很常见的传感器了,软件编写重点主要就是在one-wire总线的时序上,相关的时序可以参考ds18b20不多做赘述;
本次依然采用作者最熟悉的TinyOS平台+CC2538CB实现,由于ds18b20.c驱动文件直接采用c语言编程,contiki和RIOT也可直接使用,这里我就不移植过去测试了;源码在我的百度网盘;
硬件连接:DQ使用PA5,(上拉)
首先TinyOS部分编写APP;代码如下:
/******************************************************************* *附加实验3:DS18B20测温实验 *节点需求数1 *编译命令make cc2538cb ********************************************************************/#include "printf.h"#include "ds18b20.h"
module TestDS18B20C{ uses interface Boot; uses interface Timer<TMilli> as Timer;}implementation{ unsigned long testdata=0; task void ds18b20_Task(); void print_ds18b20(){ unsigned short result; double temp_data; result = ds18b20_read(); printf("ds18b20:"); printf(" %x ", result); if( result < 0x800 ){ temp_data = result; } else{ printf("-"); temp_data =(~result + 1) & 0x7ff; } temp_data = temp_data * 0.625 + 0.5; result = (unsigned short)(temp_data ); printf(" %d", result/10); printf(".%d", result%10); printf("℃\n"); } /*************************************************** *启动事件 ****************************************************/ event void Boot.booted(){ print_ds18b20(); call Timer.startPeriodic( 5000 ); }/*************************************************** *任务time1_Task ****************************************************/ task void ds18b20_Task(){ print_ds18b20(); } /*************************************************** *Timer1定时时间到事件 ****************************************************/ event void Timer.fired() { /****提交time_Task任务***/ post ds18b20_Task(); } }代码逻辑简单,每5秒读取一次ds18b20的数据;计算后通过串口打印 出来
其中ds18b20_read在ds18b20.c中,代码如下:
#include "hw_memmap.h"#include "gpio.h"#include "hw_gpio.h"#include "ds18b20.h" #define ReSet_18b20_DQ() do{GPIOPinTypeGPIOOutput(GPIO_A_BASE, GPIO_PIN_5); \ HWREG(GPIO_A_BASE + (GPIO_O_DATA + (GPIO_PIN_5 << 2))) &= (~(GPIO_PIN_5));}while(0)#define Set_18b20_DQ() do{GPIOPinTypeGPIOOutput(GPIO_A_BASE, GPIO_PIN_5); \ HWREG(GPIO_A_BASE + (GPIO_O_DATA + (GPIO_PIN_5 << 2))) |= GPIO_PIN_5;}while(0) /*******************************************************************************读取DS18B20 总线状态*******************************************************************************/ unsigned char GetDQ(void){ GPIOPinTypeGPIOInput(GPIO_A_BASE, GPIO_PIN_5); return HWREG(GPIO_A_BASE + (GPIO_O_DATA + (GPIO_PIN_5 << 2)));} /*******************************************************************************复位DS18B20*******************************************************************************/ unsigned long ResetDS18B20(void) { unsigned char is_exsist; unsigned short delay; ReSet_18b20_DQ(); delay = 1250;while(--delay); //500us (该时间的时间范围可以从480到960微秒) Set_18b20_DQ(); delay = 150; while(--delay); is_exsist = 0; if(0 == GetDQ()) is_exsist |= 1; delay = 300;while(--delay);Set_18b20_DQ(); return is_exsist;} /*******************************************************************************写一个字节到DS18B20*******************************************************************************/ void DS18B20WriteByte(unsigned char Dat) { unsigned char i; unsigned short delay; for(i = 8; i > 0; i--) { ReSet_18b20_DQ(); delay = 5;while(--delay); if(Dat & 0x01) Set_18b20_DQ(); else ReSet_18b20_DQ(); delay = 130; while(--delay); Set_18b20_DQ(); delay = 5;while(--delay); Dat >>= 1; } } /*******************************************************************************从DS18B20读取一个字节*******************************************************************************/ unsigned char DS18B20ReadByte( ) { unsigned char i,Dat = 0; unsigned short delay; for(i = 8; i > 0; i--) { Dat >>= 1; ReSet_18b20_DQ(); delay = 5; while(--delay); Set_18b20_DQ(); delay = 5; while(--delay); if(GetDQ()) Dat |= 0x80; delay = 130; while(--delay); Set_18b20_DQ(); } return Dat; } /*******************************************************************************读取DS18B20温度值,读取为两个字节,温度值为0XXXXX *0.0625°C*******************************************************************************/ unsigned short ds18b20_read(void){ unsigned char Temperature1L, Temperature1H; unsigned short Temperature; unsigned long delay; if(0 == ResetDS18B20()){ return 0x88; //可以 自定义返回 未检测到ds18b20的接入 } DS18B20WriteByte(SkipROM); DS18B20WriteByte(StartConvert); delay = 1800000;while(--delay); ResetDS18B20(); DS18B20WriteByte(SkipROM); DS18B20WriteByte(ReadScratchpad); Temperature1L= DS18B20ReadByte(); Temperature1H= DS18B20ReadByte(); ResetDS18B20(); Temperature = 0; Temperature = Temperature1H; Temperature <<= 8; Temperature |= Temperature1L; return Temperature; }
编译后下载到cc2538cb节点运行效果如下图:
需要注意的是可以去看cc2538的手册;IO口的读取真实电平必须先配置该IO口为输入,因为2538的IO口在输出状态下,不管实际电平是否变化,始终读取上一次软件output IO口的值;
0 0
- cc2538之ds18b20
- 7、RIOT操作系统中 CC2538采集ds18b20源码共享
- CC2538之TinyOS例程实验:2-printf
- CC2538之Contiki3.0实验:3-event
- CC2538之Contiki3.0实验:4-Sensor
- {嵌入式}之DS18B20
- ds18b20
- DS18B20
- DS18B20
- DS18B20
- DS18B20
- DS18B20
- DS18B20
- DS18B20
- ds18b20
- DS18B20
- ds18b20
- ds18b20
- Http 协议 常用消息头
- Java基础09 类数据与类方法
- poj 3311 送披萨 状压dp
- Tomcat 闪退问题方案
- string和stringstream用法总结
- cc2538之ds18b20
- MAC_Mac使用心得分享
- OpenCV矩阵运算
- UI用塑料泡沫设计草图
- sublime text 安装和使用技巧一
- boolean值及switch case判断
- Fragment+ViewPager网络请求数据问题
- Quartz 线程处理
- kafka 原理精选