3 接口与驱动
根据S3C2410的SPI特点及AD7888的工作原理确定其接口如图3所示。
图3 AD7888与S3C2410的连接图
为了实现S3C2410和AD7888在嵌入式Linux下的高速A/D转换,还编写了两者接口的驱动程序,该驱动程序功能的实现主要由以下几个函数完成。
(1)Init_SPI()完成SPI的初始化
void Init_SPI(void)
{
int i;
rSPPRE0=0x32;
rSPCON0=0x1e;
for(i=0;i<10;i++)
rSPTDAT0=0xff;
rGPECON |=0x0a800000;
rGPECON&=(~0x05400000);
rGPEUP |=0x3800;
//GPH5----->CS
rGPHCON |=0x0400;
rGPHCON&=(~0x0800);
rGPHUP&=(~0x20);
rGPHDAT |=0x20;
}
(2)ad_wr()写入要求A/D转换的通道
static ssize_t ad_wr(struCt file *file,const char *bur,size_t count,loft_t *offset)
{
int ret=0;
int i=0;
dbuf=kmalloc(count *sizeof(unsigned char),GFP_KERNEL);
copy_from_user(dbuf,bur,count);
for(i=0;i<count;i++)
ADTXdata[i]=dbuf[i];
kfree(dbuf);
return ret;
}
(3)ad_rd()得到A/D转换的结果
statie ssize_t ad_rd(struet file *file,char *bur,size_t count,loft t *offset)
{
int ret=0;
int i=0;
ad_convert();
ad_convert();
dbuf=kmalloc(count *sizeof(unsigned char),GFP KERNEL);
for(i=0;i<count;i++)
dbuf[i]=ADRXdata[i];
copy_to_user(bur,dbuf,count);
kfree(dbuf);
return ret;
}
(4)ad_convert()实际完成A/D转换
void ad_convert(void)
{
rGPHDAT&=(~0x20);
udelay(100000);
spi_tx_data(ADTXdata[0]);
ADRXdata[0]=rSPRDATO;
spi_tx_data(0xff);
ADRXdata [1 ]=rSPRDATO;
rGPHDAT |=0x20;
}
(5)spi_tx_data()完成发送数据
void spi_tx_data(unsigned char data)
{
spi_poll_done();
rSPTDAT0=data;
spi_poll_done();
}
(6)spi_poll_done()轮询SPI状态
static void spi_poll_done(void)
{
while(!(rSPSTA0&0x01));
}
说明:1)ADTXdata和ADRXdata是unsigned char的全局数组变量,分别负责存放AD7888的控制寄存器数据和A/D转换的结果。2)ad_rd()中ad_convert()调用了2次,第1次调用用于通知要采某通道的数据,第2次调用用于得到该通道A/D转换的结果。这样虽然牺牲了一些转换的速度,但可使应用程序编程更加直观。
4 结论
应用带SPI接口的串行A/D转换器占用较少的微处理器I/O资源,硬件联接简单、软件易于实现,程序运行效率高。带有SPI接口的串行A/D转换器和ARM微处理器的结合可广泛应用于实现数据采集功能的掌上设备及其他嵌入式的系统,如:医疗仪器、通信设备、抄表设备等领域。