历史上的今天
返回首页

历史上的今天

今天是:2024年10月10日(星期四)

正在发生

2019年10月10日 | MSP430程序库<六>通过SPI操作AD7708

2019-10-10 来源:eefocus

AD7708是16位的Σ-Δ型AD转换芯片,在低频应用中,AD7708可以作为单电源供电的完整前端。AD7708内部含有一个PGA(可编程增益放大器),可以完成对信号的放大;PGA范围是20-28八档可编程,当取参考电压2.5v时可以测量量程20mv到2.56v的电压。AD7708和AD7718引脚功能完全一样,只是位数AD7718是24位的,若用7718,只需改动少部分的程序,16位的部分改成24位即可。AD7708是通过SPI接口通信的;程序使用前一篇实现的SPI程序与AD芯片通信,可以作为SPI详细的使用示例。


硬件介绍:

硬件主要是MSP430的SPI接口和AD7708芯片的说用说明。


msp430的SPI接口:支持主机模式和从机模式,且始终的极性和相位可调,在于AD转换芯片通信的时候,需要极性一致。有关msp430的SPI的详细介绍,参考:MSP430程序库<五>SPI同步串行通信。


AD7718 的外部引脚有28 个。按性质主要分为模拟、数字两个部分。模拟部分引脚有模拟输入、参考电压输入和模拟电源三类。模拟输入引脚可以配置为8通道或10通道的伪差分输入,他们共同参考AINCOM端。


数字部分引脚有 SPI 接口、数据就绪、通用I/O 口和数字电源四类。SPI 接口的4 根标准信号线分别是片选信号CS 、串行时钟输入SCLK、串行数据输入DIN 和串行数据输出DOUT。当AD7718接在SPI 总线上时是从器件,从引脚CS 输入低电平信号使能AD7718。数据就绪RDY 是一个低电平有效的输出引脚。当所选通道数据寄存器中有有效数据时,输出低电平信号;数据被读出后,输出高电平。AD7718 的通用I/O 口是2 个一位口P1 和P2。它们既可配置成输入也可配置成输出,单片机通过SPI 口读写AD7718 片内相关寄存器实现对P1 和P2 的操作。它们扩展了单片机的I/O 接口能力。


AD7718 的模拟电源和数字电源是分别供电的,都既可以采用+3V 供电,也可以采用+5V 供电。但必须一致,要么都用+3V,要么都用+5V。


AD7708和AD7718是通过一组片内寄存器控制和配置的。这些寄存器的第一个是通信寄存器,它是用来控制转换器的所有操作。这些部件的所有通信必须先写通信寄存器指定要执行的下一个操作。上电或复位后,设备默认等待写通信寄存器。 STATUS寄存器包含转换器的操作条件的有关信息。 STATUS寄存器是只读寄存器。模式寄存器用于配置转换模式,校准,斩波(chop)启用/禁用,参考电压选择,通道配置和伪差分AINCOM模拟输入操作时的缓冲或无缓冲。模式寄存器是一个读/写寄存器。 ADC控制寄存器是一个读/写寄存器,用来选择活动的通道和编码输入范围和双极性/单极性操作。I/O控制寄存器是一个读/写寄存器,用于配置了2个I/O端口的操作。滤波寄存器是一个读/写寄存器,用于编码转换器的数据更新率。 ADC数据寄存器是一个只读寄存器,它包含在所选通道上的一个数据转换的结果。 ADC的失调寄存器读/写寄存器包含偏移校准数据。有五个偏移寄存器,每个全差分输入通道之一。当配置为伪差分输入模式下的通道共用偏移寄存器。 ADC增益寄存器是读/写寄存器,包含增益校准数据。有5个ADC增益寄存器,每个全差分输入通道之一。当配置为伪差分输入模式通道共享增益寄存器。该ADC包含工厂使用的测试寄存器,用户应不改变这些寄存器的操作条件。 ID寄存器是一个只读寄存器,用于硅识别目的。


我用的硬件连线方式:430的P3.0接AD7708的CS端,P3.1-P3.2接对应的AD芯片的SPI口;RDY信号没有接;所以,程序使用的是查询方式,等待STATUS寄存器的RDY位指示转换完成。


有关AD7708的详细信息可以参考它的datasheet;另外我对数据手册的寄存器部分和程序流程的部分进行了翻译,如果需要,可以在本博客底部的附件中下载。


程序实现:

首先是对AD7708的读写寄存器函数,AD7708的每次操作都以写通信寄存器开始,通过这一步,指示下一步将进行什么操作;有关寄存器每一位的意义,参考附件(博客结尾)中的AD7708-寄存器


写入寄存器:


void AD7708WriteRegister(char addr,long dat)

{

    SpiWriteData(addr);     //写通信寄存器,通知下个操作:写addr寄存器

    if(IsLong[addr])        //如果是16位寄存器, 7718则24位若移植要改if内语句

    {

        SpiWriteData(dat>>8);

    }

    SpiWriteData(0xFF&dat);       //写入低位数据

}

寄存器地址,可以查阅datasheet或我翻译的那部分;IsLong字符数组指示对应的寄存器是8位还是16位的:


char IsLong[16] = {0,0,0,0,1,1,1,0,0,0,0,0,1,1,0,0};

读取寄存器:


long AD7708ReadRegister(char addr)

{

    char h = 0,l = 0;           //高低字节数据

    SpiWriteData(0x40|addr);    //写通信寄存器,通知下个操作:读addr寄存器

    if(IsLong[addr])

    {

        h = SpiWriteData(0xFF);

    }

    l = SpiWriteData(0xFF);

    return ((unsigned int)h<<8)|l;

}

SPI解释:430是SPI主机模块,当发送的时候,同时,另外一个时钟沿采样接收,所以,每次发送完成后的半个周期,均可得到读出的数据;所以SpiWriteData函数写入的同时返回同时收到的字符。发送0xFF即是为提供读取即将到来的数据提供时钟,详细可以参考上一篇的注意事项部分(刚更新的)。


读取结果数据:


long AD7708ReadResultData()

{

    while((AD7708ReadRegister(0x00)&0x80)==0); //等待转换完成

    return AD7708ReadRegister(0x04);

}

等待STATUS的RDY位变高(AD数据转换更新完成),读取data寄存器的内容。


校准:校准的过程在datasheet中有详细的流程图;可以参考datasheet或者附件中的AD7708-寄存器,这个子函数只完成一个通道的校准,通道地址有参数输入,方便调用:


void AD7708Cal(char channel)

{

    adccon = (adccon&0x0f)|(channel<<4);

    mode = (mode&0xf8)|0x04;                //内部0校准

    AD7708WriteRegister(0x02,adccon);       //ADC控制寄存器,channel通道

    AD7708WriteRegister(0x01,mode);         //模式寄存器

    while((AD7708ReadRegister(0x01)&0x07)!=0x01);   //等待校准完成

    

    mode = (mode&0xf8)|0x05;                //内部 满标度校准

    AD7708WriteRegister(0x01,mode);         //模式寄存器

    while((AD7708ReadRegister(0x01)&0x07)!=0x01);   //等待校准完成

}

adccon是程序记录的前一次输入的ADCCON寄存器的内容,mode是程序记录的上一次输入的MODE寄存器的内容,因为串口读取需要时间,为了获取更快的速度,程序记录了这两个变量,以供使用。通道地址参考datasheet,或附件中的文档。


初始化:


void AD7708Init(char chop)

{

P3DIR|=BIT0;

P3OUT&=~BIT0;                            //CS选中

    //主机模式,115200,8位数据位,三线模式,时钟模式1(具体见spi.c)

    SpiMasterInit(115200,8,3,1);        //时钟不是准确的115200(具体见spi.c)

    _EINT();                            //开中断,spi读写程序要需要中断

    

    char filter;

    adccon = 0x0f;

    if(chop == 0)

    {

        filter = 0x03;                  //滤波寄存器设为最小值,可以更改

        mode = 0x91;                    //斩波禁止,10通道,无缓冲,空闲模式

    }

    else

    {

        filter = 0x0D;                  //滤波寄存器设为最小值,可以更改

        mode = 0x11;                    //斩波启用,10通道,无缓冲,空闲模式

    }

    

    AD7708WriteRegister(0x07,0x00);     //IO寄存器,不用==

    AD7708WriteRegister(0x03,filter);   //滤波寄存器

    AD7708WriteRegister(0x02,0x0F);     //ADC控制寄存器,0通道,单极性

    AD7708WriteRegister(0x01,mode);     //模式寄存器

    if(chop == 0)

        for(int i = 0; i<5;i++)

        {

            //校准,因只有5个失调寄存器,多的就会覆盖之前的,只校准5个即可

            AD7708Cal(5);

        }

    

    _DINT();

}

初始化制引入了斩波这一个参数,其他的均使用固定的参数:10通道伪差分、单极性、无缓冲、滤波寄存器设为斩波或禁止斩波时候的最快速度,需要的话可以自行修改。SPI初始化之后开中断,目的是向AD写内容以初始化AD。初始化完成后关中断,为了让程序库的初始化后一致,但调用这个函数后,需要开中断,才能正常使用AD采样的其它函数。


采样启动:本程序只支持了单词采样的开始,若需要连续模式的,可以自行实现(比较容易实现:只需更改寄存器的值即可):


void AD7708Start(char channel)

{

    adccon = (adccon&0x0f)|(channel<<4);

    mode = (mode&0xf8)|0x02;

    AD7708WriteRegister(0x02,adccon);

    AD7708WriteRegister(0x01,mode);

}

根据之前一次的控制寄存器和模式寄存器的设置,更改现在需要的值,写入相应寄存器即可。


到此,程序部分完成,需要扩展,可以自行添加。


使用说明:

使用时,只需加入AD7708.c,文件包含AD7708.h,然后就可以正常使用本程序提供的函数;具体可以参考示例工程和其中的main.c文件。


long a;

void main()

{

    // Stop watchdog timer to prevent time out reset

    WDTCTL = WDTPW + WDTHOLD;

    ClkInit();

    AD7708Init(0);  //禁止斩波 1时启用斩波

    

    _EINT();        //开中断,程序需要用到SPI的中断;冲突,可以更改SPI函数

    

    while(1)                    //串口测试

    {

        AD7708Start(0);

        a = AD7708ReadResultData();         //读取AD采样后的结果

        //电压计算方法:a*1.024*2.5(参考电压)/65535

        a = AD7708ReadRegister(0);          //去状态值,此处函数不需要用

        

    }

}

AD7708的程序库(简化,其他需求可以自行添加:有读写寄存器的函数之后,添加其他功能比较简单)已经完成,有什么不足之处欢迎大家讨论;谢啦。


推荐阅读

史海拾趣

华瓷(Chinocera)公司的发展小趣事

在追求经济效益的同时,华瓷始终注重环保和可持续发展。公司投入大量资金用于研发环保型陶瓷材料和生产工艺,致力于减少生产过程中的能源消耗和废弃物排放。同时,华瓷还积极参与社会公益事业,为保护环境、促进可持续发展贡献自己的力量。

Device Engineering Incorporated公司的发展小趣事

随着公司业务的不断发展,DEI公司开始考虑国际化拓展。他们积极寻求与国际知名企业的合作,通过技术交流和共同研发,不断提升自身实力。同时,DEI公司也在全球范围内建立了销售网络,将产品推向了更广阔的市场。这一举措不仅提高了公司的知名度,也为公司带来了可观的收益。

DATATRONICS公司的发展小趣事

DATATRONICS深知产品质量是企业生存和发展的基石。因此,公司投入大量资源用于建立和完善质量管理体系,确保每一款产品都符合国际标准和客户要求。同时,DATATRONICS还注重品牌形象的塑造,通过一系列营销活动和公益活动,提高了品牌知名度和美誉度。

Gigarams Semiconductor Device Corp公司的发展小趣事
这可能是由于控制算法复杂或系统响应速度不足导致的。解决方案包括简化控制算法、提高系统响应速度或采用更高效的控制策略。
港源(GANGYUAN)公司的发展小趣事
这可能是由于传感器精度不足、控制器算法不准确或驱动器性能不稳定等原因导致的。解决方案包括提高传感器精度、优化控制器算法和更换性能更稳定的驱动器。
国产公司的发展小趣事
对于功率较大的放大器,需要采用高效的散热措施来确保电路的稳定运行和长寿命。

问答坊 | AI 解惑

无形的屏幕

哇,我的电脑屏幕隐形了,成透明的了,这...这...怎么可能?淡定淡定,这不是灵异事件,奥秘来自于墙纸...厌倦了常规的墙纸当屏幕背景,那就看一下这一组怪异墙纸,它们会让你的屏幕变无形。但是事实是,屏幕还在,只不过是视觉欺骗了我们的感觉。 ...…

查看全部问答>

有人知道用920T的盒做个ARM9的板子,大约要多少钱吗?

有人知道用920T的盒做个ARM9的板子,大约要多少钱吗?芯片在哪买?…

查看全部问答>

能否根据windows驱动程序(release bin)编写linux驱动

有没有可能通过反编译等方式生成一个linux驱动 有没有捷径可以走…

查看全部问答>

请教一个简单的C51程序,

#include main() {         TMOD=0X10;         TH1=0XFE;         TL1=0X0C;         TR1=1;         ET1=1;       ...…

查看全部问答>

发个清华蓬远地取模软件

前几天取汉字模从网上下个软件,不太好,就因为取然的格式带H地,我要C语言数组地,以前用过清华蓬远的取模软件,我认为是最好地,今天翻出特发上来,大家共享,我也MARK,省得以后再找不到,呵呵…

查看全部问答>

一个晶振引发的问题

本来是51好板,就是CPU座松了,让同事搞一下变紧,拿回来突然不好用,仿真器上也不好用,本来屏幕可显开机画面,但怎么也搞不定,由于急有找了另一台机器总算把程序实验完,第二天对着这个坏板研究起来,首先是换51的40脚DIP座,小心得很,因为板上 ...…

查看全部问答>

菜农友情为STM32设计一种通用加密方法之原理

今天连续看了两篇关于加密方面的帖子,感觉自己应该友情奉献一回了~~~ 设想一种加密办法,大家看看可行吗? 关于STM32F器件电子签名以及加密问题-请指点 今日方知STM32的UID为96位即12个字节,以前知道STM32内嵌CRC32. 网上在线CRC演算工 ...…

查看全部问答>

急求一个实际应用中的反向比例运算放大电路

简要说明一下放大电路的原理和作用…

查看全部问答>

基一于PT1311的单片机升压电路设计

单片机有的是用1AA或2AA 电池供电的,这时为了保正单片机的工作电压在2.5~5.0之间,这时就要用到DC-DC升压电路了,升压电路一般要用到电感 和肖特基二极管 电阻 电容等外围元件,空间较小的情部一下就要想办法精简一下外围器件了,这时不需电感和肖 ...…

查看全部问答>

Z_Stack_2.5.1a双向绑定

最近在做关于绑定的项目,使用2.5.1a协议栈,发现协调器不能绑定终端节点,求各位大神帮忙解答!…

查看全部问答>