ADC(一)—AD7683/AD7684/ADS8317

本文介绍如何使用STM32F1单片机驱动AD7683 ADC芯片,包括选择理由、器件特点、驱动程序实现及总结。重点讨论了SPI接口配置和数据读取方法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1.写在前面

项目需要用到模拟信号转换(ADC),由于精度、速度及准确度都要求比较高,故选择外设独立ADC芯片。外置独立ADC价格上都比较贵,首先考虑的是ADI的器件,经过综合价格、性能、采购渠道等,最终选择AD7683/AD7684。AD7683和AD7684的区别是前者是伪差分输入,后者是真差分输入,其他性能基本一致,程序兼容。ADS8317是德州仪器(TI)产的,与AD7684兼容,都是真差分输入,程序三者都兼容。

2.器件特点

主要特点:

1)转换精度:16bit

2)转换速率:100kSPS

3)独立供电和参与源

4)伪差分输入/真差分输入

5)3线spi控制接口

6)使用简单,无复杂的寄存器配置,直接通过spi获取转换数据

7)8 pin msop封装

3.驱动程序

通过芯片数据手册可以知道,对于驱动程序,只需将spi总线实现,即是成功了90%。上一篇博客中我有写到spi的封装过程和相关代码,那么这次使用起来应该非常方便和易理解,也体现下这样做的好处,具体查看上一篇文章:“spi抽象/硬件spi

1)驱动一个器件,首先是查看器件时序图,AD7683的spi时序图如图:

具体分析

a)读取一个完整的16bit数据,至少需要24个时钟周期;

b)有效数据为中间16bit,注意前后无效bit数据。

ADI的器件特别喜欢这样的非标spi(避专利?),很多人第一想法就是用模拟spi去读取,ADI官方一些例程大部分也是模拟spi,其实都是可以用硬件spi去实现,取其中有效数据即可。当然用模拟spi也很容易实现。下面是以stm32f1单片机为硬件平台,利用上一文章“spi模型/硬件spi”中的spi总线模型驱动AD7683。

#include <string.h>
#include "spi_hw.h"

/* ad7684 spi device */
static struct spi_dev_device ad7684_spi_dev[3];

static void ad7684_spi_cs0(uint8_t state)
{
    if (state)
    {
        GPIO_SetBits(GPIOC, GPIO_Pin_6);
    }
    else
    {
        GPIO_ResetBits(GPIOC, GPIO_Pin_6);
    }
}

static void ad7684_spi_cs1(uint8_t state)
{
    if (state)
    {    
        GPIO_SetBits(GPIOC, GPIO_Pin_8);
    }
    else
    {
        GPIO_ResetBits(GPIOC, GPIO_Pin_8);
    }
}

static void ad7684_spi_cs2(uint8_t state)
{
    if (state)
    {
        GPIO_SetBits(GPIOA, GPIO_Pin_11);
    }
    else
    {
        GPIO_ResetBits(GPIOA, GPIO_Pin_11);
    }
}

int8_t ad7684_init(struct spi_bus_device *spi_bus)
{	
    GPIO_InitTypeDef GPIO_InitStructure;
	
    if (NULL == spi_bus)
    {
        return -1;
    }
	
    /* spi cs */
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC |RCC_APB2Periph_GPIOA ,ENABLE);
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6 | GPIO_Pin_8;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;  
    GPIO_Init(GPIOC, &GPIO_InitStructure);
    GPIO_SetBits(GPIOC,GPIO_Pin_6);
    GPIO_SetBits(GPIOC,GPIO_Pin_8);
	
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
    GPIO_Init(GPIOA, &GPIO_InitStructure);
    GPIO_SetBits(GPIOA,GPIO_Pin_11);
	
    /* device init */
    ad7684_spi_dev[0].spi_cs  = ad7684_spi_cs0;
    ad7684_spi_dev[0].spi_bus = spi_bus;
    
    ad7684_spi_dev[1].spi_cs  = ad7684_spi_cs1;
    ad7684_spi_dev[1].spi_bus = spi_bus;
	
    ad7684_spi_dev[2].spi_cs  = ad7684_spi_cs2;
    ad7684_spi_dev[2].spi_bus = spi_bus;

    return 0;
}

/**
  * @brief  read ad data from ad7684.
  * @param  \index ad7684 device,1 or 2 or 3
  * @retval none
  */

uint16_t ad7684_read(uint8_t index)
{
    uint8_t send_buff[3] = {0};
    uint8_t recv_buff[3] = {0};

    if (index < 1 || index > 3)
    {
        return 0;
    }
    spi_send_recv(&ad7684_spi_dev[index-1], send_buff, recv_buff, 3);

    return ((((recv_buff[0] << 16) | (recv_buff[1] << 8) | recv_buff[2])>>2)&0xffff);
}

spi的配置模式:

a)速率:SPI_BaudRatePrescaler_8分频;

b)模式:L 1或者 H 3;

c)方向:全双工;

d)其他查看上一文章源码。

具体分析:

a)源码是之前AD7684程序,命名没有修改,程序百分百兼容;

b)上面是一根spi总线挂了3片AD7683,定义了3个spi设备结构体和一个spi总线结构体;初始化了3个片选;总线初始化由“spi_core.h”及“spi_hw.c”实现,无需再调试修改;

c)初始化函数是片选IO设置及指针赋值;

d)读函数,用的API是“spi_send_recv”,从时序图也可看出;此时的“发送”动作并不是真正的发送,只是用来产生接收数据的时钟信号;

——第一个参数即为前面初始化的3个设备之一

——send_buff:“发送”3个字节,产生24个时钟信号(非真正发送)

——recv_buff:接收3个字节的返回值,高位在前

e)返回值,“return ((((recv_buff[0] << 16) | (recv_buff[1] << 8) | recv_buff[2])>>2)&0xffff)”通过移位(<</>>)和与(&)动作获取16位有效的数据。

4.总结

1)主要是体现上一文章中,spi封装的好处,驱动一个新的spi器件,或者多个spi器件时,可以非常方便地实现;

2)学会看器件时序图,非标准spi大部分情况都可以用标准spi实现;

3)摆脱重复调试spi的无用工作;

4)方便移植驱动程序到新的平台。

5.相关源码

[1]  https://github.com/Prry/drivers-for-mcu

6.参考

[1]  http://blog.youkuaiyun.com/qq_20553613/article/details/78998617

 

评论 20
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Acuity.

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值