数据采集是工业控制系统中的重要环节,较高的采样率对数据处理环节提出了高的要求。当数据量不大,采样率不高时,使用cpu进行传输处理是非常简单方便的;当遇到大的数据容量,高的采样率时,如果仍然使用cpu处理数据传输,将会带来巨大的cpu负载,难以满足高速大容量数据采集的要求。通常,在数据容量比较大,采样率较高的场合,使用dma技术将数据直接传输到内存,不经过cpu管理,是比较通用的方案。
英创公司针对英创主板esm335x已有的硬件资源,在linux-4.1.6操作系统环境下,提出了一种基于spi接口的大容量通用数据采集方案,其物理连接如图1所示。这里用另一块esm335x作为主设备,模拟数采装置,实际使用可以是任何支持spi主模式的设备。使用时,连接spi主从设备的公共地后,只需要连接esm335x主板上对应spi_sclk、spi_mosi、spi_cs0n的 3个管脚,见表1。
图1 spi接口大容量通用数据采集连接图
表1 esm335x工控主板spi接口数采方案管脚说明
信号名称
cn2(管脚标号)
说明
gpio29/spi_mosi
f14
spi数据信号,主设备输出,从设备输入
gpio30/spi_sclk
f15
spi时钟信号,主设备输出,从设备输入
gpio31/spi_cs0n
f16
spi片选信号,低有效,主设备输出,从设备输入
该方案使用spi作为传输协议,采用双buffer的dma技术,能够达到1msps(一个采样点数据位宽8-16位)。esm335x工作在spi从模式,能够接收的最高时钟为16mhz(最低不限制),即最高数据传输率为2mbytes/s。当dma缓存buffer1装满数据后,会触发dma中断,通知cpu将数据读出dma缓存,然后继续将新传输进入的数据存储在buffer2;buffer2装满数据后,也产生dma中断通知cpu取出数据,然后将新数据存储到buffer1,如此循环,如图2所示。当主机传输完成不再提供时钟信号后,esm335x(从设备)通过定时器超时读出dma缓存中剩余的数据。
图2 dma双buffer示意图
图3 使用dma技术的spi数据采集cpu负载
如图3所示,使用此方案后,cpu负载率很低,此例中不到1%。用户使用时,需要按如下步骤进行操作:
1、加载spi从模式驱动。在linux操作系统中,使用insmod spi-slave.ko命令,会创建设备节点/dev/spi-slave。
2、应用程序打开设备:
fd = open ( /dev/spi-slave, o_rdwr, s_irusr | s_iwusr );
3、设定传输参数:
//configure info transfer to driver
structspi_slave_transfer
{
unsignedintclk; //驱动根据不同clk,设定不同长度的dma buffer,满足填满一个buffer的时间不超过10ms(双buffer)
unsignedintmode; //spi mode: 0,1,2,3
unsignedintbits_per_word; //每个采样点的位数
};
structspi_slave_transfer transfer;
transfer.clk =16000000; //16m clk ---16kb every buffer
transfer.mode = 1;
transfer.bits_per_word = 16;
4、传入参数至内核,启动传输:
if(ioctl ( fd, spi_slave_start, &transfer )<0)
{
printf ( start wrong!!!!!!!!!!!!!!!!\n );
exit ( 1 );
}
此时,主板上的spi已经进入从模式,有数据传入时,将存入dma缓存,存满一个buffer就通知cpu读出数据到cpu维护的一个内存区域(256个kfifo组成链表,kfifo大小与buffer相同,使用完后会覆盖第一个kfifo)。同时,当一次传输完成后,通过定时器读出剩余在dma buffer中的数据。应用程序应及时使用read函数从cpu维护的区域读出数据,以免cpu维护太多内存。
count_in_byte = 0;
read_count = 0;
while(1)
{
fd_zero(&fdread);
fd_set(fd,&fdread);
atime.tv_sec = 2;
atime.tv_usec = 0;
ret = select ( fd+1, &fdread, null, null, &atime );
if( ret0 )
{
if( fd_isset(fd, &fdread) )
{
memset(read_buf,0,4096*4);
read_count = read(fd, read_buf, 4096*4);
if( read_count<0 )
{
printf ( read wrong!!!!!!!!!!!!!!!!\n );
exit ( 1 );
}
if(read_count){ //0 --- end-of-file not printf
count_in_byte += read_count;
printf(\nread_count = %d\ncount_in_byte = %d\n, read_count, count_in_byte);
}
//process data, here just print to console
if(read_count < 20){
for( i=0; i
{
printf ( %02x , read_buf[i] );
if(i%10 == 9)
printf ( \n );
}
printf(\n);
}
}
}
printf ( remaining time %u.%u!\n,atime.tv_sec, atime.tv_usec );
}
5、完成传输,关闭spi。
if(ioctl ( fd, spi_slave_stop, &transfer )<0)
{
printf ( stop wrong!!!!!!!!!!!!!!!!\n );
exit ( 1 );
}
6、关闭设备文件
close ( fd );
当主设备前后两次传输的参数不一样时,从设备需要分两次调用open/close函数,按以上步骤进行操作。如有用户对这个方案感兴趣,可以联系我们,我们将提供驱动文件和完整的应用程序示例。
上半年智能手机后置双摄占比高达71%,什么原因导致双摄这么受欢迎?
比谷歌眼镜更值得入手的智能眼镜?
基于RA6M5开发板的低功耗电子时钟设计
《纽约时报》用AR新模式来报道新闻,让我们一睹大卫·鲍伊系列服装
哪款手游最吃流量 你们心里难道没点X数吗?
英创信息技术基于SPI接口的大容量通用数据采集方案
Entegris的野心 进军中国半导体行业
如何使用Maven进行组件化发布(下)
微型LED背光照明的生产技术将在2019年趋于成熟
量子科技中国按下“快进键”,5年内我国新增85%量子领域相关企业
三星发布中频段5G技术,频宽可提高一倍
Microchip推出PCIe第五代NVMe固态硬盘控制器
Wi-Fi6和5G技术相辅相成并共存
百度与酷开的重磅合作,互联网电视版图正在重构
2010年NAND Flash价格发展持续两极化
小米正研发一款20W智能追踪式无线充 随手一放即可充电
如何理解动力电池PACK智能化?
单片机控制系统的红外线遥控器接口
电机选型的详细步骤有哪些
人工智能将会让我们的生活变得更加美好