本帖最后由 fesxp 于 2015-8-1 21:39 编辑
本实例基于STM32W108的SimpleMac协议栈,利用无线节点完成对温度、湿度、超声波、烟雾、声音、光敏等传感器的控制及数据采集,并实时将数据发送到STM32W108开发板,完成传感器数据的汇集,并通过串口传送给PC机。
13.4 传感器数据采集程序设计与实现
下面将根据不同的传感器分别进行传感器数据采集程序的设计说明,最后给出数据包的发送、接收及主函数部分的详细内容。
13.4.1 温度传感器
temperature.h文件内容:
#ifndef __TEMPERATURE_H__
#define __TEMPERATURE_H__
#define TEMP_BUS PORTA_PIN(5) //PA5
#define TEMP_BUS_INPUT_GPIO GPIO_PAIN //端口A输入寄存器
#define TEMP_BUS_OUTPUT_GPIO GPIO_PAOUT //端口A输出寄存器
#define TEMP_BUS_GPIO_PIN PA5_BIT //PA5_BIT的值为4
#define TEMP_BUS_WAKE_SOURCE 0x00000080
#define TEMP_BUS_SET (GPIO_PASET_ADDR+((GPIO_PBCFGL_ADDR
-GPIO_PACFGL_ADDR)*(TEMP_BUS/8)))
#define TEMP_BUS_CLR (GPIO_PACLR_ADDR+((GPIO_PBCFGL_ADDR
-GPIO_PACFGL_ADDR)*(TEMP_BUS/8)))
extern u16 Read_Temperature();// 读温度函数
#endif
temperature.c文件:
#include PLATFORM_HEADER
#include BOARD_HEADER
#include "temperature.h"
#include "hal/micro/micro-common.h"
#include "hal/micro/cortexm3/micro-common.h"
#define LOW 0//低电平
#define HIGH 1//高电平
/**************************************************************************
功能描述:设置端口,将端口置高或置低
输入参数:status:电平的参数,高电平或低电平
输出参数:无
*************************************************************************/
static void SetPort(int8u Statu)
{
halGpioConfig(TEMP_BUS, GPIOCFG_OUT); //设置总线为输出状态
if(TEMP_BUS/8 < 3)
{
if(Statu==HIGH)//高电平
*((volatile int32u *)TEMP_BUS_SET) = BIT(TEMP_BUS&7); //设置寄存器bit4
else
*((volatile int32u *)TEMP_BUS_CLR) = BIT(TEMP_BUS&7); //清除寄存器bit4
}
}
/**************************************************************************
功能描述:获取端口状态
输入参数:无
输出参数:u8类型值,1或0,0表示低电平,1表示高电平
*************************************************************************/
u8 GetPort()
{
halGpioConfig(TEMP_BUS, GPIOCFG_IN); //设置总线为输入状态
//bit4为1返回1,为0返回0
return (TEMP_BUS_INPUT_GPIO & (1<<TEMP_BUS_GPIO_PIN))?1:0;
}
/**************************************************************************
功能描述:实现us级延时
输入参数:int32u类型变量,延迟时间
输出参数:无
*************************************************************************/
void Delay_1us(int32u x)
{
halCommonDelayMicroseconds(x); //延时x us
}
/**************************************************************************
功能描述:对DS18B20进行复位操作
输入参数:无
输出参数:无
*************************************************************************/
void DS18B20_Reset()
{
SetPort(LOW); //输出低电平,拉低总线
Delay_1us(500); //延迟500us
SetPort(HIGH); //释放总线
Delay_1us(60); //延迟60us
while(GetPort()); //等待从机DS18B20应答(低电平有效)
while(!GetPort()); //等待从机DS18B20释放总线
}
/**************************************************************************
功能描述:向DS18B20写一个字节
输入参数:u8类型变量,写入DS18B20的数据
输出参数:无
*************************************************************************/
void DS18B20_Write(u8 Data)
{
u8 i;
for(i=0;i<8;i++)
{
SetPort(LOW); //拉低总线
Delay_1us(10); //延迟10us(最大15us)
SetPort(Data&0x01); //将数据的最低位写出
Delay_1us(40); //延迟40us(最大45us)
SetPort(HIGH); //释放总线
Delay_1us(1); //稍微延迟
Data>>=1;
}
}
/**************************************************************************
功能描述:从DS18B20读一个字节
输入参数:无
输出参数:u8类型变量,从DS18B20读取的一个字节数据
*************************************************************************/
u8 DS18B20_Read()
{
u8 i,dat;
for(i=0;i<8;i++)
{
SetPort(LOW); // 拉低总线,启动输入
Delay_1us(1); // 延迟1us
SetPort(HIGH); // 释放总线
dat = (GetPort() << 7) | (dat >> 1);//最先读出的是最低位数据
Delay_1us(45); // 延迟 45us(最大45us)
}
return dat;
}
/**************************************************************************
功能描述:读取当前温度,利用DS18B20进行温度的采集
输入参数: 无
输出参数:u16类型变量,读取的温度值,当前温度值=返回值/100
*************************************************************************/
u16 Read_Temperature()
{
u8 Temp1,Temp2;
//DS18B20 开始转换:
DS18B20_Reset(); //DS18B20 复位
DS18B20_Write(0xCC); // 跳过 ROM
DS18B20_Write(0x44); // 温度转换
Delay_1us(800); // 延迟 750~900us
//DS18B20 读暂存数据:
DS18B20_Reset(); //DS18B20 复位
DS18B20_Write(0xCC); // 跳过 ROM
DS18B20_Write(0xbe); // 读取 RAM
Temp1=DS18B20_Read(); // 读低八位, LS Byte, RAM0
Temp2=DS18B20_Read(); // 读高八位, MS Byte, RAM1
DS18B20_Reset(); //DS18B20 复位,表示读取结束
//对于负数,转换成整数之后进行单位转换,然后再重新转换回负数补码形式
if(Temp2&0xFC)
return (u16)((~((u16)(((~((Temp2<<8)|Temp1))+1)*6.25)))+1); // 高八位第八位进行整
else
return (u16)(((Temp2<<8)|Temp1)*6.25); //0.0625=xx, 0.625=xx.x, 6.25=xx.xx
}
13.4.2 温湿度传感器
DH11.h文件:
#ifndef __DH11_H__
#define __DH11_H__
#define DBUS PORTC_PIN(6) //PC6引脚
#define DBUS_INPUT_GPIO GPIO_PAIN //输入引脚
#define DBUS_OUTPUT_GPIO GPIO_PAOUT //输出引脚
#define DBUS_GPIO_PIN PC6_BIT
#define DBUS_WAKE_SOURCE 0x00000080
#define DBUS_SET (GPIO_PCSET_ADDR)
#define DBUS_CLR (GPIO_PCCLR_ADDR)
extern void SetDH11Status(int32u status); //设置相应端口为高电平或低电平
extern u8 GetDH11Status(); //获取传感器状态
extern void DH11Start(); //启动DH11传感器,触发一次信号采集;
extern u8 GetDH11BD(); //按字节读取采集的数据
extern void GetDH11Data(); //获取采集的数据
#endif
DHT11.c文件:
#include PLATFORM_HEADER
#include BOARD_HEADER
#include "DH11.h"
#include "hal/micro/micro-common.h"
#include "hal/micro/cortexm3/micro-common.h"
#include "stdio.h"
#define LOW 0//低电平
#define HIGH 1//高电平
/**************************************************************************
功能描述:完成对相应端口设置给定的电平
输入参数:status:电平的参数,高电平或低电平
输出参数:无
*************************************************************************/
void SetDH11Status(int32u status)
{
halGpioConfig(DBUS,GPIOCFG_OUT); //将DBUS端口设置为输出模式
if(DBUS/8 < 3)
{
if(status==HIGH) //高电平
*((volatile int32u *)DBUS_SET) = BIT(DBUS&7);
else //低电平
*((volatile int32u *)DBUS_CLR) = BIT(DBUS&7);
}
}
/**************************************************************************
功能描述:获取端口DBUS_INPUT_GPIO的电平状态
输入参数:无
输出参数:u8类型变量,返回1表示高电平,返回0表示低电平
*************************************************************************/
u8 GetDH11Status()
{
return (DBUS_INPUT_GPIO & (1<<DBUS_GPIO_PIN)) ? 1 : 0;
}
/**************************************************************************
功能描述:完成对DHT11传感器的初始化,触发一次数据采集
输入参数:无
输出参数:无
*************************************************************************/
void DH11Start()
{
SetDH11Status(LOW); //把总线拉低至少18ms等待DHT11响应
halCommonDelayMicroseconds(18000);
SetDH11Status(HIGH); //释放总线,输出高电平
halCommonDelayMicroseconds(20); //延时等待20-40us
halGpioConfig(DBUS,GPIOCFG_IN);
}
/**************************************************************************
功能描述:完成对给采集到的数据的按字节读取
输入参数:无
输出参数:无
*************************************************************************/
u8 GetDH11BD() { u8 i,tmp; //i为循环变量,tmp为标志位,为1表示读出的是1,为0表示读出的是0 u8 temp=0; //存放最终读到的数据 halCommonDelayMicroseconds(30); //延时30us for(i=0;i<8;i++) //循环得到8位的最终数据 { temp=temp<<1; //每个位传输都以50us的低电平时隙开始,所以在此等待低电平结束 while(!GetDH11Status()); if(GetDH11Status()) //如果输出为0,则高电平持续时间为26us-28us { halCommonDelayMicroseconds(28); } /*如果读到的数据为1,则高电平持续时间为70us,那么28us后仍为高电平,则 表明读取的数据为1,设置标志位*/ if(GetDH11Status()) { tmp=1; halCommonDelayMicroseconds(40); } else tmp=0; temp|=tmp; } return temp; } |