ADC chip - the most detailed explanation of AD7705 (STM32)

foreword

   读者必读: I used the external ADC module - AD7705 during my professional practice. I have referred to a lot of materials in the process of using them. Some materials are very useful, and some materials have some minor problems.
  切记: Be sure to read the English chip manual DataSheet, and refer to the AD7705 Chinese manual on the Internet. English manual

References: 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. Introduction to AD7705

  The AD7705/7706 are 2/3-channel analog front-ends applied to low-frequency measurements. The device accepts a low-level input signal directly from the sensor and produces a serial digital output. 16-bit no missing code performance is achieved using sigma-delta conversion technique. The selected input signal is fed to a dedicated front-end based on an analog modulator with programmable gain. An on-chip digital filter processes the output signal of the modulator. The first notch of the digital filter is programmed through on-chip control registers that allow adjustment of the filter's cutoff point and output update rate.
   AD7705/7706 only need 2.7 ~ 3.3V or 4.75 ~ 5.25V single power supply. The AD7705 is a two-channel fully differential analog input, while the AD7706 is a three-channel pseudo-differential analog input, both with a differential reference input. Both devices can process input signals ranging from 0 to +20mV to 0 to +2.5V when the supply voltage is 5V and the reference voltage is 2.5V. It can also handle bipolar input signals of ± 20mV ~ ± 2.5V. For AD7705, the AIN (-) input terminal is used as the reference point, while AD7706 is the COMMON input terminal. When the power supply voltage is 3V and the reference voltage is 1.225V, it can handle unipolar input signals from 0~+10mV to 0~+1.225V, and its bipolar input signal range is ±10mV to ±1.225V. Therefore, AD7705/7706 can realize the conditioning and conversion of all signals of 2/3 channel system.
  The CMOS structure ensures that the device has very low power consumption, and the power-down mode reduces the power consumption in standby to 20μW (typ.). The AD7705/7706 are available in 16-lead plastic dual in-line (DIP) and 16-lead wide body (0.3 inch) SOIC packages and 16-lead TSSOP packages. Figure 1 is the AD7705 module
AD7705 module
                                    Figure 1 AD7705 module

1.1 Characteristic parameters

The English manual is a brief summary   of the description
insert image description here

 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 Functional Block Diagram

insert image description here

1.3 Pinout and its function

  (1) Pinout diagram
insert image description here

  (2) Pin function table

Pin name Function
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.                          Serial clock, Schmitt logic input. Apply an external serial clock to this input port to access the serial data of the AD7705/7706. Control clock when transmitting data with MCU
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.                  Provide the master clock signal for the converter. Available as crystal/resonator or external clock. A crystal/resonator can be connected between the MCLKIN and MCLKOUT pins. Alternatively, MCLKIN can be driven with a CMOS-compatible clock, leaving MCLKOUT unconnected. The clock frequency ranges from 500kHz to 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 inevitably burn power driving capacitive loads on Pin MCLK OUT.                                               When the main clock is a crystal/resonator, the crystal/resonator is connected between MCLKIN and MCLKOUT. If an external clock is connected to the MCLKIN pin, MCLKOUT will provide an inverted clock signal. This clock can be used to provide a clock source for external circuits and can drive a CMOS load. If user does not need, MCLKOUT can be turned off by CLKDIS bit in clock register. This way, the device does not dissipate unnecessary power by driving a capacitive load on the MCLKOUT pin
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.                                         Chip Select, an active low logic input, selects the AD7705/AD7706. Tie this pin low to enable the AD7705/7706 to operate in three-wire interface mode (interfacing the device with SCLK, DIN, and DOUT). In systems with multiple devices on the serial bus, the devices can be selected by CS', or can be used as a frame synchronization signal when communicating with the AD7705/7706
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.                                                    Reset input. Active-Low Input to Reset the Device's Control Logic, Interface Logic, Calibration Coefficients, Digital Filters, and Analog Modulators to the Power-Up State
AIN2(+) Positive Input of the Differential Analog Input Pair AIN2(+)/AIN2(−) for AD7705. Channel 1 for AD7706.                  Positive Input of Differential Analog Input Channel 1.
AIN1(+) Positive Input of the Differential Analog Input Pair AIN1(+)/AIN1(−) for AD7705. Channel 2 for AD7706.                  Positive input of differential analog input channel 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’s differential analog input pair AIN1(+)                                            / Negative Input of AIN1(-). Common input to the AD7706, referenced by Channel 1, Channel 2, and Channel 3.
REFIN(+) Reference Input. Positive input of the differential reference input to the AD7705/AD7706. The reference input is differential with the provision that REF IN(+) must be greater than REF IN(−).REF IN(+) can lie anywhere between VDD and GND.             Reference input terminal, the reference input is differential, and it is stipulated that REFIN(+) must be greater than REFIN(-). REFIN(+) can take any value between VDD and 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(−). Reference input                                    , REFIN(-) can take any value between VDD and GND, and satisfy REFIN(+) is greater than REFIN(-)
AIN2(−) Negative Input of the Differential Analog Input Pair AIN2(+)/AIN2(−) for AD7705. Channel 3 for AD7706. Negative Input of the Differential Analog Input Pair                AIN2(+)/AIN2(−) for AD7705. AD7706 corresponds to the third channel.
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 通讯寄存器手册说明

  英文版手册
insert image description here
insert image description here
  中文手册

名称 功能
DRDY ‾ \overline{\text{DRDY}} DRDY 对于写操作,必须有一个“0”被写到这位,以便通信寄存器上的写操作能够准确完成。如果“1”被写到这位,后续各位将不能写入该寄存器。它会停留在该位直到有一个“0”被写入该位。一旦有“0”写到 0/DRDY位,以下的 7 位将被装载到通信寄存器。对于读操作,该位提供器件的 DRDY标志。该位的状态与DRDY输出引脚的状态相同。
RD2–RS0 寄存器选择位。这 3 个位选择下次读/写操作在 8 个片内寄存器中的哪一个上发生,见表 。当选定的寄存器完成了读/写操作后,器件返回到等待通信寄存器下一次写操作的状态。它不会保持在继续访问原寄存器的状态。insert image description here
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 输入端必须与一个器件允许的共模电压范围内的外部电压相连接。insert image description here

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 设置寄存器手册说明

英文手册
insert image description here
insert image description here
中文手册

名称 功能
MD1–MD0 insert image description here
G2–G0 G2-G0 增益选择位。这些位负责片上的 PGA 的增益设置,insert image description hereinsert image description here
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 时钟寄存器手册说明

英文手册
insert image description here

insert image description hereinsert image description here

中文手册

名称 功能
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×滤波器第一个陷波频率insert image description hereinsert image description here

注意: 有许多中文手册中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)

   The AD7705/7706 contain several independent sets of zero-scale registers, one for each input channel. They are both 24-bit read/write registers, and 24-bit data must be written before being transferred to the zero-scale calibration register. Zero-scale registers and full-scale registers are used together to form a register pair. Each register pair corresponds to a pair of channels, see Table 7. When the device is set up to allow access to these registers through the digital interface, the device itself no longer accesses the register coefficients to make the output data have the correct scale. As a result, the first output data read from the slave after accessing the calibration registers (whether read/write) may contain incorrect data. In addition, during data calibration, the calibration register cannot be written. This kind of event can be avoided by the following methods: Before the calibration register starts working, set the FSYNC position of the mode register to a high level, and set it to a low level after the task ends.
insert image description here

2.7 Full-scale calibration register (RS2=1, RS1=0, RS0=1)

insert image description here

  
  
  

3. STM32F10x driver

   The SPI communication protocol adopted by the AD7705, here everyone already knows the C language by default, and the SPI communication protocol is not discussed in detail here, nor is the writing method of the header file.
   If some students are not clear about SPI, here I will give the video website of station B of punctual atom: video

3.1 SPI code

3.1.1 SPI and STM32 pin connection diagram

insert image description here

3.1.2 SPI.H code

#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 code

#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 program

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;
			 }
       
}

Guess you like

Origin blog.csdn.net/cugautozp/article/details/108032819