本实例基于STM32W108的SimpleMac协议栈,利用无线节点完成对温度、湿度、超声波、烟雾、声音、光敏等传感器的控制及数据采集,并实时将数据发送到STM32W108开发板,完成传感器数据的汇集,并通过串口传送给PC机。
13.4传感器数据采集程序设计与实现
下面将根据不同的传感器分别进行传感器数据采集程序的设计说明,最后给出数据包的发送、接收及主函数部分的详细内容。
13.4.1
温度传感器
temperature.h文件内容:
#ifndef __TEMPERATURE_H__ #define __TEMPERATURE_H__ #define TEMP_BUS PORTA_PIN(5) #define TEMP_BUS_INPUT_GPIO #define TEMP_BUS_OUTPUT_GPIO GPIO_PAOUT //端口A输出寄存器 #define TEMP_BUS_GPIO_PIN #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); // SetPort(HIGH); // dat = (GetPort() << 7) | (dat >> 1);//最先读出的是最低位数据 Delay_1us(45); // } return dat; } /************************************************************************** 功能描述:读取当前温度,利用DS18B20进行温度的采集 输入参数:无 输出参数:u16类型变量,读取的温度值,当前温度值=返回值/100 *************************************************************************/ u16 Read_Temperature() { u8 Temp1,Temp2; //DS18B20 开始转换: DS18B20_Reset(); //DS18B20 DS18B20_Write(0xCC); // DS18B20_Write(0x44); // Delay_1us(800); // //DS18B20 读暂存数据: DS18B20_Reset(); //DS18B20 DS18B20_Write(0xCC); // DS18B20_Write(0xbe); // Temp1=DS18B20_Read(); // Temp2=DS18B20_Read(); // 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; } |