本项目采集光敏传感器和可燃气体传感器等模拟量传感器的模拟值
一、项目分析
1.传感器选型
光敏传感器采用M21:
M21电路图:
可燃气体传感器M2:
M2电路图:
2.模拟量传感器原理
将气体专感器、光敏传感器分别插入到两块ZigBee模块,与通过串口连接到计算机的ZigBee模块共同组成传感器采集系统。
带酒精的棉签靠近气体传感器模块,使用手机电筒照射光敏/传感器模块,当气体传感器检测到不同浓度的气体时,光敏传感器检测到不同光强的光照时,都会在计算机的串口调试软件上就显示检测到的气体电压信息和光照电压信息。
模拟量传感器发出的是连续信号,用电压、电流、电阻等表示被测参数的大小。比如光敏传感器、气体传感器等都是常见的模拟量传感器。
气体传感器是指将被检测的气体分子与气敏材料发生的物理或化学反应所产生的物理或化学量变化,转变为可有效测量的电信号,从而实现对气体种类和浓度进行测量的-种传感器。
光敏传感器是利用光敏元件将光信号转换为电信号的传感器,是对外界光信号或光辐射有响应或转换功能的敏感装置。
电信号:
3.A/D转换
1.A/D转换初始化
void hal_adc_Init(void)
{
APCFG |= 1; //设置模拟端口:模拟量输入引脚
P0SEL |= (1 << 0); //将相应端口设置为外设功能
P0DIR &= ~(1 << (0)); //配置端口为输入
}
2.A/D转换
uint16 get_adc(void)
{
uint32 value;
hal_adc_Init(); //ADC初始化
ADCIF = O; //清除ADC中断标志
ADCCON3 = (Ox80|0x10|0x00);
while(!ADCIF) //等待AD转化结束
{
;
}
value = ADCL; //获取ADC转换结果的低位部分存入value中
value |= (((uint16)ADCH)<<8); //取得最终转换结果存入value中
value = value *330; //0表示0V,32768(2^15)表示3.3V
value = value>>15; //根据计算公式电压值=(value*3.3)/32768 (V)
return (uint16)value; //返回分辨率为0.01V的电压值
}
4.定时器
1.定时器初始化
void Timer4_Init(void)
{
//Set prescaler divider value to 128(32M/128-250KHZ)
T4CTL |= OxEO; //设置分频系数为128
T4CTL &= ~(0x10); //暂停定时器
T4CTL &= ~(0x08); //禁止溢出中断
T4CTL |= 0x04; //复位计数器到0x00,并初始化相关通道所有的输出引脚
T4IE=0; //中断禁止
}
2.打开定时器
void Timer4_On(void)
{
T4CTL |= 0x08; //使能溢出中断
T4CTL &= ~(0x03); //定时器设置为自由运行模式,从0X00到0XFF反复计数
T4CTL |= Ox10; //启动定时器
T4IE = 1; //使能定时器中断
SEND DATA FLAG-0; //定时时长标志变量,到达定时时长置1,未达到置0
}
3.关闭定时器
void Timer4_Off(void)
{
T4CTL &=~(0×08); //禁止溢出中断
T4CTL &=(Ox10); //暂停定时器
T41E = 0; //中断禁止
}
4.定时中断服务函数
HAL_ISR_FUNCTION(T4_ISR, T4_VECTOR)
{
T40VFIF = 0; //清除溢出中断标志
T4IF = 0; //清除中断标志
NUM ++; //每发生一次中断, 中断计数次数加1
if(NUM == 1935)
{
NUM == 0;
SEND_DATA_FLAG = 1;
//halledToggle(1);
Timer4_Off(); //关闭定时器
}
else
{
SEND_DATA_FLAG = 0; //清除定时时长标志变量,重复计时
}
}
二、搭建环境
使用新大陆公司开发好的包
1.解压缩后是三个文件夹,再新建一个project文件夹。
2.新建工程部分省略,可以看我之前的文章。
新建test工程:
新建app文件夹用于存放主功能代码,依次通过add -- add Group……方式,新建6个文件夹,文件夹名复制CC2530_lib里的4个文件夹名(moudle不用)和mylib、sensor_drv文件夹。
3.文件夹建好之后,通过add -- add files……方式在每个文件夹中增加.c文件
4.file文件增加完毕之后,引入头文件地址
$PROJ_DIR$\..\CC2530_lib\basicrf
$PROJ_DIR$\..\CC2530_lib\board
$PROJ_DIR$\..\CC2530_lib\common
$PROJ_DIR$\..\CC2530_lib\utils
$PROJ_DIR$\..\mylib
$PROJ_DIR$\..\sensor_drv
三、编写代码
1.发送端
#include "hal_defs.h"
#include "hal_cc8051.h"
#include "hal_int.h"
#include "hal_mcu.h"
#include "hal_board.h"
#include "hal_led.h"
#include "hal_rf.h"
#include "basic_rf.h"
#include "hal_uart.h"
#include "UART_PRINT.h"
#include "TIMER.h"
#include "get_adc.h"
#include "sh10.h"
#include <string.h>
#define MAX_SEND_BUF_LEN 128
#define MAX_RECV_BUF_LEN 128
static uint8 pTxData[MAX_SEND_BUF_LEN];
static uint8 pRxData[MAX_RECV_BUF_LEN];
#define MAX_UART_SEND_BUF_LEN 128
#define MAX_UART_RECV_BUF_LEN 128
uint8 uTxData[MAX_UART_SEND_BUF_LEN];
uint8 uRxData[MAX_UART_RECV_BUF_LEN];
uint16 uTxlen = 0;
uint16 uRxlen = 0;
/*****点对点通讯地址设置******/
#define RF_CHANNEL 20
#define PAN_ID 0x23 //35号
#define MY_ADDR 0x1234
#define SEND_ADDR 0x5678
static basicRfCfg_t basicRfConfig;
uint8 APP_SEND_DATA_FLAG;
void ConfigRf_Init(void)
{
basicRfConfig.panId = PAN_ID;
basicRfConfig.channel = RF_CHANNEL;
basicRfConfig.myAddr = MY_ADDR;
basicRfConfig.ackRequest = TRUE;
while(basicRfInit(&basicRfConfig) == FAILED);
basicRfReceiveOn();
}
void main()
{
uint16 sensor_value;//传感器的值
halBoardInit(); //初始化
halLedSet(1); //LED灯初始化
ConfigRf_Init(); //发送初始化
Timer4_Init(); //定时器初始化
Timer4_On(); //定时器开启
while(1)
{
APP_SEND_DATA_FLAG = GetSendDataFlag();
if(APP_SEND_DATA_FLAG == 1)
{
#if defined(GM_SENSOR)
sensor_value = get_adc();
printf_str(pTxData,"光照传感器电压;%d.%dV\r\n",sensor_value/100,sensor_value%100);
#endif
#if defined(QT_SENSOR)
sensor_value = get_adc();
printf_str(pTxData,"气敏传感器电压;%d.%dV\r\n",sensor_value/100,sensor_value%100);
#endif
halLedToggle(1);
basicRfSendPacket(SEND_ADDR,pTxData,strlen(pTxData));
Timer4_On();
}
}
}
2.接收端
#include "hal_defs.h"
#include "hal_cc8051.h"
#include "hal_int.h"
#include "hal_mcu.h"
#include "hal_board.h"
#include "hal_led.h"
#include "hal_rf.h"
#include "basic_rf.h"
#include "hal_uart.h"
#include "UART_PRINT.h"
#include "TIMER.h"
#include "get_adc.h"
#include "sh10.h"
#include <string.h>
#define MAX_SEND_BUF_LEN 128
#define MAX_RECV_BUF_LEN 128
static uint8 pTxData[MAX_SEND_BUF_LEN];
static uint8 pRxData[MAX_RECV_BUF_LEN];
#define MAX_UART_SEND_BUF_LEN 128
#define MAX_UART_RECV_BUF_LEN 128
uint8 uTxData[MAX_UART_SEND_BUF_LEN];
uint8 uRxData[MAX_UART_RECV_BUF_LEN];
uint16 uTxlen = 0;
uint16 uRxlen = 0;
/*****点对点通讯地址设置******/
#define RF_CHANNEL 20
#define PAN_ID 0x23 //35号
#define MY_ADDR 0x5678
#define SEND_ADDR 0x1234
static basicRfCfg_t basicRfConfig;
uint8 APP_SEND_DATA_FLAG;
void ConfigRf_Init(void)
{
basicRfConfig.panId = PAN_ID;
basicRfConfig.channel = RF_CHANNEL;
basicRfConfig.myAddr = MY_ADDR;
basicRfConfig.ackRequest = TRUE;
while(basicRfInit(&basicRfConfig) == FAILED);
basicRfReceiveOn();
}
void main()
{
uint16 len = 0;
halBoardInit();
ConfigRf_Init();
halLedSet(2);
Timer4_Init();
Timer4_On();
while(1)
{
if(basicRfPacketIsReady())
{
halLedToggle(2);
len = basicRfReceive(pRxData,MAX_RECV_BUF_LEN,NULL);
halUartWrite(pRxData,len);
}
}
}
发送端是两块zigbee板子,一个插气体传感器,另一个插光敏传感器,发送端如何下载程序?
新建一个gm_sensor存放执行代码条件,下载插有气体传感器传感器的zigbee板子时,圈起来的地方改为QT_SENSOR,反之气敏传感器传感器改为GM_SENSOR。
注意:test01和test02都有main函数,所以下载发送端/接收端时,要屏蔽另一个。勾选则代表屏蔽!
四、效果展示
源代码公布: