APP下载

基于Linux嵌入式系统的S3C6410和ADS1298R的SPI接口驱动的实现

2014-07-29汤沁徐学军彭地卓李骥

中国新通信 2014年1期

汤沁 徐学军 彭地卓 李骥

【摘要】 本文介绍了高速模数转换芯片ADS1298R与ARM11微控制器S3C6410利用串行外设接口(SPI)进行数据通信的应用方案,给出了两者SPI接口的连接图和Linux操作系统下驱动的具体实现方法,最后编写了应用程序进行测试,论证了该方法的可行性。ADS1298R和S3C6410基于SPI的串行通信方式为嵌入式高速数据采集系统提供了一个解决方案。

【关键词】 SPI驱动 ADS1298R S3C6410 Linux

SPI总线是一种同步串行外设接口, MCU通过它可以与各种外围设备进行数据通信[7]。SPI总线只需3~4根数据线和控制线即可扩展具有SPI接口的各种I/O器件,其硬件功能很强,实现软件相当简单[1]。SPI为全双工通信,显得简单高效,因而A/D转换器与ARM通过SPI接口相结合而组成的基于Linux的数据采集系统显得十分有效。

一、ADS1298R的特性和使用

ADS1298R是美国德州仪器公司推出的一款低功率,8通道,同步采样,24位三角积分模数转换器,此产品具有内置的可编程增益放大器(PGA),内部基准和一个板载振荡器[4]。运行数据速率最高可达32KSPS,时钟频率2.048MHz,具有串行外设接口(SPI),并兼容串口。其引脚定义如图1所示。

如图2所示为ADS1298R的串行接口时序图,串行时钟为数据的输入输出提供了传输时序。当一次数据转换完成后,DRDY变低,表示有数据可进行传输,将片选信号CS拉低,串行时钟开始工作,DRDY电平在SCLK的第一个时钟下降沿升高,在SCLK上升沿往外部控制设备传数据,在下降沿从外部控制设备读数据命令。数据传输阶段CS必须保持低电平,传输一组数据需要216个串行时钟周期。

二、S3C6410概述

S3C6410是三星公司推出的一款采用RISC架构的16/32位微控制器,它基于ARM1176JZF-S内核,高效的八级流水线使其贯通率比以前的ARM内核提高了40%[6]。最高时钟频率可达667MHz。

S3C6410含有2通道的SPI接口,可来实现串行数据的传输。每个SPI通道含有两个独立的32位发送和接收数据寄存器和两个32位移位寄存器,以及两个64字节的接收和发送FIFO,三者在SPI通信中的关系如图3所示。

三、SPI驱动

设备驱动是从操作系统当中提取物理或者虚拟设备的软件,是连接硬件与操作系统的桥梁。SPI驱动程序属于流接口驱动程序,导出标准的流接口函数,由流接口驱动管理器向应用程序提供文件系统,应用程序通过对文件系统的处理来完成对设备的操作[2,3]。

根据SPI接口连接原理,将ADS1298R和S3C6410的SPI接口引脚按图4所示的方式进行连接。

为了实现S3C6410与ADS1298R的数据通信,编写了基于嵌入式Linux操作系统下混杂设备驱动程序,该SPI驱动主要由以下几个函数构成。

(1)spi_init_function()完成SPI的初始化工作。首先将对应I/O口配置成SPI功能模式,然后对S3C6410的SPI寄存器进行如下顺序的配置。

●将SPI传输模式(CPOL&CPHA)配置成与ADS1298R一致。

●设置串行时钟配置寄存器CLK_CFG。

●设置SPI FIFO控制寄存器MODE_CFG。

●开Tx或Rx通道。

●将片选设置成手动模式,将NSSOUT设置成低并开始传输或接收数据[5]。

static void spi_init_function(void)

{······

CH_CFG = ((0 << 6) | (0 << 5) | (0 << 4) | (0 << 3) | (1 << 2) | (0 << 1) | (0 << 0));

CLK_CFG = ((0 << 9) | (1 << 8) | (0x4 << 0));

MODE_CFG = ((0 << 29) | (0 << 19) | (0 << 17) | (1 << 11) | (1 << 5)

| (0 << 2) | (0 << 1) | (0 << 0));

SLAVE_SEL = (0x00);

······}

(2)spi_write()用于向ADS1298R传递控制命令。S3C6420通过spi_write()函数向ADS1298R传递命令,使其工作在对应状态。传数据时开发送通道,并将CS信号拉低,然后将用户层传递过来的命令通过图3的发送通道传送至ADS1298R,ADS1298R在SCLK的下降沿从DIN将数据读入。

static ssize_t spi_write(struct file *filp,const char __user *buff,size_t count,loff_t *offp)

{······

SPI_CS_LOW( );

for(i=0;i

writeByte(kbuf[i]);

SPI_CS_HIGH();

······}

(3)spi_read( )用于读取经AD转换后的数据。ADS1298R将转换的数据准备好后,DRDY信号变低,S3C6410便可开接收通道,并拉低CS,然后通过图3的接收通道接收数据,ADS1298R在SCLK的上升沿将数据从DOUT送出。

static ssize_t spi_read(struct file *filp, char __user *buff, size_t count, loff_t *offp)

{······

SPI_CS_LOW( );

while(!DRDY);

for(i=0;i<9;i++)

tab[i] = readByte( );

SPI_CS_HIGH( );

······}

四、SPI测试程序

为了测试驱动的正确性,编写了测试应用程序对驱动进行测试。为了方便对ADS1298R工作模式和状态的控制,我们将对ADS1298R的控制命令放在了应用程序里。对ADS1298R的控制主要是对其23个可读可写寄存器的配置。用ADS1298R内部自带测试信号进行测试。测试程序包括两部分,第一部分目的是通过传递命令方式配置ADS1298R相应寄存器,本测试程序对ADS1298R的控制命令集为:

ADS1299RegVal[27]=

{0x41,0x18,0x85,0x10,0xdc,0x03,0x05,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x01,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02,0x0a,0xe3};

第二部分循环读ADS1298R,并将读到的数据以数据流的形式存入文件中。

由以下两个函数实现:

read(spi_fd,&data,3);

fprintf(stream,"%06lx\40",data);

测试结果如图5所示。

并且我们还用信号源输出正弦波形进行了单通道测试,其中正弦波幅值为100mVpp,频率为10Hz。测试结果如图6所示,由于配置的A/D增益为6,故输出波形幅值为600mVpp。

对采集的波形进行功率谱分析,结果如图7所示。

五、结论

经测试本SPI驱动能实现ADS1298R与S3C6410之间的串行数据通信。使用带SPI接口的A/D与微控制器相连进行数据采集系统的开发具有占微控制器I/O资源少,硬件连接方便,软件开发易于实现的特点。此SPI驱动只需稍加修改便可与其他带SPI接口的A/D相连,具有很好的可移植性。带SPI接口的A/D与ARM微控制器结合能很好的应用于具有信号采集功能的嵌入式系统,如抄表系统、医疗仪器、监控设备等领域。endprint

{······

SPI_CS_LOW( );

while(!DRDY);

for(i=0;i<9;i++)

tab[i] = readByte( );

SPI_CS_HIGH( );

······}

四、SPI测试程序

为了测试驱动的正确性,编写了测试应用程序对驱动进行测试。为了方便对ADS1298R工作模式和状态的控制,我们将对ADS1298R的控制命令放在了应用程序里。对ADS1298R的控制主要是对其23个可读可写寄存器的配置。用ADS1298R内部自带测试信号进行测试。测试程序包括两部分,第一部分目的是通过传递命令方式配置ADS1298R相应寄存器,本测试程序对ADS1298R的控制命令集为:

ADS1299RegVal[27]=

{0x41,0x18,0x85,0x10,0xdc,0x03,0x05,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x01,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02,0x0a,0xe3};

第二部分循环读ADS1298R,并将读到的数据以数据流的形式存入文件中。

由以下两个函数实现:

read(spi_fd,&data,3);

fprintf(stream,"%06lx\40",data);

测试结果如图5所示。

并且我们还用信号源输出正弦波形进行了单通道测试,其中正弦波幅值为100mVpp,频率为10Hz。测试结果如图6所示,由于配置的A/D增益为6,故输出波形幅值为600mVpp。

对采集的波形进行功率谱分析,结果如图7所示。

五、结论

经测试本SPI驱动能实现ADS1298R与S3C6410之间的串行数据通信。使用带SPI接口的A/D与微控制器相连进行数据采集系统的开发具有占微控制器I/O资源少,硬件连接方便,软件开发易于实现的特点。此SPI驱动只需稍加修改便可与其他带SPI接口的A/D相连,具有很好的可移植性。带SPI接口的A/D与ARM微控制器结合能很好的应用于具有信号采集功能的嵌入式系统,如抄表系统、医疗仪器、监控设备等领域。endprint

{······

SPI_CS_LOW( );

while(!DRDY);

for(i=0;i<9;i++)

tab[i] = readByte( );

SPI_CS_HIGH( );

······}

四、SPI测试程序

为了测试驱动的正确性,编写了测试应用程序对驱动进行测试。为了方便对ADS1298R工作模式和状态的控制,我们将对ADS1298R的控制命令放在了应用程序里。对ADS1298R的控制主要是对其23个可读可写寄存器的配置。用ADS1298R内部自带测试信号进行测试。测试程序包括两部分,第一部分目的是通过传递命令方式配置ADS1298R相应寄存器,本测试程序对ADS1298R的控制命令集为:

ADS1299RegVal[27]=

{0x41,0x18,0x85,0x10,0xdc,0x03,0x05,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x01,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02,0x0a,0xe3};

第二部分循环读ADS1298R,并将读到的数据以数据流的形式存入文件中。

由以下两个函数实现:

read(spi_fd,&data,3);

fprintf(stream,"%06lx\40",data);

测试结果如图5所示。

并且我们还用信号源输出正弦波形进行了单通道测试,其中正弦波幅值为100mVpp,频率为10Hz。测试结果如图6所示,由于配置的A/D增益为6,故输出波形幅值为600mVpp。

对采集的波形进行功率谱分析,结果如图7所示。

五、结论

经测试本SPI驱动能实现ADS1298R与S3C6410之间的串行数据通信。使用带SPI接口的A/D与微控制器相连进行数据采集系统的开发具有占微控制器I/O资源少,硬件连接方便,软件开发易于实现的特点。此SPI驱动只需稍加修改便可与其他带SPI接口的A/D相连,具有很好的可移植性。带SPI接口的A/D与ARM微控制器结合能很好的应用于具有信号采集功能的嵌入式系统,如抄表系统、医疗仪器、监控设备等领域。endprint