在工业控制应用、特别是要求闭环控制的实时应用中,通常都需要实时采集模拟信号。因此作为一款面向实时控制应用的工控主板EM9380,配置了最多可达8路的AD转换单元。为了实现闭环控制的高效操作,AD转换是由板上独立运行的硬件协处理器(Cortex-M3)来直接操作。应用程序通过驱动程序,其设备文件名为“MCU2:”,来操作AD的功能。在标准配置的EM9380中,其AD单元的基本技术特性包括:
• 单端输入采集,可进一步选择单通道、双通道、4通道及8通道模式。
• 差分输入采集,可进一步选择单通道、双通道及4通道模式。
• 采集触发模式方面,支持软件触发和阈值触发两种模式。软件触发指一旦应用程序调用相关API函数,即进行数据采集;而阈值触发模式是指当应用程序启动AD采集后,
只有当输入的数据超出所设置的门限阈值时,才开始采集数据,这种模式广泛应用于状态监测及波形捕捉等应用。
• 采集数据方面,支持单点采集和波形采集两种模式。单点采集指每个通道仅采集一个样点;而波形采集则是按设置的采样间隔,采集一定长度的数据序列,这种模式一般
应用于需要分析波形数据的场合,如需要做FFT,获得波形的频谱特征。
本文后续部分将针对EM9380的多通道AD在硬件、软件方面的特性,具体介绍实现数据采集的相关步骤。
AD通道的硬件接口说明
EM9380中与AD关联的管脚是GPIO8 – GPIO15,这8路GPIO在上电时的缺省配置是数字输入模式。只有当应用程序调用AD转换的API时,其相应的管脚才会转换为模拟输入状态。EM9380共支持7种输入模式,每种模式使用固定的通道配置,未使用的管脚则保持在GPIO模式。输入模式与具体管脚的关系列表如下:
单通道单端输入
AD通道号 | 信号输入管脚 | 备注 |
AD_CH0 | GPIO8 | 与公共GND构成信号回路 |
双通道单端输入
AD通道号 | 信号输入管脚 | 备注 |
AD_CH0 | GPIO8 | 与公共GND构成信号回路 |
AD_CH1 | GPIO9 | 与公共GND构成信号回路 |
4通道单端输入
AD通道号 | 信号输入管脚 | 备注 |
AD_CH0 | GPIO8 | 与公共GND构成信号回路 |
AD_CH1 | GPIO9 | 与公共GND构成信号回路 |
AD_CH2 | GPIO10 | 与公共GND构成信号回路 |
AD_CH3 | GPIO11 | 与公共GND构成信号回路 |
8通道单端输入
AD通道号 | 信号输入管脚 | 备注 |
AD_CH0 | GPIO8 | 与公共GND构成信号回路 |
AD_CH1 | GPIO9 | 与公共GND构成信号回路 |
AD_CH2 | GPIO10 | 与公共GND构成信号回路 |
AD_CH3 | GPIO11 | 与公共GND构成信号回路 |
AD_CH4 | GPIO12 | 与公共GND构成信号回路 |
AD_CH5 | GPIO13 | 与公共GND构成信号回路 |
AD_CH6 | GPIO14 | 与公共GND构成信号回路 |
AD_CH7 | GPIO15 | 与公共GND构成信号回路 |
单通道差分输入
AD通道号 | 输入管脚 | 输入信号 | 实际输入信号 |
AD_CH0 | GPIO8 | AD_CH0+ | AD_CH0+ / AD_CH0- |
GPIO9 | AD_CH0- |
双通道差分输入
AD通道号 | 输入管脚 | 输入信号 | 实际输入信号 |
AD_CH0 | GPIO8 | AD_CH0+ | AD_CH0+ / AD_CH0- |
GPIO9 | AD_CH0- | ||
AD_CH2 | GPIO10 | AD_CH2+ | AD_CH2+ / AD_CH2- |
GPIO11 | AD_CH2- |
4通道差分输入
AD通道号 | 输入管脚 | 输入信号 | 实际输入信号 |
AD_CH0 | GPIO8 | AD_CH0+ | AD_CH0+ / AD_CH0- |
GPIO9 | AD_CH0- | ||
AD_CH2 | GPIO10 | AD_CH2+ | AD_CH2+ / AD_CH2- |
GPIO11 | AD_CH2- | ||
AD_CH4 | GPIO12 | AD_CH4+ | AD_CH4+ / AD_CH4- |
GPIO13 | AD_CH4- | ||
AD_CH6 | GPIO14 | AD_CH6+ | AD_CH6+ / AD_CH6- |
GPIO15 | AD_CH6- |
对于单端输入,其输入满量程为0 – 2.5V,对应的量化数据分别为0 – 4095(12-bit AD分辨率)。差分输入时,数据值与输入电压的关系如下表所示:
AD转换数据(HEX) | CH+输入电压 | CH-输入电压 | 备注 |
4095(0xFFF) | 2.5V | 0V | 正向最大差 |
2048(0x800) | CH+ = CH- | ||
0(0x000) | 0 | 2.5V | 反向最大差 |
在标准配置下,各AD通道的输入阻抗大致为40KΩ。为了保证AD转换的精度,建议前端输入的模拟信号,应根据实际信号的特点,加入适当的信号调理单元。
接口软件说明
为了操作EM9380的AD采集功能,首先需要打开硬件协处理器的驱动程序,其设备文件名为”MCU2:”(注意是MCU2,而不是MCU1):
#include// 数据类型定义
HANDLE hMCU2;
hMCU2 = CreateFile(_T(“MCU2:”), // name of device
GENERIC_READ|GENERIC_WRITE, // desired access
FILE_SHARE_READ|FILE_SHARE_WRITE, // sharing mode
NULL, // security attributes (ignored)
OPEN_EXISTING, // creation disposition
FILE_FLAG_RANDOM_ACCESS, // flags/attributes
NULL); // template file (ignored)
驱动程序MCU2通过DeviceIoControl,支持以下AD采集命令:
MCU_GENERIC_ADC_SE1 // 单端输入,单通道模式
MCU_GENERIC_ADC_SE2 // 单端输入,双通道模式
MCU_GENERIC_ADC_SE4 // 单端输入,4通道模式
MCU_GENERIC_ADC_SE8 // 单端输入,8通道模式
MCU_GENERIC_ADC_DI1 // 差分输入,单通道模式
MCU_GENERIC_ADC_DI2 // 差分输入,双通道模式
MCU_GENERIC_ADC_DI4 // 差分输入,4通道模式
同时以上命令需通过以下的数据结构来设置相关参数:
typedef struct
{
BYTE ucSize; // 本数据结构大小 = 24字节
BYTE ucCmd; // AD命令码:MCU_GENERIC_ADC_XXX
DWORD dwPeriod; // 采样间隔,单位为us,= 0:软件触发
WORD wData[8]; // 返回的采集数据
bool bFlashed; // 保存本配置作为启动缺省功能
BYTE ucChkSum; // 校验和
} MCU_ADC_INFO, *PMCU_ADC_INFO; // struct for ADC
参数dwPeriod为采样间隔,设置为0表示软件触发数据采集,不为0,则按设置的采样间隔进行AD转换。最短采样间隔为25us,即最高采样率40Ksps。注意若启动多通道数据采集,则每通道的采样周期为dwPeriod×通道数。
当dwPeriod不为零时,wData[ ]的前三个值将作为输入参数,其中wData[0]表示采集的总样点数,wData[1]表示阈值窗口的上限值(最大值=4095),wData[2]表示阈值窗口的下限值(最小值=0)。通过这些参数的合理逻辑组合,就可实现以下4种数据形式的采集:
dwPeriod | wData[0] | wData[1] | wData[2] | 采集数据 |
= 0 | - | - | - | 软件触发,单点采集 |
> 0 | 通道数 | wData[1] > wData[2] | 阈值触发,单点采集 | |
> 0 | 通道数×N | 0 | 0 | 软件触发,N点波形采集 |
> 0 | 通道数×N | wData[1] > wData[2] | 阈值触发,N点波形采集 |
对单点数据采集,MCU2驱动将以MCU_ADC_INFO数据结构的形式回传采集结果,其中采集数据包含在wData[ ]中,分别对应AD的CH0 – CH7。wData的数据格式为:
16-bit AD转换数据 | |
D15 – D12(4-bit) | D11 – D0(12-bit) |
通道号(0 – 7) | ADC实际转换输出的数据值(0 – 4095) |
对波形采集,为了提高效率,回传的数据采用以下数据结构的形式:
typedef struct
{
BYTE ucSize; // 本数据结构大小 = 51字节
BYTE ucCmd; // AD命令码:MCU_GENERIC_ADC_XXX
WORD wData[24]; // 返回的采集数据
BYTE ucChkSum; // 校验和
} MCU_ADC_FLOW, *PMCU_ADC_FLOW; // struct for ADC
24个采集数据将根据AD采集命令所使用的通道数,顺序循环排列。而每个数据的格式与单点采集数据的格式是一样的。
以下代码实现单端输入8通道,软件触发单点采集:
MCU_ADC_INFO Info; //定义结构对象
memset(&Info, 0, sizeof(MCU_ADC_INFO));//清零
//填写所需的参数
Info.ucSize = sizeof(MCU_ADC_INFO);
Info.ucCmd = MCU_GENERIC_ADC_SE8; //单端8通道输入
Info.dwPeriod = 0; //软件触发,单点采集
// 生成chksum字节
Info.ucChkSum = ChkSum(&Info, sizeof(MCU_ADC_INFO)-1);
// 调用DeviceIoControl
if (!DeviceIoControl(hMCU2, // File handle to the driver
MCU_IOCTL_ACCESS, // I/O control code
&Info, // input buffer
sizeof(MCU_ADC_INFO), // in buffer size
&Info, // out buffer
sizeof(MCU_ADC_INFO), // out buffer size
NULL, // pointer to number of bytes returned
NULL)) // ignored (=NULL)
{
// 出错处理......
return FALSE;
}
// 对采集的数据Info.wData[]进行处理......
全部0条评论
快来发表一下你的评论吧 !