自己写的Linux下的MQ-2烟雾传感器驱动程序,硬件环境为三星的SMDKC110开发板,使用S5PV210(ARM Cortex-A8)作为处理器。
烟雾传感器原理图
附带有说明文档(想不到我之前还写得那么细致!):
<智能家居烟雾传感器驱动程序>
烟雾传感器驱动分为两个部分:烟雾报警部分 和 烟雾测量部分
************
报警部分:
************
1. 驱动使用platform模型进行设计,分为SmokeDetect_device.c和SmokeDetect_driver.c两个文件
2. 注册杂项设备(misc),主设备号固定是10(misc),从设备号由系统自动分配,加载成功后使用lsmod可以看到:
Smoke_Detect_device
Smoke_Detect_driver
3. 本驱动注册成功后生成 /dev/smarthome_smokedetect 节点
4. 对 smarthome_smokedetect 设备节点的操作主要有:
1)打开操作open。使用open打开设备节点后会对GPIO进行初始化并申请中断,此时烟雾报警功能已完全开启。
[ 25.461039] SmokeDetect driver request_irq success!!! //注册中断成功
当传感器检测到烟雾的时候,会触发中断。
a.中断服务程序会将蜂鸣器输入设置为高电平,蜂鸣器开始报警。
b.中断服务程序会将中断源引脚设置为输入,关闭中断。
2)读操作read。每次进行读取操作都将读到一个结构体:
struct SmokeDetect_Info{
unsigned short flag;
};
#define NO_ALARM 0 //flag为0时 没有烟雾告警
#define IS_ALARM 1 //flag为1时 发生烟雾告警
3)写操作write。向设备节点随便写入一个值,会执行相应操作:
a.清除蜂鸣器的报警。
b.将中断源引脚设置为外部中断源,重新打开中断。
4)关闭操作close。 关闭操作会执行以下动作:
a.清除蜂鸣器的报警。
b.将中断源引脚设置为输入。
c.注销中断。
************
烟雾测量部分:
************
1. 直接使用内核现有的ADC驱动,没有另外新增驱动程序。使用的ADC驱动程序源码路径:linux/arch/arm/mach-s5pv210/adc.c
配置内核添加ADC驱动程序步骤:在内核源码树里面输入make menuconfig,进入编译配置界面
System Type --->
[*] S5PXXXX ADC driver //选中
然后重新编译烧写内核,烧写完成后启动内核会在/dev 目录底下生成名字为ADC的设备节点
2. 把驱动程序里面的这个宏添加到应用程序中
#define ADC_INPUT_PIN _IOW('S',0x0c,unsigned long)
然后使用ioctl选择ADC输入通道
#define ADC_CHANNEL_0 0 //烟雾测量使用的是AIN0通道,
//输入值不能大于等于4,4以后是为触摸屏预留的
ioctl(adc_fd,ADC_INPUT_PIN,ADC_CHANNEL_0);
3. 使用read读取ADC的数值
read(adc_fd,buffer,4); //读出来的是一个整型值
4. 应用程序附带了一个均值算法,可参考使用。
S5PV210的Datasheet中的ADC原理图
SmokeDetect_device.c
#include <asm/uaccess.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/irq.h>
#include <linux/platform_device.h>
<pre name="code" class="cpp">/* read the s5pv210 datasheet! */
#define S5PV210_GPH_BASE 0xe0200c00
#define GPH_SIZE 0x6c
#define S5PV210_GPD_BASE 0xe02000a0
#define GPD_SIZE 0x34
void SmokeDetect_device_release(struct device * pdev);
static struct resource SmokeDetect_resource[]={
[0] = {
.start = S5PV210_GPH_BASE,
.end = S5PV210_GPH_BASE &