烟雾传感器就是通过监测烟雾的浓度来实现火灾防范的, 烟雾报警器内部采用离子式烟雾传感,离子式烟雾传感器是一种技术先进,工作稳定可靠的传感器,被广泛运用到各种消防报警系统中,性能远优于气敏电阻类的火灾报警器。
*******************************************
一:在裸机上完成对烟雾传感器的驱动。
#include <ioCC2530.h>
#define uint unsigned int
#define uchar unsigned char
//定义控制LED灯的端口
#define LED1 P1_0//LED1为P1.0口控制
#define AIR P2_0 //烟雾传感器IO为P2.0口控制
//函数声明
void Delayms(uint); //延时函数
void InitLed(void); //初始化LED1
void AirInit(); //烟雾传感器初始化
uchar AirScan(); //烟雾IO口扫描程序
/****************************
延时函数
*****************************/
void Delayms(uint xms) //i=xms 即延时i毫秒
{
uint i,j;
for(i=xms;i>0;i--)
for(j=587;j>0;j--);
}
/****************************
LED初始化函数
*****************************/
void InitLed(void)
{
P1DIR |= 0x01; //P1_0定义为输出
LED1 = 1; //LED1灯熄灭
}
/****************************
烟雾输入口初始化函数
*****************************/
void AirInit()
{
P2SEL &= ~0X01; //设置P20为普通IO口
P2DIR &= ~0X01; // 在P20口,设置为输入模式
P2INP &= ~0x01; //打开P20上拉电阻,不影响
}
/****************************
烟雾检测函数
*****************************/
uchar AirScan(void)
{
if(AIR==0)
{
Delayms(10);
if(AIR==0)
{
return 1; // 无烟雾
}
}
return 0; //有烟雾
}
/***************************
主函数
***************************/
void main(void)
{
InitLed();//调用初始化函数
AirInit();
while(1)
{
if(AirScan()) //按键改变LED状态 返回1表示无烟雾,返回0表示有烟雾。
LED1=1; //无烟雾,LED1灭掉
else
LED1=0; //有烟雾,LED1点亮
}
}
上述代码实现了当有烟雾或有毒气体的时候时候 LED1 灭掉,没有烟雾的时候 LED1 亮。
*******************************************
二:将程序添加到协议栈代码中。
烟雾传感器电路是对 IO 口电平的检测。所以在协议栈里检测程序比较简单。我们只需要配置好 IO 口,然后周期性检测就可以了。
(一)、IO口定义及初始化
打开例程 SampleApp.eww 工程,打开 SampleApp.c 文件。我们先定义和初始化 P2.0引脚。设为输入模式。
----------------------------------------------------
//烟雾传感器 IO 定义
#define AIR P2_0 //P2.0
void SampleApp_Init( uint8 task_id )
/******烟雾传感器电路初始化******/
P2SEL &= ~0X01; //设置P2.0为普通IO口
P2DIR &= ~0X01; // 在P2.0口,设置为输入模式
P2INP &= ~0x01; //打开P2.0上拉电阻
----------------------------------------------------
(二)、串口初始化
==========================================
初始化串口(参考协议栈串口实验)
1、
SampleApp.c
#include "MT_UART.h" //串口头文件引用
2、
SampApp.c
SampApp_Init()
SampApp_TransID() = 0;
MT_UartInit();
3、
void MT_UartInit()
uartConfig.baudRate =MT_UART_DEFAULT_BAUDRATE;
uartConfig.flowControl = MT_UART_DEFAULT_OVERFLOW;
#define MT_UART_DEFAULT_BAUDRATE HAL_UART_BR_115200 //38400
#define MT_UART_DEFAULT_OVERFLOW FALSE //TRUE
4、
用 ZTOOL,串口 0。我们可以在 option——C/C++ 的 CompilerPreprocessor 里面看到,已经默认添加 ZTOOL_P1 预编译。
5、
void SampleApp_Init( uint8 task_id )
MT_UartInit();
MT_UartRegisterTaskID(task_id);//登记任务号
至此,就可以使用
HalUARTWrite(0, "Hello,world\n", 12); //(串口, 字符, 字符个数) 发送数据了。
(三)点播配置
==========================================
利用周期性点播的定时器作为烟雾信息采集时间,将采集到的信息发送给协调器。
并通过串口打印。协调器只做串口打印。 0.5 秒采集一次。
点播配置部分(参考网络通讯--点播)
1、
afAddrType_t Point_To_Point_DstAddr;
//点对点通信定义
2、
void SampleApp_Init( uint8 task_id ) 里面,
对 Point_To_Point_DstAddr 一些参数进行配置
---------------
Point_To_Point_DstAddr.addrMode = (afAddrMode_t)
Addr16Bit
;//点播
Point_To_Point_DstAddr.endPoint =
SAMPLEAPP_ENDPOINT;
Point_To_Point_DstAddr.addr.shortAddr = 0x0000; //发给协调器
--------------- 3、
在SampleApp.c中
发送点播函数
添加头文件声明 void SampleApp_SendPointToPointMessage( void );
定义该函数
void SampleApp_SendPointToPointMessage( void )
{
uint8 L;
if(AIR==1)
{
L=1;//有烟雾
HalUARTWrite(0,"Get bad Air\n",11); //串口
//HalLcdWriteString( "Got bad Air", HAL_LCD_LINE_3 ); //LCD
}
else
{
L=0;//无烟雾
HalUARTWrite(0,"No bad Air\n",12); //串口
//HalLcdWriteString( "No bad Air", HAL_LCD_LINE_3 );//LCD
}
if ( AF_DataRequest( &Point_To_Point_DstAddr,
&SampleApp_epDesc,
SAMPLEAPP_POINT_TO_POINT_CLUSTERID,
1,
&L,
&SampleApp_TransID,
AF_DISCV_ROUTE,
AF_DEFAULT_RADIUS ) == afStatus_SUCCESS )
{
}
else
{
// Error occurred in request to send.
}
}
4、
在SampleApp.h中声明SAMPLEAPP_POINT_TO_POINT_CLUSTERID
#define SAMPLEAPP_MAX_CLUSTERS 3 //2
#define SAMPLEAPP_PERIODIC_CLUSTERID 1
#define SAMPLEAPP_FLASH_CLUSTERID 2
#define SAMPLEAPP_POINT_TO_POINT_CLUSTERID 3
5、将数据打包并按指定的方式发送给指定设备
周期性点播发送数据
uint16 SampleApp_ProcessEvent( uint8 task_id, uint16 events )
if ( events & SAMPLEAPP_SEND_PERIODIC_MSG_EVT )
// Send the periodic message
//SampleApp_SendPeriodicMessage();//周期性发送函数
SampleApp_SendPointToPointMessage();//此处替换成点播函数
osal_start_timerEx( SampleApp_TaskID, SAMPLEAPP_SEND_PERIODIC_MSG_EVT,
(SAMPLEAPP_SEND_PERIODIC_MSG_TIMEOUT + (osal_rand() & 0x00FF)) );
---------------------------------------
终端每 0.5 秒执行点播函数一次,我们在点播函数里判断 IO 口。加入下面的代码。
SampleApp.h
// Send Message Timeout
#define SAMPLEAPP_SEND_PERIODIC_MSG_TIMEOUT 500 // Every 500 ms
--------------------------------------
6、
协调器接收函数我们将数据读出来然后判断。通过串口打印传感器信息出来。
接收 ID 我们在原来基础上改成我们刚定义的 SAMPLEAPP_POINT_TO_POINT_CLUSTERID。
void SampleApp_MessageMSGCB( afIncomingMSGPacket_t *pkt )
switch ( pkt->clusterId )
case SAMPLEAPP_POINT_TO_POINT_CLUSTERID:
if(pkt->cmd.Data[0])
HalUARTWrite(0,"Got bad Air\n",12); //有烟雾
else
HalUARTWrite(0,"No bad Air\n",11); //无烟雾
break;
7、
由于协调器不允许给自己点播,故周期性点播初始化时协调器不能初始化。
uint16 SampleApp_ProcessEvent( uint8 task_id, uint16 events )
case ZDO_STATE_CHANGE:
SampleApp_NwkState = (devStates_t)(MSGpkt->hdr.status);
if ( //(SampleApp_NwkState == DEV_ZB_COORD)|| //协调器不给自己点播
(SampleApp_NwkState == DEV_ROUTER)
|| (SampleApp_NwkState == DEV_END_DEVICE) )
{
// Start sending the periodic message in a regular interval.
osal_start_timerEx( SampleApp_TaskID,
SAMPLEAPP_SEND_PERIODIC_MSG_EVT,
SAMPLEAPP_SEND_PERIODIC_MSG_TIMEOUT );
}
原文链接:https://blog.csdn.net/scgaliguodong123_/article/details/41776157
本站声明:网站内容来源于网络,如有侵权,请联系我们,我们将及时处理。
还没有人抢沙发呢~