ADC芯片——AD7705最详细讲解(STM32)「建议收藏」

ADC芯片——AD7705最详细讲解(STM32)「建议收藏」目录

大家好,又见面了,我是你们的朋友全栈君。

前言

   读者必读:本人在专业实习的时候用到了外部ADC模块——AD7705,在使用的过程中参考过很多资料,有些资料非常有用,有些资料讲的有些小问题。
  切记:一定要看英文芯片手册DataSheet,网上的AD7705中文手册也就参考一下。英文手册

参考资料: 1.https://www.amobbs.com/thread-5535730-1-1.html?_dsign=4f28e329
      2.https://www.cnblogs.com/BlueMountain-HaggenDazs/p/4740758.html
      3. https://blog.csdn.net/ysgjiangsu/article/details/94650445?utm_medium=distribute.pc_relevant.none-task-blog-baidulandingword-8&spm=1001.2101.3001.4242

1. AD7705简介

  AD7705/7706 是应用于低频测量的 2/3 通道的模拟前端。该器件可以接受直接来自传感器的低电平的输入信号,然后产生串行的数字输出。利用Σ-∆转换技术实现了 16 位无丢失代码性能。选定的输入信号被送到一个基于模拟调制器的增益可编程专用前端。片内数字滤波器处理调 制器的输出信号。通过片内控制寄存器可调节滤波器的截止点和输出更新速率,从而对数字滤波 器的第一个陷波进行编程。
   AD7705/7706 只需 2.7~3.3V 或 4.75~5.25V 单电源。AD7705 是双通道全差分模拟输入,而 AD7706 是 3 通道伪差分模拟输入,二者都带有一个差分基准输入。当电源电压为 5V、基准电压 为 2.5V 时,这二种器件都可将输入信号范围从 0~+20mV 到 0~+2.5V 的信号进行处理。还可处 理±20mV~±2.5V 的双极性输入信号,对于 AD7705 是以 AIN(-)输入端为参考点,而 AD7706 是 COMMON 输入端。当电源电压为 3V、基准电压为 1.225V 时,可处理 0~+10mV 到 0~+1.225V 的单 极性输入信号,它的双极性输入信号范围是±10mV 到±1.225V。因此,AD7705/7706 可以实现 2/3 通道系统所有信号的调理和转换。
  CMOS 结构确保器件具有极低功耗,掉电模式减少等待时的功耗至 20μW(典型值)。 AD7705/7706 采用 16 脚塑料双列直插(DIP)和 16 脚宽体(0.3 英寸)SOIC 封装和 16 脚 TSSOP 封装。如图1为AD7705模块
AD7705模块
                                    图 1 AD7705模块

1.1 特性参数

  英文手册是这样描述的
在这里插入图片描述
简要概括一下

 1. 16位无丢失代码性AD转化器

 2. 芯片5V供电时,REF建议电压范围是1V~3.5V,推荐值2.5V;

 3. 芯片3V供电时,REF建议电压范围是1V~1.75V,推荐值1.225V,模块上参考电压芯片是REF192-2.048,也就是2.048V,显然都不是推荐值,且这已经超出了3V供电的推荐范围,因此电路设计不规范。
 
 4. 双通道差分输入

 5. 基准电压为2.5V时,在单极性信号下,输入范围是0到2.5V,在双极性输入下,输入范围是-1.25到+1.25

 6. 低功耗CMOS芯片,功耗一般为20uW
 
 7.  可编程,可编程增益,以及降噪参数等。 

1.2 功能方框图

在这里插入图片描述

1.3 引脚排列及其功能

  (1) 引脚排列图
在这里插入图片描述

  (2) 引脚功能表

管脚名称 功能
SCLK Serial Clock. An external serial clock is applied to the Schmitt-triggered logic input to access serial data from the AD7705/AD7706. This serial clock can be a continuous clock with all data transmitted in a continuous train of pulses. Alternatively, it can be a noncontinuous clock with the information transmitted to the AD7705/AD7706 in smaller batches of data.                         串行时钟,施密特逻辑输入。将一个外部的串行时钟加于这一输入端口,以访问AD7705/7706 的串行数据。和单片机传输数据时的控制时钟
MCLK IN   Master Clock Signal. This can be provided in the form of a crystal/resonator or external clock. A crystal/resonator can be tied across the Pin MCLK IN and Pin MCLK OUT. Alternatively, the MCLK IN pin can be driven with a CMOS-compatible clock with the MCLK OUT pin left unconnected. The parts can be operated with clock frequencies in the range of 500 kHz to 5 MHz.                 为转换器提供主时钟信号。能以晶体/谐振器或外部时钟的形式提供。晶体/谐振器可以接在MCLKIN 和MCLKOUT 二引脚之间。此外,MCLKIN 也可用CMOS 兼容的时钟驱动, 而MCLKOUT 不连接。时钟频率的范围为500kHz~5MHz
MCLK OUT    When the master clock for these devices is a crystal/resonator, the crystal/resonator is connected between Pin MCLK IN and Pin MCLK OUT. If an external clock is applied to Pin MCLK IN, Pin MCLK OUT provides an inverted clock signal. This clock can be used to provide a clock source for external circuitry and is capable of driving 1 CMOS load. If the user does not require this clock externally, Pin MCLK OUT can be turned off via the CLKDIS bit of the clock register. This ensures that the part does not unnecessarily burn power driving capacitive loads on Pin MCLK OUT.                                              当主时钟为晶体/谐振器时,晶体/谐振器被接在MCLKIN 和MCLKOUT 之间。如果在MCLKIN 引脚处接上一个外部时钟,MCLKOUT 将提供一个反相时钟信号。这个时钟可以用来为外部电路提供时钟源,且可以驱动一个CMOS 负载。如果用户不需要,MCLKOUT 可以通过时钟寄存器中的CLKDIS位关掉。这样,器件不会在MCLKOUT 脚上驱动电容负载而消耗不必要的功率
CS ‾ \overline{\text{CS}} CS Chip Select. Active low logic input used to select the AD7705/AD7706. With this input hardwired low, the AD7705/AD7706 can operate in its 3-wire interface mode with Pin SCLK, Pin DIN, and Pin DOUT used to interface to the device. The CS pin can be used to select the device communicating with the AD7705/AD7706.                                        片选,低电平有效的逻辑输入,选择AD7705/7706。将该引脚接为低电平,AD7705/7706 能以三线接口模式运行(以SCLK、DIN 和DOUT 与器件接口)。在串行总线上带有多个器件的系统中,可由CS’对这些器件作出选择,或在与AD7705/7706 通信时,CS’可用作帧同步信号
RESET ‾ \overline{\text{RESET}} RESET Logic Input. Active low input that resets the control logic, interface logic, calibration coefficients, digital filter, and analog modulator of the parts to power-on status.                                                   复位输入。低电平有效的输入,将器件的控制逻辑、接口逻辑、校准系数、数字滤波器和模拟调制器复位至上电状态
AIN2(+) Positive Input of the Differential Analog Input Pair AIN2(+)/AIN2(−) for AD7705. Channel 1 for AD7706.                 差分模拟输入通道1的正输入端。
AIN1(+) Positive Input of the Differential Analog Input Pair AIN1(+)/AIN1(−) for AD7705. Channel 2 for AD7706.                  差分模拟输入通道2 的正输入端。
AIN1(-) Negative Input of the Differential Analog Input Pair AIN1(+)/AIN1(−) for AD7705. COMMON input for AD7706 with Channel 1, Channel 2, and Channel 3 referenced to this input.                                           AD7705的差分模拟输入对AIN1(+)/AIN1(-)的负输入。AD7706的常用输入,通道1、通道2和通道3引用该输入。
REFIN(+) Reference Input. Positive input of the differential reference input to the AD7705/AD7706. The referenceinput is differential with the provision that REF IN(+) must be greater than REF IN(−).REF IN(+) can lie anywhere between VDD and GND.            基准输入端,基准输入是差分的,并规定REFIN(+)必须大于REFIN(-)。REFIN(+)可以取VDD 和GND 之间的任何值
REFIN(-) Reference Input. Negative input of the differential reference input to the AD7705/AD7706. The REF IN(−) can lie anywhere between VDD and GND, provided that REF IN(+) is greater than REF IN(−).                                   基准输入端,REFIN(-)可以取VDD 和GND 之间的任何值,且满足REFIN(+)大于REFIN(-)
AIN2(−) Negative Input of the Differential Analog Input Pair AIN2(+)/AIN2(−) for AD7705. Channel 3 for AD7706.               AD7705的差分模拟输入对AIN2(+)/AIN2(−)的负输入。AD7706对应第三通道。
DRDY ‾ \overline{\text{DRDY}} DRDY Logic Output. A logic low on this output indicates that a new output word is available from the AD7705/AD7706 data register. The DRDY pin returns high upon completion of a read operation of a full output word. If no data read has taken place between output updates, the DRDY line returns high for 500 × tCLK IN cycles prior to the next output update. While DRDY is high, a read operation should neither be attempted nor in progress to avoid reading from the data register as it is being updated. The DRDY line returns low after the update has taken place. DRDY is also used to indicate when the AD7705/AD7706 has completed its on-chip calibration sequence.          逻辑输出。这个输出端上的逻辑低电平表示可从AD7705/7706 的数据寄存器获取新的输出字。完成对一个完全的输出字的读操作后,DRDY’引脚立即回到高电平。如果在两次输出更新之间,不发生数据读出,DRDY’将在下一次输出更新前500×tCLKIN 时间返回高电平。当DRDY’处于高电平时,不能进行读操作,以免数据寄存器中的数据正在被更新时进行读操作。当数据被更新后,DRDY’又将返回低电平。DRDY’也用来指示何时AD7705/7706 已经完成片内的校准序列.
DOUT Serial Data Output. Serial data is read from the output shift register on the part. The output shift register can contain information from the setup register, communication register, clock register, or data register, depending on the register selection bits of the communication register                                                               串行数据输出端
DIN Serial Data Input. Serial data is written to the input shift register on the part. Data from the input shift register is transferred to the setup register, clock register, or communication register, depending on the register selection bits of the communication register.         串行数据输入端
VDD   Supply Voltage. 2.7 V to 5.25 V operation.                                          电源电压,+2.7V~5.25V,个人建议5V供电效果好一些
GND 内部电路的地电位基准点

  
  
  

2. 片内寄存器

  AD7705/7706 片内包括 8 个寄存器,这些寄存器通过器件的串行口访问。第一个是通信寄存器,它管理通道选择,决定下一个操作是读操作还是写操作,以及下一次读或写哪一个寄存器。所有与器件的通信必须从写入通信寄存器开始。上电或复位后,器件等待在通信寄存器上进行一次写操作。这一写到通信寄存器的数据决定下一次操作是读还是写,同时决定这次读操作或写操作在哪个寄存器上发生。所以,写任何其它寄存器首先要写通信寄存器,然后才能写选定的寄存器。
  在编写程序的过程中主要使用了三个寄存器分别为:通信寄存器、设置寄存器和时钟寄存器,就详细讲解这三个。

2.1 通信寄存器

  通信寄存器是一个8 位寄存器,既可以读出数据也可以把数据写进去。所有与器件的通信必须从写该寄存器开始。写上去的数据决定下一次读操作或写操作在哪个寄存器上发生。一旦在选定的寄存器上完成了下一次读操作或写操作,接口返回到通信寄存器接收一次写操作的状态。

2.1.1 通讯寄存器手册说明

  英文版手册
在这里插入图片描述
在这里插入图片描述
  中文手册

名称 功能
DRDY ‾ \overline{\text{DRDY}} DRDY 对于写操作,必须有一个“0”被写到这位,以便通信寄存器上的写操作能够准确完成。如果“1”被写到这位,后续各位将不能写入该寄存器。它会停留在该位直到有一个“0”被写入该位。一旦有“0”写到 0/DRDY位,以下的 7 位将被装载到通信寄存器。对于读操作,该位提供器件的 DRDY标志。该位的状态与DRDY输出引脚的状态相同。
RD2–RS0 寄存器选择位。这 3 个位选择下次读/写操作在 8 个片内寄存器中的哪一个上发生,见表 。当选定的寄存器完成了读/写操作后,器件返回到等待通信寄存器下一次写操作的状态。它不会保持在继续访问原寄存器的状态。在这里插入图片描述
R/W 读/写选择。这个位选择下次操作是对选定的寄存器读还是写。“0”表示下次操作是写,“1“表示下次操作是读。
STBY 等待模式。此位上写“1”,则处于等待或掉电模式。在这种模式下,器件消耗的电源电流仅为 10μA。在等待模式时,器件将保持它的校准系数和控制字信息。写“0”,器件处于正常工作模式。
CH1–CH0 通道选择。这 2 个位选择一个通道以供数据转换或访问校准系数,如表 7 所示。器件内的 3 对校准寄存器用来存储校准系数。如表 7 和 8 所示指出了哪些通道组合是具有独立的校准系数的。当 CH1 为逻辑 1 而 CH0 为逻辑 0 时,由表可见对 AD7705/7706 是AIN1(-)输入脚在内部自己短路。这可以作为评估噪声性能的一种测试方法(无外部噪声源)。在这种模式下,AIN1(-)/COMMON 输入端必须与一个器件允许的共模电压范围内的外部电压相连接。在这里插入图片描述

2.1.2 通信寄存器配置(RS2=0,RS1=0,RS0=0)

  英文手册给了这么这么一个表格为了,为了避免一些人不喜欢看英文的手册,也将中文版的手册附上编写代码的时候一定要对照这英文手册看,主要是中文手册会有些翻译错误,误导大家编写程序导致之后编写的程序错误很难找出。
步骤如下:

  1. DRDY ‾ \overline{\text{DRDY}} DRDY : 要写寄存器根据手册说明,这位给0

  2. RS2–RS0: 这三位如何填写看手册表,现在是要操作通信寄存器选择其他寄存器,根据手册所给的表格这里三位就先用 ? ? ?三问号代替,这是个8位寄存器前4位就是0???,后四位先补0000

  3. R/W : 这里下次操作是写所以补0 (为什么下一次操作是写,解释一下:前面手册说了,想要操作其他寄存器首先必须先操作通信寄存器在RS2–RS0先选择下一个操作的寄存器是什么,不操作通信寄存器,是一定进行不了下一个寄存器位操作的)

  4. STBY: vcz根据手册上来这一位给0正常工作

  5. CH1-CH0 : 一般用AIN1(+/-)作为一组通道,那么配置就是00,用AIN2(+/-)作为一组通道那么配置就是01
    后4位加上前4位,总的写法就是0???0000或者0???0001,先不急这些问号的事情,下面就会说明。

2.2 设置寄存器

   设置寄存器是一个8位寄存器,既可以读数据也可以写数据。

2.2.1 设置寄存器手册说明

英文手册
在这里插入图片描述
在这里插入图片描述
中文手册

名称 功能
MD1–MD0 在这里插入图片描述
G2–G0 G2-G0 增益选择位。这些位负责片上的 PGA 的增益设置,在这里插入图片描述在这里插入图片描述
B/U 单极性/双极性工作。“0”表示选择双极性操作,“1”表示选择单极性工作。
BUF 缓冲器控制。“0”表示片内缓冲器短路,缓冲器短路后,电源电流降低。此位处于高电平时,缓冲器与模拟输入串联,输入端允许处理高阻抗源。
FSYNC 滤波器同步。该位处于高电平时,数字滤波器的节点、滤波器控制逻辑和校准控制逻辑处于复位状态下,同时,模拟调制器也被控制在复位状态下。当处于低电平时,调制器和滤波器开始处理数据,并在 3×(1/输出更新速率)时间内(也就是滤器的稳定时间)产生一个有效字。FSYNC 不影响数字接口,也不使 DRDY输出复位(如果它是低电平)。

2.2.2 设置寄存器配置(RS2=0,RS1=0,RS0=1)

   配置一个设置寄存器步骤如下:

  1. 想要配置设置寄存器就必须先在通信寄存器中RS2—-RS0三位中进行选择,根据标题已经给出如何设置通用寄存器这里先配置通信寄存器。2进制写发为 00010000,16进制写法为 0x10
  2. 前面通过通信寄存器选择了写入设置寄存器中,那么接下来才是正式的配置设置寄存器。可以看到设置寄存器是一个8位寄存器。MD1—MD0可以根据自己想要的模式进行选择,这里是选择自校准模式,这两位位 01
  3. G2—G0为增益位,可以根据自己的需求,设置增益位,这选择增益为2,即为 001
  4. B/U 位:这里根据自己的需求选择单双极性工作,这里选择单极性配置位为 1
  5. BUF位: 这里选择无缓冲即配置位为 0
  6. FSYNC位:根据表可以看到1处于复位时,0为数据处理,即这里配置位为 0
  7. 综合上面的8位配置2进制写法为 01001100,16进制写法为 0x4c,这样一个设置寄存器才算正式配置完成。

2.3 时钟寄存器

   时钟寄存器是一个可以读/写数据的 8 位寄存器。

2.3.1 时钟寄存器手册说明

英文手册
在这里插入图片描述

在这里插入图片描述在这里插入图片描述

中文手册

名称 功能
ZERO 必须在这些位上写零,以确保 AD7705/7706 正确操作。否则,会导致器件的非指定操作。
CLKDIV 主时钟禁止位。逻辑“1”表示阻止主时钟在 MCLKOUT 引脚上输出。禁止时,MCLKOUT 输出引脚处于低电平。这种特性使用户可以灵活地使用 MCLKOUT 引脚,例如可将 MCLKOUT 做为系统内其它器件的时钟源,也可关掉 MCLKOUT,使器件具有省电性能。当在 MCLKIN 上连一个外部主时钟,AD7705/7706 继续保持内部时钟,并在CLKDIS 位有效时仍能进行正常转换。当在 MCLKIN 和 MCLKOUT 之间接一个晶体振荡器或一个陶瓷谐振器,则当 CLKDIS 位有效时,AD7705/7706 时钟将会停止,也不进行模数转换。
CLK 时钟位。CLK 位应根据 AD7705/7706 的工作频率而设置。如果转换器的主时钟频率为2.4576MHz(CLKDIV=0)或为 4.9152MHz(CLKDIV=1),CLK 应置“1” 。如果器件的主时钟频率为 1MHz(CLKDIV=0)或 2MHz (CLKDIV=1),则该位应置“0”。该位为给定的工作频率设置适当的标度电流,并且也(与 FS1 和 FS0 一起)选择器件的输出更新率。如果 CLK 没有按照主时钟频率进行正确的设置,则AD7705/7706 的工作将不能达到指标。
FS1–FS0 滤波器选择位,它与 CLK 一起决定器件的输出更新率。表 12 显示了滤波器的第一陷波和-3dB 频率。片内数字滤波器产生 sinc3(或 sinx/x3)滤波器响应。与增益选择一起,它也决定了器件的输出噪声。改变了滤波器的陷波以及选定的增益将影响分辨率。表 1 至表 4 示出了滤波器的陷波频率和增益对输出噪声和器件分辨率的影响.器件的输出数据率(或有效转换时间)等于由滤波器的第一个陷波选定的频率。例如,如果滤波器的第一个陷波选在 50Hz,则每个字的输出率为 50Hz,即每2ms 输出一个新字。当这些位改变后,必须进行一次校准。达到满标度步进输入的滤波器的稳定时间,在最坏的情况下是 4×(1/输出数据率)。例如,滤波器的第一个陷波在 50Hz,则达到满标度步进输入的滤波器的稳定时间是 80ms(最大)。如果第一个陷波在 500Hz,则稳定时间为 8ms(最大)。通过对步进输入的同步,这个稳定时间可以减少到 3×(1/输出数据率)。换句话说,如果在 FSYNC 位为高时发生步进输入,则在 FSYNC位返回低后 3×(1/输出数据率)时间内达到稳定。-3dB 频率取决于可编程的第一个陷波频率,按照以下关系式:滤波器-3dB 频率=0.262×滤波器第一个陷波频率在这里插入图片描述在这里插入图片描述

注意: 有许多中文手册中CLK这里是翻译错误的,在这里用高亮将错误标记出来。大家也可以去看看英文手册中的正确描述(用了两个高亮框将正确的圈出来了)。

2.3.2 时钟寄存器配置(RS2=0,RS1=1,RS0=0)

   配置一个时钟寄存器步骤如下:

  1. 与之前配置设置寄存器方法相同, 还是先要在通信寄存器中的RS2—RS0三位中选择,这里三位为010,即通讯寄存器16进制配置为 0x20.
  2. 配置完时通信寄存器,再来看时钟寄存器手册。ZERO位:根据手册提示写0
  3. CLKDIV位:需要根据模块上晶振进行判断,这里使用的AD7705模块的晶振为4.9152MHz,再根据手册提示这里写 1
  4. CLK位:根据上面的晶振这位写 1
  5. FS1—FS0位:前面CLK位写1,这里只有四个方式选择,这里选择500Hz,所以两位写11。(为什么选择500Hz我参考了这位大神指点 链接
  6. 注意 时钟寄存器一旦配置出错一定会出现问题,不要问作者为什么知道。在配置前懒得写代码,白嫖网上的代码时发现一直不出效果,找了许久没发现问题出现在哪。之后还是老老实实的翻了翻了英文手册才找出问题,没有认真看手册的血的教训,之前看的还是中文手册,所以建议还是少看一些中文手册多看看原版的英文手册还是有好处的。

2.4 数据寄存器(RS2=0,RS1=1,RS0=1)

   数据寄存器是一个 16 位只读寄存器,它包含了来自 AD7705/7706 最新的转换结果。如果通信寄存器将器件设置成对该寄存器写操作,则必定会实际上发生一次写操作以使器件返回到准备对通信寄存器的写操作,但是向器件写入的 16 位数字将被 AD7705/7706 忽略。

2.5 测试寄存器 (RS2=1,RS1=0,RS0=0)

   测试寄存器用于测试器件时。建议用户不要改变测试寄存器的任何位的默认值(上电或复位时自动置入全 0),否则当器件处于测试模式时,不能正确运行。

2.6 零标度校准寄存器(RS2=1,RS1=1,RS0=0)

   AD7705/7706 包含几组独立的零标度寄存器,每个零标度寄存器负责一个输入通道。它们皆为 24 位读/写寄存器,24 位数据必须被写之后才能传送到零标度校准寄存器。零标度寄存器和满标度寄存器连在一起使用,组成一个寄存器对。每个寄存器对对应一对通道,见表 7。当器件被设置成允许通过数字接口访问这些寄存器时,器件本身不再访问寄存器系数以使输出数据具有正确的尺度。结果,在访问校准寄存器(无论是读/写操作)后,从器件读得的第一个输出数据可能包含不正确的数据。此外,数据校准期间,校准寄存器不能进行写操作。这类事件可以通过以下方法避免:在校准寄存器开始工作前,将模式寄存器的 FSYNC 位置为高电平,任务结束后,又将其置为低电平。
在这里插入图片描述

2.7 满标度校准寄存器(RS2=1,RS1=0,RS0=1)

在这里插入图片描述

  
  
  

3. STM32F10x驱动程序

   AD7705采用的SPI通讯协议,这里默认大家已经会C语言,SPI通讯协议了这里不细讲,头文件写法也不讲。
   如果有同学还不清楚SPI的话这里我给出正点原子的B站视频网站:视频

3.1 SPI 代码

3.1.1 SPI与STM32引脚连接图

在这里插入图片描述

3.1.2 SPI.H代码

#ifndef __SPI_H
#define __SPI_H 
#include "sys.h"
#include "stm32f10x_spi.h"


#define CLK Pin5
#define DOUT Pin6
#define Din Pin7
#define DRDY Pin8

#define CS_ADC_LOW() GPIO_ResetBits(GPIOA,GPIO_Pin_4) 
#define CS_ADC_HIGH() GPIO_SetBits(GPIOA,GPIO_Pin_4)

void SPI1_Init(void);
u8 SPIx_ReadWriteByte(u8 TxData);
 
#endif 

3.1.3 SPI.C代码

#include "spi.h"
#include "delay.h"

/* 复用功能 SPI1_REMAP = 0 SPI1_NSS PA4 CS SPI1_SCK PA5 CLK SPI1_MISO PA6 DOUT SPI1_MOSI PA7 DIN PC4 DRDY */

SPI_InitTypeDef  SPI_InitStructure;

void SPI1_Init(void)
{ 
   
	
  GPIO_InitTypeDef GPIO_InitStructure;
	
  RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_GPIOC|RCC_APB2Periph_SPI1|RCC_APB2Periph_AFIO, ENABLE);
	
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4;// AdDrdy
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU ;//PC4配置成上拉输入
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  GPIO_Init(GPIOC, &GPIO_InitStructure);               
  
	
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4;         //SPI CS 
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;  //推挽输出
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  GPIO_Init(GPIOA, &GPIO_InitStructure);               
  
  GPIO_SetBits(GPIOC,GPIO_Pin_4);
  GPIO_SetBits(GPIOA,GPIO_Pin_4);
	
	/* Configure SPI1 pins: SCK, MISO and MOSI */
  GPIO_InitStructure.GPIO_Pin =  GPIO_Pin_5 | GPIO_Pin_6 | GPIO_Pin_7;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP ;  //复用推挽输出
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  GPIO_Init(GPIOA, &GPIO_InitStructure);
  
  SPI_Cmd(SPI1, DISABLE); //失能能SPI外设
  SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex;  //设置SPI单向或者双向的数据模式:SPI设置为双线双向全双工
  SPI_InitStructure.SPI_Mode = SPI_Mode_Master;                //设置SPI工作模式:设置为主SPI
  SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b;                //设置SPI的数据大小:SPI发送接收8位帧结构
  SPI_InitStructure.SPI_CPOL = SPI_CPOL_High;                //选择了串行时钟的稳态:时钟悬空高
  SPI_InitStructure.SPI_CPHA = SPI_CPHA_2Edge;        //数据捕获于第二个时钟
  SPI_InitStructure.SPI_NSS = SPI_NSS_Soft;                //NSS信号由硬件(NSS管脚)还是软件(使用SSI位)管理:内部NSS信号有SSI位控制
  SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_256;                //定义波特率预分频的值:波特率预分频值为256
  SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB;        //指定数据传输从MSB位还是LSB位开始:数据传输从MSB位开始
  SPI_InitStructure.SPI_CRCPolynomial = 7;        //CRC值计算的多项式
  SPI_Init(SPI1, &SPI_InitStructure);  //根据SPI_InitStruct中指定的参数初始化外设SPIx寄存器
  
  SPI_Cmd(SPI1, ENABLE); //使能SPI外设
       
  CS_ADC_LOW();       
  SPIx_ReadWriteByte(0xff);//启动传输 
  CS_ADC_HIGH();
}


//SPIx 读写一个字节
//TxData:要写入的字节
//返回值:读取到的字节
u8 SPIx_ReadWriteByte(u8 TxData)
{ 
                  
        u8 retry=0;                                 

        while (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_TXE) == RESET) //检查指定的SPI标志位设置与否:发送缓存空标志位
        { 
   
                retry++;
                if(retry>200)return 0;
        }                          

        SPI_I2S_SendData(SPI1, TxData); //通过外设SPIx发送一个数据
        retry=0;

        while (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_RXNE) == RESET); //检查指定的SPI标志位设置与否:接受缓存非空标志位
        { 
   
                retry++;
                if(retry>200)return 0;
        }                                                              

        return SPI_I2S_ReceiveData(SPI1); //返回通过SPIx最近接收的数据 
}

3.2 AD7705程序

3.2.1 AD7705.H

#ifndef __AD7705_H
#define __AD7705_H 
#include "spi.h"

void AD7705_WriteByte(u8 Dst_Addr);
void Init_AD7705(u8 chnanel);
u16 GetData7705_CH1(void);
u16 GetData7705_CH2(void);
void ADC_7705(void);
void ADC_7705_double(void);

#endif 

3.2.1 AD7705.C

#include "ad7705.h"
#include "spi.h"
#include "oled.h"
#include "usart.h"
#include "math.h"
#include "delay.h"
#include "beep.h"

//写数据
void AD7705_WriteByte(u8 Dst_Addr)   
{ 
      
        CS_ADC_LOW();//使能器件 
        delay_us(20);
        SPIx_ReadWriteByte(Dst_Addr);
        delay_us(100);
        CS_ADC_HIGH();//使能器件 
}



/********AD7705初始化函数***********/

void Init_AD7705(u8 chnanel)
{ 
   
    u8 i;
    for(i=0;i<150;i++)/* 多于连续32个 DIN=1 使串口复位 */
    { 
   
        AD7705_WriteByte(0xff);//持续DIN高电平写操作,恢复AD7705接口
    }  
        delay_ms(1);
    switch(chnanel)
    { 
   
      case 1:
             AD7705_WriteByte(0x20); /* 写时钟寄存器选中ch1*/
             AD7705_WriteByte(0x0f); /* 4.9152MHz时钟,250Hz数据更新速率 */
             AD7705_WriteByte(0x10); /*选择设置寄存器,使用chnanel 1*/
             AD7705_WriteByte(0x4c); //写设置寄存器 ,设置成双极性、无缓冲、增益为2、滤波器工作、自校准
      break;
			/*有更改,时钟寄存器设为0x0a,4.9152MHz时钟,500Hz数据更新速率,*/
      case 2:
             AD7705_WriteByte(0x21); /* 写时钟寄存器选中ch2 */
             AD7705_WriteByte(0x0f); /* 4.9152MHz时钟,500Hz数据更新速率 */
             AD7705_WriteByte(0x11); /*选择设置寄存器,使用chnane 2*/
             AD7705_WriteByte(0x4c); //写设置寄存器,设置成双极性、无缓冲、增益为2、滤波器工作、自校准
       break;
       default:       
                break;
        }
}

/* 读AD7705转换数据 输入通道channel */
u16 GetData7705_CH1(void)
{ 
   
    u16 temp1 = 0;
    u16 DataL = 0;
    u16 DataH = 0;
    Init_AD7705(1);                        //初始化通道1
    delay_ms(1);
    AD7705_WriteByte(0x39);   //选中CH1数据寄存器读 
    while(GPIO_ReadInputDataBit(GPIOC, GPIO_Pin_4==1)){ 
   }//待数据准备好AdDrdy=0 
    CS_ADC_LOW(); //使能器件 
    delay_us(20);
    DataH = SPIx_ReadWriteByte(0xff);
    DataL = SPIx_ReadWriteByte(0xff);
    delay_us(100);
    CS_ADC_HIGH();   //取消片选 
    DataH = DataH << 8;
    temp1  =  DataH | DataL;

    return temp1;
}


/* 读AD7705转换数据 输入通道channel */
u16 GetData7705_CH2(void)
{ 
   
    u16 temp2 = 0;
    u16 DataL = 0;
    u16 DataH = 0;
    Init_AD7705(2);                //初始化通道2
    delay_ms(1);
    AD7705_WriteByte(0x38);   //选中CH2数据寄存器读 
    while(GPIO_ReadInputDataBit(GPIOC, GPIO_Pin_4==1));  //待数据准备好AdDrdy=0 
    CS_ADC_LOW(); //使能器件 
    delay_us(20);
    DataH = SPIx_ReadWriteByte(0xff);
    DataL = SPIx_ReadWriteByte(0xff);
  	delay_us(100);
    CS_ADC_HIGH();   //取消片选 
    DataH = DataH << 8;
    temp2  =  DataH | DataL;

    return temp2;
}  


//数据处理

extern u8 num1[];
extern u32 l_ncm1;
extern u8 num2[];
extern u32 l_ncm2;
void ADC_7705(void)
{ 
           
    
        u16 RCH1_16bit,RCH2_16bit;              
        RCH1_16bit = GetData7705_CH1();								
        l_ncm1  = (u32)(RCH1_16bit*(25000.0/65535)); //算出通道1电压

        RCH2_16bit = GetData7705_CH2();
        l_ncm2  = (u32)(RCH2_16bit*(25000.0/65535)); //算出通道2电压

         num1[0]    = l_ncm1/10000+'0';
         num1[2]    = (l_ncm1%10000)/1000+'0';
         num1[3]    = (l_ncm1%1000)/100+'0';
         num1[4]    = (l_ncm1%100)/10+'0';
         num1[5]    = l_ncm1%10+'0';

        num2[0]    = l_ncm2/10000+'0';
        num2[2]    = (l_ncm2%10000)/1000+'0';
        num2[3]    = (l_ncm2%1000)/100+'0';
        num2[4]    = (l_ncm2%100)/10+'0';
        num2[5]    = l_ncm2%10+'0';
	
	     if(l_ncm2>8500|l_ncm2<8200)
			 { 
   
			   BEEP=!BEEP;
				 delay_ms(10);
			   l_ncm2=0;
					 
			 }
			 else
       { 
   
			   BEEP=0;
			 }
       
}
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

发布者:全栈程序员-用户IM,转载请注明出处:https://javaforall.cn/125114.html原文链接:https://javaforall.cn

【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛

【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...

(2)


相关推荐

  • R语言画图——添加数学表达式和R2[通俗易懂]

    R语言画图——添加数学表达式和R2代码如下:filepath<-file.choose()df1<-read.csv(filepath,header=T)df1library(ggplot2)QTs<-ggplot(data=df1,aes(x=Ts,y=Q10,shape=factor))+geom_point(size=3)+scale_shape_manual(values=c(1,17))+#白天

  • layuiadmin配置mysql_layuiAdmin 后台管理模板

    layuiadmin配置mysql_layuiAdmin 后台管理模板完全由layui自有的前端架构实现而成的一套通用型后台管理模板系统iframe版使用简单基于iframe标签页实现,简单实用传统开发模式,撸起袖子直接开干交互体验相比“单页版”略有点欠缺始终基于全新的layui版本面向全屏幕尺寸的响应式适配能力灵活的主题色配置专属的开发者文档,助你快速掌握版本的持续更新,集大众之所需layui社区VIP标识专属的会员专区,与同道中人隔空交流不限制…

    2022年10月29日
  • js操作string它substr方法

    js操作string它substr方法

  • lock free(无锁并发)是什么

    lock free(无锁并发)是什么一、非阻塞同步(Non-blockingSynchronization)1.无锁编程/lock-free/非阻塞同步无锁编程,即不使用锁的情况下实现多线程之间的变量同步,也就是在没有线程被阻塞的情况下实现变量的同步,所以也叫非阻塞同步(Non-blockingSynchronization)。实现非阻塞同步的方案称为“无锁编程算法”(Non-blockingalgorithm)。lock-free是目前最常见的无锁编程的实现级别(一共三种级别):wait-free l.

  • 【Unity小游戏】整整一个周末写一款《皇室战争 玩法》 的 即时战斗类 游戏Demo。两万多字游戏制作过程+解析

    【Unity小游戏】整整一个周末写一款《皇室战争 玩法》 的 即时战斗类 游戏Demo。两万多字游戏制作过程+解析Unity游戏制作,本篇文章介绍了复刻皇室战争玩法的一个自制小游戏,共有该游戏的两万字教程加制作过程,欢迎品尝!世界上没有绝对的公平,如果我们起点就比别人第一步,那就更需要比别人努力了。

  • 【⚠️windows删除文件夹抽风了⚠️】“错误0x80070091:目录不是空的”问题处理

    有时候我们想要删除一些无用的文件,但是删除的时候缺发现无法删除文件提示“错误0x80070091:目录不是空的”的问题,下面小编就详细的为大家介绍无法删除空文件夹提示“错误0x80070091:目录不是空的”通用解决方法。具体解决方法如下:1、首先呢,我们随便复制一个文件。(比如我复制自己桌面这个图片)2、“BT”这个文件夹根目录有两个文件夹。3、打开第一个文件夹,一直打开到最后一个文件夹,粘贴之前复制的文件。4、打开第二个文件…

发表回复

您的电子邮箱地址不会被公开。

关注全栈程序员社区公众号