一、简介
本文介绍如何在SimpleBLEPeripheral工程中,采集ds18b20的温度值,在OLED上显示
二、实验平台
编译环境:IAR820.02
协议栈:BLE-CC254x-1.40
代码查看器:Source Insight 3.5
硬件平台:SmartRf 开发板
安卓APP平台: SmartRf
三、编写声明
作者:爱已oО欠费
相关CC2541群:606444519
淘宝小店:https://item.taobao.com/item.htm?spm=a1z10.3-c-s.w4023-16306486995.5.hdKUUO&id=548576956486
四、实验前提
请完成以下博文:
因为采集的数据由OLED显示出来,所以要先实现OLED能正常显示
可以参考【cc2541历程】替换协议栈LCD文件:http://blog.youkuaiyun.com/wangjiawu7/article/details/70246299
四、相关电路
板子上DHT11和DS18B20公用一个接口
六、实验步骤
1.
1)创建一个ds18b20.c文件和一个ds18b20.h文件.
存放在(F:\2541学习历程\cc2541\6.温度传感器ds18b20\BLE-CC254x-1.4.0\Projects\ble\SimpleBLEPeripheral\Source)文件夹里
2)编辑ds18b20.c文件
代码如下:
#include<ioCC2541.h>
#include "stdio.h"
#include "ds18b20.h"
/**************************************************
移植此函数,需要修改相应的宏定义和相应的延时函数
**************************************************/
void DQ_Input(void)//设置端口为输入
{
P0DIR &= 0xfe;
}
void DQ_Output(void)//设置端口为输出
{
P0DIR |= 0x01;
}
//延时函数
void delay_us(unsigned int k)
{
unsigned int i,j;
for(i=0;i<k;i++)
for(j=0;j<2;j++);
}
//写Ds18b20数据
void Write_ds18b20(unsigned char cmd)
{
unsigned char i;
DQ_Output(); //设置为输出//设置IO为输出,2530->DS18B20
for(i=0;i<8;i++)
{
DQ =0;
delay_us(1);
DQ = cmd&0x01;
delay_us(40); // 15-60us
DQ = 1;
cmd >>= 1;
}
}
//写Ds18b20数据
unsigned char Read_ds18b20(void)
{
unsigned char i,temp =0;
DQ_Output(); //设置为输出
DQ = 1;
delay_us(10);
for(i=0;i<8;i++)
{
DQ_Output(); //设置为输出
DQ = 0; // 给脉冲信号
delay_us(2);
DQ = 1; // 给脉冲信号
delay_us(2);
DQ_Input(); //设置为输入
if(DQ == 1) temp |= 1<<i;
delay_us(70); //60 -120us
}
return temp;
}
//ds18b20初始化 初始化成功返回0x00,失败返回0x01
unsigned char ds18b20_Init(void)
{
unsigned char Status = 0;
unsigned int cnt = 0;
DQ_Output(); //DQ设置为输出
DQ = 0; //单片机将DQ拉低
delay_us(650); //精确延时 大于 480us 小于960us
DQ = 1; //拉高总线
delay_us(100); //稍做延时
DQ_Input(); //设置IO输入
do
{
if(DQ != 0)
break;
cnt++;
}while(cnt<500);
DQ_Output(); //设置为输出
DQ = 1;
return Status; //返回初始化状态
}
float Get_temp(void)
{
unsigned char temp_l, temp_h; //定义8位缓冲器
unsigned int temp; //定义温度缓冲寄存器
float temperature;
ds18b20_Init();
Write_ds18b20(0xcc); // 跳过读序号列号的操作
Write_ds18b20(0x44); // 启动温度转换
ds18b20_Init();
Write_ds18b20(0xcc); //跳过读序号列号的操作
Write_ds18b20(0xbe); //读取温度寄存器等(共可读9个寄存器) 前两个就是温度
temp_l = Read_ds18b20(); //低位
temp_h = Read_ds18b20(); //高位
//temp = ((V1 >> 4)+((V2 & 0x07)*16)); //转换数据
temp=temp_h*0xFF+temp_l;
temperature = temp*0.0625;
return temperature;
}
3)编辑ds18b20.h文件
代码如下:
#ifndef __DS18B20_H__
#define __DS18B20_H__
#include"iocc2541.h"
#define DQ P0_0 //温度传感器引脚
unsigned char ds18b20_Init(void);
float Get_temp(void);
void delay_us(unsigned int k);
#endif
4)在工程中添加相应的ds18b20.c文件和ds18b20.h文件
单击左上角工程SimpleBLEPeripheral.ewp->App->右键->Add->
然后选择路径(F:\2541学习历程\cc2541\6.温度传感器ds18b20\BLE-CC254x-1.4.0\Projects\ble\SimpleBLEPeripheral\Source)中添加
先选中文件,然后打开就可以添加进去了
2.定义ds18b20相关事件
1)定义ds18b20相关事件(SimpleBLEPeripheral.c中)
添加相应的头文件:ds18b20.h和stdio.h
2).在uint16 SimpleBLEPeripheral_ProcessEvent函数中代码做相应修改(SimpleBLEPeripheral.c中)
代码如下:
uint16 SimpleBLEPeripheral_ProcessEvent( uint8 task_id, uint16 events )
{
VOID task_id; // OSAL required parameter that isn't used in this function
if ( events & SYS_EVENT_MSG )
{
uint8 *pMsg;
if ( (pMsg = osal_msg_receive( simpleBLEPeripheral_TaskID )) != NULL )
{
simpleBLEPeripheral_ProcessOSALMsg( (osal_event_hdr_t *)pMsg );
// Release the OSAL message
VOID osal_msg_deallocate( pMsg );
}
// return unprocessed events
return (events ^ SYS_EVENT_MSG);
}
if ( events & SBP_START_DEVICE_EVT )
{
// Start the Device
VOID GAPRole_StartDevice( &simpleBLEPeripheral_PeripheralCBs );
// Start Bond Manager
VOID GAPBondMgr_Register( &simpleBLEPeripheral_BondMgrCBs );
// P0SEL &= 0xfe; //DS18B20的io口初始化
// Set timer for first periodic event 注释掉否则连接不稳定
osal_start_timerEx( simpleBLEPeripheral_TaskID, SBP_PERIODIC_EVT, SBP_PERIODIC_EVT_PERIOD );
return ( events ^ SBP_START_DEVICE_EVT );
}
if ( events & SBP_PERIODIC_EVT )
{
// Restart timer
//if ( SBP_PERIODIC_EVT_PERIOD )
//{
performPeriodicTask();
osal_start_timerEx( simpleBLEPeripheral_TaskID, SBP_PERIODIC_EVT, SBP_PERIODIC_EVT_PERIOD );
// }
//周期执行事件
// Perform periodic application task
// performPeriodicTask();
return (events ^ SBP_PERIODIC_EVT);
}
// Discard unknown events
return 0;
}
3).在static void performPeriodicTask( void )函数中代码做相应修改
代码如下:
static void performPeriodicTask( void )
{
EA = 0;// 因为是 io 口读写, 所以为了避免干扰, 需要关中断
float ds18b20_temp = Get_temp();
EA = 1;
// 显示温度
char str[32];
sprintf(str, "ds18b20 : %.2f", ds18b20_temp);
HalLcdWriteString( str, HAL_LCD_LINE_1 );
HalLcdWriteString( " ", HAL_LCD_LINE_2 );
}
七.实验结果:
下1.编译无误,下载,ok。OLED第一行显示ds18b20温度值.实验成功