目录
在项目开发中经常要检测周围环境中的温度、湿度、亮度、电池电压、声音等非电信号,经过相应的传感器,将非电信号转化为模拟信号,这些模拟信号,处理器都是无法直接识别的,必须经过ADC-模数转化器将模拟量转化为数字量。
N32905内部集成了ADC,省去了外接ADC的麻烦。lvd低电压检测的含义是当检测到的电压低于某一个值时执行某种提示,比如关机、声音报警、串口打印等等,而实现lvd低电压检测的核心就是实现电压检测,本例程将在Duckbill WIFI-Mini905开发板上将ADC1采集到的电压显示在串口上。
准备工作:
wifi音视频开发板一块
1.N32905 ADC简介
N32905内部有7通道、10位分辨率的ADC。2通道专用于4线电阻触摸屏,2通道专用于音频,3通道可用于各种用途,如低压检测、键盘检测、光敏电阻检测等等,本例程低压检测将检测ADC1的电压,使用此通道。每一个通道输入电压范围从0-3.3V之间。支持最大转化率400K/s。
ioctl是应用程序对设备控制的函数,通常用于设置设备的一些参数,例如串口的传输波特率、马达的转速等等,当然也可以控制GPIO。
函数原型:int ioctl(int fd, ind cmd, …)
输入参数:1.fd:用户程序打开设备时使用open函数返回的文件标示符;
2.cmd:用户程序对设备的控制命令;
- 省略号,那是一些补充参数,一般最多一个,有或没有是和cmd 的意义相关的。
返回值:0:成功;
-1:出错;
如果驱动程序提供了对ioctl的支持,用户就可以在用户程序中使用ioctl函数控制设备的I/O通道。
2.硬件设计
底板10pin排针上的ADC1、ADC2分别与N32905的66脚ADC_AIN[3]、64脚ADC_AIN[2]直接相连。
3.软件设计
3.1内核配置
以下几步操作是在内核配置菜单中选择支持ADC驱动。
特别说明:
ADC默认选用ADC_AIN[3],若使用ADC_AIN[2]则需修改驱动,路径/duckbill/N32905/BSP/linux-2.6.17.14_fa93/drivers/input/touchscreen/w55fa93_ts.c,将所有SET_NORMAL_AIN3替换成SET_NORMAL_AIN2即可,也可在内核配置菜单中添加选项,后期再做。
3.2 lvd应用程序分析
/****************************************************************************
*
* lvd 低电压检测程序
* WIFI_Mini905底板上的ADC1检测电压,ADC1对应N32905的ADC_AIN[3]
*
****************************************************************************/
#include <fcntl.h>
#include <stdio.h>
#include <errno.h>
#include <string.h>
#define TS_DEV "/dev/input/event0"
#define ADCSYS_FILE "/sys/devices/platform/w55fa93-adc/adc"
#define LVD_INTERVAL 1
#define BUF_SIZE 8
int main(int argc, char *argv[])
{
//定义触摸屏文件描述符tsfd,adc文件描述符adcfd
int tsfd, adcfd;
//定义数组buf,用于保存读取的数据
char buf[BUF_SIZE];
//打开触摸屏设备文件TS_DEV,若返回值小于0失败
if ((tsfd = open(TS_DEV, O_RDONLY)) < 0) {
printf("open device %s failed, errno = %d\n", TS_DEV, errno);
return -1;
}
// wait for generate first adc data
usleep(1);
while (1) {
//每次写数据到buf前,现将buf清空
memset(&buf[0], 0x0, BUF_SIZE);
// read voltage
//打开ADC设备文件ADCSYS_FILE
adcfd = open(ADCSYS_FILE, O_RDWR);
if (adcfd < 0) {
printf("open device %s failed, errno = %d\n", ADCSYS_FILE, errno);
return -1;
}
//读电压值,并将其写入buf中
read(adcfd, buf, BUF_SIZE);
//printf("buf = %x, %x, %x, %x\n", buf[0], buf[1], buf[2], buf[3]);
//计算电压的大小
printf("voltage = %1.2f\n", (float)(buf[3]*256 + buf[2])/1024.0*3.3);
//关闭ADC设备文件
close(adcfd);
sleep(LVD_INTERVAL);
}
return 0;
}
本例程的程序结构简单清晰,while死循环的流程是每次打开ADC设备文件,读取电压值,计算电压的大小,关闭ADC设备文件,如此反复。
注意:
由于驱动中ADC的实现依赖于触摸屏,因此在打开ADC设备文件前需打开触摸屏设备文件。
4.编译
在ubuntu下切换路径至/duckbill/N32905/applications/lvd。
执行make,编译生成可执行文件lvd_demo,lvd_demo将会自动拷贝至例程文件系统目录 /duckbill/N32905/usr/TEST_mini905/mkFilesys下。
执行例程文件系统TEST_mini905/test_mini905/目录下的脚本mkjffs2.sh,生成我们所需的jffs2文件系统。
5.烧录运行
WIFI-Mini905开发板与电脑之间连接好usb电源线(也充当下载线)、usb转串口线,将拨码开关S1拨向Rec位,按下自锁开关K1,开发板通电,N32905进入烧录模式。
使用TurboWriter依次烧录 开发板光盘资料\Mini905光盘资料\BIN\基础例程下的loader(SpiLoader_905.bin)、内核(Kernel.bin)以及刚刚生成的文件系统(TEST_mini905.jffs2.summary),烧录步骤与例程1一致。
烧录完成后将拨码开关S1拨向Nor位,开发板重新通电,电源指示灯亮,N32905进入正常启动模式,等待系统运行起来。
在串口超级终端输入./lvd_demo,执行lvd应用程序。用杜邦线连接ADC1与GND,串口输出电压0V,连接ADC1与3.3V,串口输出电压3.3V,检测电压的精度很高。