引言
传统的分布式数据采集系统,常采用串口或以太网等方式向上位机传送数据,这种数据采集方式需要布线,不具备移动性和户外操作的能力。而作为海量存储的USB设备,具有容量大、易于携带、可靠性高等特点,非常适合户外大容量数据的采集存储。随着EDA技术的不断发展,SOPC被广泛应用于复杂的电子系统设计,而Altera公司的NIOSII处理器以其强大的快速性和灵活性,更适用于嵌入式系统,以替代传统的CPU。
本方案采用Altera公司的FPGA器件EP2C8Q208C8,嵌入NIOSII处理器,控制USB文件管理芯片CH376和A/D转换芯片TLC549完成大容量的数据采集,通过文件的方式写U盘扇区,实现对实时性要求不高的大容量现场数据快速采集存储,系统设计框图如图1所示[1]。

图1 系统设计框图
1 NIOSII处理器的大容量数据采集存储系统硬件设计
1.1 系统功能与硬件组成
本系统完成数据的实时采集存储,共有4个按键开关:KEY0系统复位按键;KEY1开始数据采集按键;KEY2停止数据采集按键;KEY3清除U盘数据文件按键。硬件组成如图2所示[23],FPGA芯片集成了方框内的所有组件,除了NIOSII处理器外,还包括SOPC标准组件。

图2 系统硬件组成
图2中的SDRAM控制器,用于控制外接SDRAM芯片K4S641632,K4S641632执行用户程序和数据缓存;EPCS控制器,控制外部配置芯片EPCS4SI8,将程序下载到EPCS芯片和配置完成后,
将EPCS中的程序加载到SDRAM运行;JTAG UART组件,完成程序下载和调试;System ID组件能够帮助调试过程中确认系统是否正常工作;定时器组件,产生1 s的定时中断;PLL组件,用于时钟的产生和管理;三组GPIO组件,分别控制CH376工作、蜂鸣器在一次U盘写数据完成后指示、4个按键的接口。另外还有一个自定义外设组件,控制A/D转换器TLC549工作。可见,把系统的主要功能都集成在一个芯片上,真正体现了SOPC设计思想。
1.2 CH376功能简介
CH376 是文件管理控制芯片,用于处理器控制读写U 盘或者SD 卡中的文件。CH376 支持USB设备方式和USB 主机方式,并且内置USB 通信协议的基本固件、处理MassStorage海量存储设备的专用通信协议的固件、SD 卡的通信接口固件,以及FAT16、FAT32和FAT12 文件系统的管理固件。支持常用的USB 存储设备和SD 卡。CH376 支持3种通信接口:8 位并口、SPI 接口或异步串口接口。
处理器可以通过上述任何一种通信接口控制CH376 芯片,存取U 盘或者SD 卡中的文件或者与计算机通信[4]。本系统用NIOSII作为处理器,CH376工作在USBHost模式,采用8位并口的接口以文件的方式对U盘进行写扇区操作,完成大容量数据的快速采集存储。FPGA与CH376的硬件接线如图3所示[3]。

图3 FPGA与CH376的硬件接线图
1.3 自定义组件A/D控制器的设计
TLC549是美国德州仪器公司的8位串行A/D转换芯片,通过三根线完成串行数据接收。由于Altera的SOPC标准库中不带TLC549控制器,所以需要根据TLC549的工作时序,自定义外设组件。NOISII处理器通过Avalon_MM总线从机接口,将A/D转换控制器集成到SOPC系统中。A/D转换控制器adc_ctrl模块功能框图如3所示。
adc_ctrl模块采用Verilog硬件描述语言编写[5],实现Avalon_MM从机接口和A/D转换芯片控制功能,该模块的对外接口线分成三类:第一类是系统控制信号,包括时钟信号clk和复位信号rst_n;第二类是外部A/D转换芯片的接口信号如A/D转换的数据线adc_data、片选信号线adc_cs_n、时钟线adc_clk;第三类是Avalon_MM从机接口线包括Avalon_MM总线读片选sys_cs_n、读使能sys_rd_n、读取数据线sys_rddata、A/D转换控制模块的信号描述如下[3]:
module adc_ctrl(clk,rst_n,adc_data,adc_cs_n,adc_clk,sys_cs_n,sys_rd_n,sys_rddata);
……//A/D转换状态机
always @(cstate or dchag_flag or bitnum or d17uscnt)
case(cstate)
IDLE: nstate<=TSUDL;
TSUDL:if (dchag_flag) nstate<=START; else nstate<=TSUDL;
START:if (dchag_flag) nstate<=DTRAN; else nstate<=START;
DTRAN:if (dchag_flag && (bitnum==3'd7)) nstate<= STOP; else nstate<=DTRAN;
STOP:if (dchag_flag) nstate<=TWHDL; else nstate<=STOP;
TWHDL:if(dchag_flag&&(d17uscnt==5'd18)) nstate<= IDLE;else nstate<=TWHDL;
default: nstate<=IDLE;
endcase
……//Avalon_MM接口逻辑
wire sys_rdcs_n=sys_cs_n|sys_rd_n;
reg sys_dlink;
always @(posedge clk or negedge rst_n)
if (!rst_n) sys_dlink<=1'b1;
else sys_dlink<=sys_rdcs_n;
assign sys_rddata=sys_dlink?8'hzz:adc_dinr;
在程序设计时,A/D转换芯片控制器采用三段式状态机产生TLC549芯片A/D转换的时序。Avalon_MM总线从机接口程序设计,只涉及读功能,对片选信号和读信号进行逻辑“或”,并将其结果需缓存一拍,这个缓存结果也是数据输出有效控制信号,它保证了A/D采集到的数据能在 Avalon总线的读信号上升沿被锁存[3]。
最后将自定义组件adc_ctrl封装后集成到系统中,并进行引脚分配和编译下载,完成整个SOPC的硬件设计。自定义外设A/D转换控制器功能框图如图4所示。

图4 自定义外设A/D转换控制器功能框图
2 NIOSII处理器的大容量数据采集存储系统软件设计
2.1 主程序设计思路和设计流程
系统中4个按键接到FPGA的4个GPIO,这4个GPIO口采用边沿触发中断的方式。主程序中检测到GPIO中断标志后,再判断是哪个按键中断,进行相应的子程序调用,主程序流程如图5所示。

图5 主程序流程图
主程序初始化程序包括按键初始化函数、CH376初始化函数和U盘初始化函数,中断注册包括按键中断注册、定时器中断注册和CH376中断注册[6]。
2.2 数据采集子程序设计
主程序在调用数据采集子程序时,打开定时器,等待10 KB数据采集存入SDRAM,然后通过CH376USB-Host模式以扇区写方式,每次写入20个扇区的数据,将SDRAM的数据以文件的格式存入USB移动存储器[7],直至写完数据后将新建的文件关闭。同时,蜂鸣器发出报警声,表示一次数据采集存盘结束。每采集一次数据,新建一个文件,存一次盘。其中全局变量wjbh是每次采集文件的文件编号,每采集一次,文件编号加1。
static void shujucaiji (void){//定义静态指针变量,指向SDRAM数据缓冲区地址
unsigned short*ram=(unsigned short *) (SDRAM_BASE+0x10000);
memset (ram,0,10240);//设置数据缓冲区空间大小//启动定时器允许中断、连续计数
IOWR_ALTERA_AVALON_TIME_CONTRL(TIME_BASE,7);
while(!flag1);//等待10 KB数据采集结束
flag1=0;
IOWR_ALTERA_AVALON_TIME_CONTRL(TIME_BASE,8);//关断定时器
write_wenjian (wjbh);//将采样结果以文件形式,用//写扇区方式存入U盘
wjbh++;//wjbh为文件编号,每采集一次,文件编号加1
IOWR_ALTERA_AVALON_PIO_DATA(BUZZER_BASE,0);//蜂鸣器报警
}
2.3 定时器中断程序设计
定时器每隔1 s产生一次定时中断,启一次A/D转换,将A/D转换后的数据存到SDRAM中[7],当采集完10 KB数据后,将数据采集结束标志位flag1置1。
static void handle_TIME_interrupt (void){
IOWR_ALTERA_AVALON_TIME_STATUS(TIME_BASE,0); //清定时器中断标志位读取A/D采样值存入SDRAM,由于是16位存储器,每次存入后地址指针自动加2
*(ram++)=IORD_8DIRECT(adc_ctrl_BASE,0);
delay();//调延时
if (count<5120)count++;//采样满10 KB,停止采样
else{
count=0;
flag1=1;
}
}
2.4 CH376以文件方式写扇区子程序设计
FPGA通过GPIO与CH376相连,NIOSII处理器通过对GPIO的读写操作完成CH376数据和命令/状态字的读写[8]。CH376以扇区方式写数据,并以.txt文件形式保存,其中函数filename()根据数据采样的次数,在根目录下生成文件名,例如第一次采集数据生成的文件名为/sjcj1.txt,第二次采集数据生成的文件名为/sjcj2.txt。函数write_command_to _usb(),以字节方式对CH376写1字节命令,函数send_string_to_usb(),向CH376发送字符串数据;函数write_shanqu(),将SDRAM中10 KB的数据,以扇区方式发送到U盘,并存在相应的文件下;函数write_data_to _usb,以字节方式对CH376写1字节数据。
//CH376命令定义
#define SET_FILE_NAME 0x2f
#define FILE_CREAT0x34
#define FILE_CLOSE0x0x36
……
static write_wenjian(unsigned char i){//根据文件编号,生成根目录下文件名。
wjm=filename(i);
write_command_to _usb(SET_FILE_NAME); //发送“设置文件名“命令
send_string_to_usb(wjm,12); //发送文件名
write_command_to _usb(FILE_CREAT); //发送“新建文件命令
while(ch376_intflag!=1) ; //等待发送命令完成
ch376_intflag=0;//将SDRAM数据写入第i-1扇区,每次写20个扇区,共10 KB。
write_shanqu(i);
write_command_to_usb(FILE_CLOSE);//关闭文件
write_data_to _usb(1);//更新文件长度
……
}
结语
本系统采用FPGA器件的SOPC技术,用NIOSII处理器控制CH376的USBHost模式完成大容量的数据快速采集存储,由于FPGA具有输入输出引脚多、运行速度快和可编程的特点,只要软件稍作修改,即可将数据存入SD卡中。经过软硬件的综合测试,能成功实现系统各项功能,弥补了单纯用单片机实现数据采集的不足,提高了系统的灵活性和数据的存储能力。