9. EBF-AD5689

9.1. 模块简介

EBF-AD5689 模块是野火电子推出的一款具有两路独立输出的 16 位 nanoDAC+ 数模转换模块,本模块使用亚德诺半导体 AD5689 芯片作为转换芯片, 具有低功耗高驱动能力的特性,具有最大正负 2LSB、偏置误差不超过正负 1.5mV、增益误差不超过 0.1%FSR 的特性,并可使用带回读或菊花链的最高 50MHz SPI, 能实现使用一个 SPI 外设一次对多个 DAC 模块进行数据读写。

AD5689模块

9.2. 参数特性

EBF-AD5689模块参数特性

特性

说明

电压

5V

电流

70mA

可选增益

1 或 2

工作温度

-40℃-85℃

结构尺寸

644mmx448mm×124mm(包含插件原件引脚高度)

输出通道

2

通信方式

与 SPI、QSPI 和 MICROWIRE 接口标准以及大多数 DSP 兼容

应用领域

光收发器、功率放大器、工业自动化、数据采集系统

9.3. 模块功能选择

EBF-AD5689模块功能选择

功能选择跳线帽

说明

J4

增益选择。接 GND 时 DAC 的输出 0V-10V。接 5V 时 DAC 输出 (-)10V-10V。

J5

上电复位选择。接 GND 时上电后输出零电平,接 5V 时上电后输出中间电平。

J6

A_OUT 输出基准选择

J7

B_OUT 输出基准选择

当增益选择 (J4) 接 GND 时,输出基准选择 (J6/J7) 应接 GND; 当增益选择接 5V 时,输出基准选择应 2V5。

9.4. 模块接口说明

EBF-AD5689模块接口说明

特性

说明

GND

电源地

RESET

异步复位输入

LDAC

异步/同步模式选择

SYNC

输入数据的帧同步信号

SCLK

串行时钟输入

SDO

串行数据输出

SDIN

串行数据输入

5V

电源 5V

9.5. 硬件连接

配套开发板硬件连接方式如下,

EBF-AD5689模块硬件连接

模块引脚

GND

SYNC

SCLK

SDO

SDIN

5V

F103MINI

GND

PA4

PA5

A6

A7

5V

F103 指南者

GND

PA4

PA5

A6

A7

5V

F103 霸道

GND

PA4

PA5

A6

A7

5V

F407 霸天虎

GND

PA3

PB3

PB4

PB5

5V

F407 骄阳

GND

PI0

PI1

PI2

PI3

5V

F429 挑战者

GND

PF6

PF7

PF8

PF9

5V

F767 挑战者

GND

PF6

PF7

PF8

PF9

5V

H743 挑战者

GND

PF6

PF7

PF8

PF9

5V

H743_PRO

GND

PF6

PF7

PF8

PF9

5V

H743 繁星

GND

PI0

PI1

PI2

PI3

5V

H750_PRO

GND

PF6

PF7

PF8

PF9

5V

9.6. 单通道输出正弦波

9.6.1. 实验现象

这里以 STM32F103霸道 开发板为例,根据上面的硬件连接信息,将模块与开发板进行连接,再用USB线连接开发板与电脑,上电后打开野火多功能调试助手, 选择与开发板连接的端口号打开后将 单通道输出正弦波 例程编译下载至开发板。

上位机会打印如下信息,

adc_1

用示波器测量 A_OUT 口会出现如下波形,

示波器正弦波

9.6.2. 例程介绍

本例程采用的硬件SPI,硬件SPI在《SPI基础知识》一文已经介绍,不再赘述,这里主要分析代码框架。

在编写AD5689模块驱动时,也要考虑更改硬件环境的情况。我们把AD5689模块引脚相关的宏定义到”bsp_ad5689.h”文件中, 在更改或移植的时候只用改宏定义就可以。

这里采用的SPI1,输入数据的帧同步信号引脚为A4,时钟引脚为A5,SDO引脚为A6,SDIN引脚为A7,具体定义如下,

bsp_ad5689.h
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
 // ... ...

 #define AD5689_SPIx                SPI1
 #define AD5689_SPIx_CLK_ENABLE()   __HAL_RCC_SPI1_CLK_ENABLE()
 #define AD5689_GPIO_CLK_ENABLE()   __HAL_RCC_GPIOA_CLK_ENABLE()
 #define AD5689_SYNC_Pin            GPIO_PIN_4   //SYNC
 #define AD5689_SYNC_GPIO_Port      GPIOA
 #define AD5689_SCK_Pin             GPIO_PIN_5   //SCLK
 #define AD5689_SCK_GPIO_Port       GPIOA
 #define AD5689_MISO_Pin            GPIO_PIN_6   //SDO
 #define AD5689_MISO_GPIO_Port      GPIOA
 #define AD5689_MOSI_Pin            GPIO_PIN_7   //SDIN
 #define AD5689_MOSI_GPIO_Port      GPIOA

 // ... ...

AD5689_Init函数为ad5689模块的初始化函数,在这里调用了 AD5689_GPIO_Config 函数对硬件进行初始化,复位模块之后屏失能同步功能,

AD5689_Init
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
 void AD5689_Init(void)
 {
     /* AD5689引脚和SPI初始化 */
     AD5689_GPIO_Config();

     /* 模块复位 */
     AD5689_RESET_L;
     HAL_Delay(5);
     AD5689_RESET_H;
     HAL_Delay(5);
     AD5689_Reset();

     /* LDAC屏蔽寄存器设置,失能LDAC,不采用同步功能 */
     AD5689_LDAC_MASK(LDAC_Disable,LDAC_Disable);
 }

AD5689_GPIO_Config函数主要是对引脚的初始化及SPI的配置,需要注意的是单片机的 MISO(主入从出)对应AD5689芯片是 SDO(输出), MOSI(主出从入)对应AD5689芯片的SDIN(输入)。

AD5689_GPIO_Config
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
 void AD5689_GPIO_Config(void)
 {
     GPIO_InitTypeDef GPIO_InitStruct;
     /* 使能SPI外设以及SPI引脚时钟 */
     AD5689_SPIx_CLK_ENABLE();
     AD5689_GPIO_CLK_ENABLE();

     /* SCK */
     GPIO_InitStruct.Pin = AD5689_SCK_Pin;
     GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
     GPIO_InitStruct.Pull = GPIO_NOPULL;
     GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
     HAL_GPIO_Init(AD5689_SCK_GPIO_Port, &GPIO_InitStruct);

     /* MISO <--> SDO, MOSI <--> SDIN*/
     GPIO_InitStruct.Pin = AD5689_MISO_Pin|AD5689_MOSI_Pin;
     GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
     GPIO_InitStruct.Pull = GPIO_NOPULL;
     GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
     HAL_GPIO_Init(AD5689_MISO_GPIO_Port, &GPIO_InitStruct);

     /* SYNC */
     GPIO_InitStruct.Pin = AD5689_SYNC_Pin;
     GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
     GPIO_InitStruct.Pull = GPIO_NOPULL;
     GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
     HAL_GPIO_Init(AD5689_SYNC_GPIO_Port, &GPIO_InitStruct);

     /* SPI外设配置 */
     hspi_AD5689.Instance = AD5689_SPIx;
     hspi_AD5689.Init.Mode = SPI_MODE_MASTER;             //主模式
     hspi_AD5689.Init.Direction = SPI_DIRECTION_2LINES;   //全双工
     hspi_AD5689.Init.DataSize = SPI_DATASIZE_8BIT;       //数据位为8位
     hspi_AD5689.Init.CLKPolarity = SPI_POLARITY_LOW;    //CPOL=0,LOW
     hspi_AD5689.Init.CLKPhase = SPI_PHASE_2EDGE;         //CPHA为数据线的第二个变化沿
     hspi_AD5689.Init.NSS = SPI_NSS_SOFT;                 //软件控制NSS
     hspi_AD5689.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_32; //32分频
     hspi_AD5689.Init.FirstBit = SPI_FIRSTBIT_MSB;        //最高位先发送
     hspi_AD5689.Init.TIMode = SPI_TIMODE_DISABLE;        //TIMODE模式关闭
     hspi_AD5689.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLE;  //CRC关闭
     hspi_AD5689.Init.CRCPolynomial = 7;                  //默认值,无效
     HAL_SPI_Init(&hspi_AD5689);                          //初始化
 }

再看一下main函数,同样先初始化系统时钟,初始化HAL库及串口配置,初始化按键和AD5689,在循环中不断输出变化的波形。

main
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
 int main(void)
 {
     /* 系统时钟初始化成72MHz */
     SystemClock_Config();

     /* HAL 库初始化 */
     HAL_Init();

     /* 配置串口1为:115200 8-N-1 */
     DEBUG_USART_Config();
     printf("欢迎使用野火 F103 AD5689单通道输出正弦波 例程\r\n");

     /* 按键初始化 */
     Key_GPIO_Config();

     /* AD5689初始化 */
     AD5689_Init();

     while (1)
     {
         /* 输出波形 */
         AD5689_Sine();
     }
 }

最后是 AD5689_Sine 函数中使用AD5689_WriteUpdate_DACREG函数改变AD5689输出的电压,Sine16bit 波形数据是有工程中的 正弦波表制作脚本 生成的。

AD5689_Sine
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
 /* 波形数据 ---------------------------------------------------------*/
 const uint16_t Sine16bit[128] = {
     32768, 34388, 36005, 37614, 39210, 40791, 42353, 43891,
     45401, 46881, 48326, 49733, 51099, 52420, 53693, 54914,
     56081, 57192, 58242, 59230, 60154, 61010, 61797, 62513,
     63157, 63726, 64219, 64635, 64974, 65233, 65413, 65513,
     65533, 65473, 65333, 65113, 64814, 64437, 63982, 63451,
     62844, 62164, 61412, 60590, 59700, 58744, 57724, 56644,
     55505, 54310, 53062, 51765, 50422, 49035, 47608, 46145,
     44650, 43125, 41575, 40003, 38414, 36811, 35198, 33578,
     31958, 30338, 28725, 27122, 25533, 23961, 22411, 20886,
     19391, 17928, 16501, 15114, 13771, 12474, 11226, 10031,
     8892,  7812,  6792,  5836,  4946,  4124,  3372,  2692,
     2085,   1554,  1099,   722,   423,   203,    63,     3,
     23,   123,   303,   562,   901,  1317,  1810,  2379,
     3023,  3739,  4526,  5382,  6306,  7294,  8344,  9455,
     10622, 11843, 13116, 14437, 15803, 17210, 18655, 20135,
     21645, 23183, 24745, 26326, 27922, 29531, 31148, 32768
 };
 uint32_t Idx = 0;

 void AD5689_Sine(void)
 {
     uint16_t val;

     val =  Sine16bit[Idx];
     Idx++;

     /* 写入和更新DAC通道A */
     AD5689_WriteUpdate_DACREG(DAC_A,val);
     if(Idx==128)
         Idx = 0;
     HAL_Delay(5);
 }