其他分享
首页 > 其他分享> > AD5592R STM32驱动代码

AD5592R STM32驱动代码

作者:互联网

一、前言

  最近项目上需要使用8路DAC,本来想用STM32自带的DAC,但是STM32自带的DAC好像只有2路,不满足要求,市面上很多的DAC芯片虽然有8路,但是精度只有8位,而我需要一个精度更高的,在选型的时候选到了ADS9226这款芯片,它有8个DAC通道,精度是12位的,当时也只关心这2个指标。

  等到使用的时候才发现这个芯片的功能比想象中的更强大,它的每个通道都可以配置为:ADC、DAC、GPIO输入、GPIO输出、85kΩ下拉、开漏、三态,可以配置的功能非常多,然鹅让我没想到的是网上竟然找不到现成的程序可以参考,于是我自己写了一个STM32的测试程序。

  手册去ADI的官网可以找到,中文的和英文的都有,但是要注意的是中文手册有点问题,目前发现有些寄存器的地址号写的不对,但是英文手册写的没问题。

  我因为只使用DAC功能,因此我只测试了DAC功能,ad5592r.c里面有一个DAC的例程,经过测试是没问题的。下面我附上ad5592r.c和ad5592r.h,这两个文件配合正点原子的库函数版本使用,拿SPI的例程改改就能用。但是SPI初始化函数需要改改,一个是SPI的数据为16位的,一个是第一个边沿采样。代码如下,需要注意的地方我给标红了。

 1 void SPI2_Init(void)
 2 {
 3      GPIO_InitTypeDef GPIO_InitStructure;
 4     SPI_InitTypeDef  SPI_InitStructure;
 5 
 6     RCC_APB2PeriphClockCmd(    RCC_APB2Periph_GPIOB, ENABLE );//PORTB时钟使能 
 7     RCC_APB1PeriphClockCmd(    RCC_APB1Periph_SPI2,  ENABLE );//SPI2时钟使能     
 8  
 9     GPIO_InitStructure.GPIO_Pin = GPIO_Pin_13 | GPIO_Pin_15;
10     GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;  //PB13/14/15复用推挽输出 
11     GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
12     GPIO_Init(GPIOB, &GPIO_InitStructure);//初始化GPIOB
13 
14     GPIO_InitStructure.GPIO_Pin = GPIO_Pin_14;
15     GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;  //PB13/14/15复用推挽输出 
16     GPIO_Init(GPIOB, &GPIO_InitStructure);//初始化GPIOB
17 
18     
19      GPIO_SetBits(GPIOB,GPIO_Pin_13|GPIO_Pin_14|GPIO_Pin_15);  //PB13/14/15上拉
20 
21     SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex;  //设置SPI单向或者双向的数据模式:SPI设置为双线双向全双工
22     SPI_InitStructure.SPI_Mode = SPI_Mode_Master;        //设置SPI工作模式:设置为主SPI
23     SPI_InitStructure.SPI_DataSize = SPI_DataSize_16b;        //设置SPI的数据大小:SPI发送接收16位帧结构
24     SPI_InitStructure.SPI_CPOL = SPI_CPOL_High;        //串行同步时钟的空闲状态为高电平
25     SPI_InitStructure.SPI_CPHA = SPI_CPHA_1Edge;    //串行同步时钟的第二个跳变沿(上升或下降)数据被采样
26     SPI_InitStructure.SPI_NSS = SPI_NSS_Soft;        //NSS信号由硬件(NSS管脚)还是软件(使用SSI位)管理:内部NSS信号有SSI位控制
27     SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_32;        //定义波特率预分频的值:波特率预分频值为256
28     SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB;    //指定数据传输从MSB位还是LSB位开始:数据传输从MSB位开始
29     SPI_InitStructure.SPI_CRCPolynomial = 7;    //CRC值计算的多项式
30     SPI_Init(SPI2, &SPI_InitStructure);  //根据SPI_InitStruct中指定的参数初始化外设SPIx寄存器
31     
32     SPI_Cmd(SPI2, ENABLE); //使能SPI外设
33     
34     //SPI2_ReadWriteByte(0xff);//启动传输         
35 }  

ad5592r.c

  1 #include "ad5592r.h" 
  2 #include "spi.h"
  3 #include "delay.h"
  4 #include "usart.h"
  5 
  6 /**
  7  * /brief 初始化AD5592R
  8  */
  9 void AD5592R_Init(void)
 10 {    
 11     GPIO_InitTypeDef GPIO_InitStructure;
 12     RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE );//PORTB时钟使能 
 13 
 14     GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12;  // PB12 推挽 
 15      GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;  //推挽输出
 16     GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
 17      GPIO_SetBits(GPIOB,GPIO_Pin_12);
 18      GPIO_Init(GPIOB, &GPIO_InitStructure);
 19     
 20     //PB11与AD5592R RESET引脚连接
 21     GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11;  // PB11 推挽 
 22     GPIO_SetBits(GPIOB, GPIO_Pin_11);
 23        GPIO_Init(GPIOB, &GPIO_InitStructure);
 24 
 25     SPI2_Init();                                       //初始化SPI
 26     SPI2_SetSpeed(SPI_BaudRatePrescaler_32);       //设置为256分频
 27     
 28     AD5592R_HW_Reset();
 29 }
 30 
 31 /**
 32  * \brief AD5592R硬件复位
 33  */
 34 void AD5592R_HW_Reset(void)
 35 {
 36     GPIO_ResetBits(GPIOB, GPIO_Pin_11);
 37     delay_us(250);      //手册上说复位功能最多需要250us
 38     GPIO_SetBits(GPIOB, GPIO_Pin_11);
 39 }
 40 
 41 /**
 42  * \brief 读取AD5592R的寄存器
 43  *
 44  * \param[in] addr:寄存器地址
 45  *
 46  * \note D1和D0用来选择LDAC模式,每当调用一次该函数时,都会将模式设定为DAC即时更
 47  *       新模式,需要修改的话,可以用一个变量保存。
 48  */
 49 u16 AD5592R_Read_Register(ad5592r_addr_t addr)   
 50 {  
 51     u16 data = 0;   
 52     
 53     data = (RDBK_LDAC_MODE << 11) | RDBK_LDAC_MODE_EN | (addr << 2);  //选择寄存器,使能回读并设定回读寄存器地址
 54     
 55     AD5592R_CS=0;                               //使能器件   
 56     SPI2_ReadWriteByte(data);                   //发送读取状态寄存器命令  
 57     AD5592R_CS=1;
 58     
 59     delay_us(1);   //片选信号拉低到拉高之间的时间间隔最小为20nS
 60     
 61     AD5592R_CS=0;
 62     data = SPI2_ReadWriteByte(0X0000);            //读取一个字节  
 63     //delay_us(1);    //如果上一行发送的数据是0xFFFF,那么片选信号很快就会拉高,但是发其他数据却不会,原因不明,因此这里加一个延时。
 64     AD5592R_CS=1;                               //取消片选   
 65     
 66     return data;   
 67 }
 68 
 69 
 70 /**
 71  * \brief 读取AD5592R的寄存器
 72  *
 73  * \note 这个函数主要是用来测试,读出来15个寄存器的值。芯片复位后读取,其中data[6]为0x00FF,data[7]为0x005C,其他寄存器的值都为0,如果读出的结果都为0xFFFF,那可能通信出现问题了
 74  */
 75 void AD5592R_Read_All_Register(u16 data[16])
 76 {
 77     u8 i;
 78     
 79     for (i = 0; i < 16; i++) {
 80         data[i] = AD5592R_Read_Register((ad5592r_addr_t)i);
 81     }
 82 }
 83 
 84 /**
 85  * \brief 通用控制寄存器配置
 86  *
 87  * \param[in] flag:可以加入如下标志:
 88  *                  #GP_COTL_ADC_BUF_PRECHARGE: ADC缓冲器用于对ADC预充电,不设置则禁用(默认)
 89  *                  #GP_COTL_ADC_BUF_EN:        使能ADC缓冲器,不设置则禁能(默认)
 90  *                  #GP_COTL_LOCK:              不能改变I/Ox引脚配置寄存器的内容,不设置则可以改变(默认)
 91  *                  #GP_COTL_ALL_DAC:           (一个数据)写入所有DAC,不设置则由DAC地址决定写入哪个DAC(默认)
 92  *                  #GP_COTL_ADC_RANGE_REFx2:   ADC增益为0 V至2 × VREF,不设置则为1倍(默认)
 93  *                  #GP_COTL_DAC_RANGE_REFx2:   DAC增益为0 V至2 × VREF,不设置则为1倍(默认)
 94  */
 95 void AD5592R_GP_Contol_Set(u16 flag)
 96 {
 97     u16 data = 0;
 98     
 99     data = (GP_CNTL_REG << 11) | flag;
100     AD5592R_CS = 0;
101     SPI2_ReadWriteByte(data);
102     AD5592R_CS = 1;
103 }
104 
105 /**
106  * \brief 将指定的引脚配置为指定的功能
107  *
108  * \param[in] func:设定的功能#ADC_PIN_CONF:配置为ADC引脚
109  *                            #DAC_PIN_CONF:配置为DAC引脚
110  *                            #PD_CONF:下拉配置,设定为85kΩ下拉(默认就是这个)
111  *                            #GPIO_W_CONF:GPIO写配置,意思就是将引脚配置为GPIO输出
112  *                            #GPIO_R_CONF:GPIO读配置,意思就是将引脚配置为GPIO输入
113  *                            #GPIO_OD_CONF:GPIO开漏配置,意思就是将引脚配置为开漏输出,否则为推挽输出(默认)
114  *                            #GPIO_3_STAT_CONF:三态配置                 
115  * \param[in] pin:选择需要配置的引脚,取值为AD5592R_PIN_0~AD5592R_PIN_7,可以按
116  *                 位或。
117  *                 
118  *                 
119  * \param[in] flag:根据func的值,可以传入一些特殊标志,具体如下:
120  *                  1、如果写入的func值为 GPIO_W_CONF,则传入的flag可以加入
121  *                     AD5592R_PIN_7_BUSY,表示将PIN7设定为BUSY引脚。
122  *                  2、如果写入的func值为GPIO_R_CONF,则传入的flag可以加入
123  *                     GPIO_R_CONF_EN_RDBK,表示下一个SPI操作输出GPIO引脚的状态,
124  *                     并将状态通过返回值返回。
125  *                  
126  *
127  */
128 u8 AD5592R_Pin_Config(ad5592r_addr_t func, u8 pin, u16 flag)
129 {
130     u16 data = 0;
131     
132     //将PIN_7设定为BUSY引脚,如果传入AD5592R_PIN_7_BUSY,那么D7也必须为1
133     if ((func == GPIO_W_CONF) && (flag & AD5592R_PIN_7_BUSY)) {
134         data |= AD5592R_PIN_7;
135     }
136     
137     if ((func == GPIO_W_CONF) && (flag & GPIO_R_CONF_EN_RDBK)) {
138         data |= GPIO_R_CONF_EN_RDBK;
139     }
140     
141     data |= (func << 11) | pin;
142     
143     AD5592R_CS = 0;
144     SPI2_ReadWriteByte(data);
145     AD5592R_CS = 1;
146     //如果使能GPIO回读,那么下一个SPI操作返回GPIO引脚的状态
147     if ((func == GPIO_W_CONF) && (flag & GPIO_R_CONF_EN_RDBK)) {
148         delay_us(1);
149         AD5592R_CS = 0;
150         data = SPI2_ReadWriteByte(0);
151         AD5592R_CS = 1;
152         return data;
153     }
154     
155     return 0;
156 }
157 
158 /**
159  * \brief 给8个GPIO写入数据
160  *
161  * \param[in] value:要写入的值
162  */
163 void AD5592R_GPIO_Write(u8 value)
164 {
165     u16 data = (GPIO_W_DATA << 11) | value;
166     
167     AD5592R_CS = 0;
168     SPI2_ReadWriteByte(data);
169     AD5592R_CS = 1;
170 }
171 
172 /**
173  * \brief 给DAC通道写入数据
174  *
175  * \param[in] channel:0~7有效,指定DAC通道
176  * \param[in] value:要写入的值,低12位有效
177  */
178 void AD5592R_DAC_Write_Data(u8 channel, u16 value)
179 {
180     u16 data = 0;
181     
182     channel &= 0x07;    //只取低3位
183     value &= 0x0FFF;    //只取低12位
184     
185     data = (1 <<15) | (channel << 12) | value;  //最高位要置1,表示写数据
186     
187     AD5592R_CS = 0;
188     SPI2_ReadWriteByte(data);
189     AD5592R_CS = 1;
190 }
191 
192 /**
193  * \brief 配置DAC通道回读
194  *
195  * \param[in] channel:0~7有效,指定DAC通道
196  * \param[in] value:要写入的值,低12位有效
197  *
198  * \note 指的是当某个DAC通道使能以后,每次使能回读之后的下一个时钟周期读出数据
199  *       并不是每次写DAC数据后的下一个时钟周期读出数据
200  */
201 u16 AD5592R_DAC_Readback(u8 channel)
202 {
203     u16 data = 0;
204     
205     channel &= 0x07;    //只取低3位
206     data = (DAC_READBACK << 11) | (0x3 << 3) | channel;
207     AD5592R_CS = 0;
208     SPI2_ReadWriteByte(data);
209     AD5592R_CS = 1;
210     delay_us(1);
211     AD5592R_CS = 0;
212     data = SPI2_ReadWriteByte(0);
213     AD5592R_CS = 0;
214     
215     data &= 0xFFF;  //取低12位,事实上读取成功后,最高位是1,以表示这是一个数据
216     return data;
217 }
218 
219 /**
220  * \brief 设定关断DAC和内部基准电压源
221  *
222  * \param[in] value:#true:关断基准电压源、 DAC和ADC
223  *                   #false:基准电压源和DAC关断状态由D9和D7至D0决定(默认)。
224  */
225 void AD5592R_PD_ALL_Set(u8 value)
226 {
227     u16 data = 0;
228     
229     data = AD5592R_Read_Register(POW_DOWN_REF_CNTL);    //先读出寄存器的值
230     
231     data |= (POW_DOWN_REF_CNTL << 11);
232     
233     if (value == false) {
234         data &= ~POW_DOWN_REF_CNTL_PD_ALL;
235     } else {
236         data |= POW_DOWN_REF_CNTL_PD_ALL;
237     }
238     
239     AD5592R_CS = 0;
240     SPI2_ReadWriteByte(data);
241     AD5592R_CS = 1;
242 }
243 
244 /**
245  * \brief 选择基准电压源
246  *
247  * \param[in] value:    #REF_INTERNAL:使用内部基准电压源 
248  *                       #REF_EXTERNAL:使用外部基准电压源
249  */
250 void AD5592R_Ref_Set(ref_select_t value)
251 {
252     u16 data = 0;
253     
254     data = AD5592R_Read_Register(POW_DOWN_REF_CNTL);    //先读出寄存器的值
255     
256     data |= (POW_DOWN_REF_CNTL << 11);
257     
258     if (value == REF_INTERNAL) {
259         data &= ~POW_DOWN_REF_CNTL_EN_REF;
260     } else {
261         data |= POW_DOWN_REF_CNTL_EN_REF;
262     }
263     
264     AD5592R_CS = 0;
265     SPI2_ReadWriteByte(data);   
266     AD5592R_CS = 1;
267 }
268 
269 /**
270  * \brief 选择关断DAC
271  *
272  * \param[in] pin:选择需要配置的引脚,取值为AD5592R_PIN_0~AD5592R_PIN_7,可以按
273  *                 位或。
274  * \param[in] mode:    #MORMAL_MODE:选择的引脚设置为正常模式 
275  *                      #PD_MODE:引脚若配置为DAC则关断
276  */
277 void AD5592R_PD_DAC(u8 pin, pd_mode_t mode)
278 {
279     u16 data = 0;
280     
281     data = AD5592R_Read_Register(POW_DOWN_REF_CNTL);    //先读出寄存器的值
282     data |= (POW_DOWN_REF_CNTL << 11);
283     if (mode == MORMAL_MODE) {
284         data &= ~pin;
285     } else {
286         data |= pin;
287     }
288     AD5592R_CS = 0;
289     SPI2_ReadWriteByte(data);
290     AD5592R_CS = 1;
291 }
292 
293 /**
294  * \brief ADC序列寄存器设置
295  *
296  * \prarm[in] channel:0~7有效,指定需要加入转换序列的ADC通道
297  * \prarm[in] flag:可以加入如下标志:
298  *                 #ADC_SEQ_REP:使能序列重复,不设置则禁用序列重复(默认)
299  *                 #ADC_SEQ_TEMP:使能温度指示器回读,不设置则禁用温度指示器回读(默认)
300  */
301 void AD5592R_ADC_Sequence_set(u8 channel, u16 flag)
302 {
303     u16 data = 0;
304     
305     channel &= 0x07;
306     
307     data = (ADC_SEQ_REG << 11) | flag | channel;
308     AD5592R_CS = 0;
309     SPI2_ReadWriteByte(data);
310     AD5592R_CS = 1;
311 }
312 
313 
314 /**
315  * \brief AD5592R软件复位
316  */
317 void AD5592R_Soft_Reset(void)
318 {
319     AD5592R_CS = 0;
320     SPI2_ReadWriteByte(0x7DAC); //SPI写入0x7DAC表示软件复位
321     AD5592R_CS = 1;
322 }
323 
324 
325 #if 0
326 int main(void)
327 {     
328     u8 i = 0;
329     u16 data[16] = { 0 };
330     u16 value = 0;
331     
332     delay_init();             //延时函数初始化      
333     NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);//设置中断优先级分组为组2:2位抢占优先级,2位响应优先级
334     uart_init(115200);         //串口初始化为115200
335     printf("Hello World!\r\n");
336     LED_Init();                  //初始化与LED连接的硬件接口
337 
338     AD5592R_Init();
339     //AD5592R_Read_All_Register(data);
340     //for (i = 0; i < 16; i++) {
341     //    printf("data[%d] = 0x%04x\r\n", i, data[i]);
342     //}
343     
344     AD5592R_Ref_Set(REF_EXTERNAL);  //DAC使用外部基准源
345     AD5592R_Pin_Config(DAC_PIN_CONF, AD5592R_PIN_ALL, 0);   //将所有引脚配置为DAC
346     AD5592R_DAC_Write_Data(0, 0x888);
347     value = AD5592R_DAC_Readback(0);
348     printf("value = 0x%04x\r\n", value);
349        
350     while(1)                        
351     {
352         delay_ms(500);
353         delay_ms(500);
354         LED0=!LED0;//DS0闪烁
355     }
356 }
357 #endif

ad5592r.h

  1 /**
  2  * \brief AD5592R的寄存器和数据都是16位的
  3  *        SYNC引脚在16位数据传输开始之前拉低,16位数据传输完成之后拉高
  4  *        高位先传
  5  *        空闲时时钟为高电平
  6  *        写入DAC时,数据能够以最高50 MHz的速率传输。执行转换或从AD5592R传输数据时, SCLK的最大速度为20 MHz。
  7  *        对于AD5592R来说,在时钟的下降沿读取数据,时钟上升沿发送数据,也就是说
  8  *        主机应该配置为下降沿发送,上升沿读取
  9  *        片选信号拉低到拉高之间的时间间隔最小为30nS
 10  */
 11 
 12 #ifndef __AD5592R_H
 13 #define __AD5592R_H                
 14 #include "sys.h" 
 15 
 16 /**
 17  * \brief STM32引脚定义
 18  * @{
 19  */
 20 #define    AD5592R_CS             PBout(12)          //AD5592R的片选信号
 21 /**
 22  * @}
 23  */
 24 
 25 /**
 26  * \brief AD5592R引脚定义
 27  * @{
 28  */
 29 #define AD5592R_PIN_0           (1 << 0)
 30 #define AD5592R_PIN_1           (1 << 1)
 31 #define AD5592R_PIN_2           (1 << 2)
 32 #define AD5592R_PIN_3           (1 << 3)
 33 #define AD5592R_PIN_4           (1 << 4)
 34 #define AD5592R_PIN_5           (1 << 5)
 35 #define AD5592R_PIN_6           (1 << 6)
 36 #define AD5592R_PIN_7           (1 << 7)
 37 #define AD5592R_PIN_ALL         0xFF
 38 
 39 #define AD5592R_PIN_7_BUSY      (1 << 8)
 40 #define GPIO_R_CONF_EN_RDBK     (1 << 10)
 41 /**
 42  * @}
 43  */
 44 
 45 #ifndef true
 46 #define true 1
 47 #endif
 48 
 49 #ifndef false
 50 #define false 0
 51 #endif
 52 
 53 typedef enum ref_select {
 54     REF_INTERNAL = 0,    /* 使用内部基准电压源 */
 55     REF_EXTERNAL = 1,    /* 使用外部基准电压源 */
 56 } ref_select_t;
 57 
 58 typedef enum pd_mode {
 59     MORMAL_MODE = 0,    /* 选择的引脚设置为正常模式 */
 60     PD_MODE     = 1,    /* 通道若配置为DAC则关断 */
 61 } pd_mode_t;
 62 
 63 /**
 64  * \brief 定义AD5592R的寄存器地址
 65  */
 66 typedef enum ad5592r_addr {
 67     NOP                 = 0,    //无操作
 68     DAC_READBACK        = 1,    //DAC回读寄存器
 69     ADC_SEQ_REG         = 2,    //ADC序列寄存器
 70     GP_CNTL_REG         = 3,    //通用控制寄存器
 71     ADC_PIN_CONF        = 4,    //ADC引脚配置
 72     DAC_PIN_CONF        = 5,    //DAC引脚配置
 73     PULL_DOWN_CONF      = 6,    //下拉配置
 74     RDBK_LDAC_MODE      = 7,    //回读和LDAC模式
 75     GPIO_W_CONF         = 8,    //GPIO写配置
 76     GPIO_W_DATA         = 9,    //GPIO写数据
 77     GPIO_R_CONF         = 10,   //GPIO读配置
 78     POW_DOWN_REF_CNTL   = 11,   //断电/基准控制
 79     GPIO_OD_CONF        = 12,   //GPIO开漏配置
 80     GPIO_3_STAT_CONF    = 13,   //三态配置
 81     RESERV              = 14,   //保留
 82     SOFT_REST           = 15,   //软件复位
 83 } ad5592r_addr_t;
 84                  
 85 /**
 86  * \brief 寄存器定义
 87  * @{
 88  */
 89  
 90 /**
 91  * \brief 输入移位寄存器
 92  *      +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
 93  *      |D15|D14|D13|D12|D11|D10|D9 |D8 |D7 |D6 |D5 |D4 |D3 |D2 |D1 |D0 |
 94  *      +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
 95  *      | 0 | 控制寄存器地址| 0 | 0 |           控制寄存器数据          |
 96  *      +---+-----------+---+---+---+-----------------------------------+
 97  *      | 1 |  DAC地址  |                   12位DAC数据                 |
 98  *      +---+-----------+-----------------------------------------------+
 99  *      控制寄存器应该写入的数据格式见各个具体寄存器的描述
100  * @{
101  */
102 #define CNTL_BIT                (0 << 15)   //表示控制寄存器
103 #define DATA_BIT                (1 << 15)   //表示数据寄存器
104 //当D15为1时,[D14:D12]对应DAC通道,[D11:D0]表示DAC数据
105 
106 /**
107  * \brief 以下定义为控制地址定义,当B15为0时有效
108  * @{
109  */
110 #define CNTL_ADDR_NOP                (0 << 11)   //无操作
111 
112 /**
113  * \brief DAC回读寄存器,[D15:D5]固定为 0000 1000 000,[D4:D3]为11表示使能回读,为00表示禁能回读(默认),[D2:D0]选择DAC通道
114  * 当使能了DAC回读,那么给DAC通道写入数据并且SYNC引脚拉高之后,将SYNC拉低并发送16个时钟就能从SDO引脚读到回读的值。
115  */
116 #define CNTL_ADDR_DAC_READBACK       (1 << 11)   //DAC回读
117 
118 /**
119  * \brief ADC序列寄存器,[D15:D10]固定为 0001 00,[D7:D0]某一位为1则该ADC通道在转换序列中
120  */
121 //ADC转换结果,D15为0,[D14:D12]指定ADC通道,[D11:D0]表示转换后的结果
122 #define CNTL_ADDR_ADC_SEQ_REG        (2 << 11)   //ADC序列寄存器,选择ADC(s)进行转换
123 #define ADC_SEQ_REP         (1 << 9)    //#0:ADC序列重复禁能(默认)。#1:ADC序列重复使能
124 #define ADC_SEQ_TEMP        (1 << 10)   //#0:禁用温度指示器回读(默认)。#1:启用温度指示器回读
125 
126 #define CNTL_ADDR_GP_CNTL_REG        (3 << 11)   //通用控制寄存器,ADC和DAC控制寄存器
127 
128 /**
129  * \brief ADC引脚配置寄存器,[D15:D8]固定为 0010 0000,[D7:D0]哪一位为1则设定哪个引脚为ADC引脚,如果设置为0(默认),
130  *        则输入输出功能由引脚配置寄存器决定
131  */
132 #define CNTL_ADDR_ADC_PIN_CONF       (4 << 11)   //ADC引脚配置,选择哪些引脚是ADC输入
133 
134 /**
135  * \brief DAC引脚配置寄存器,[D15:D8]固定为0010 1000,[D7:D0]哪一位为1则设定哪个引脚为DAC引脚,如果设置为0(默认),
136  *        则输入输出功能由引脚配置寄存器决定
137  */
138 #define CNTL_ADDR_DAC_PIN_CONF       (5 << 11)   //DAC引脚配置,选择哪些引脚是DAC输出
139 
140 /**
141  * \brief 下拉配置寄存器,[D15:D8]固定为0011 0000,[D7:D0]:#0:输入/输出功能由引脚配置寄存器决定。#1:该引脚为85kΩ下拉
142  */
143 #define CNTL_ADDR_PD_CONF            (6 << 11)   //下拉配置,选择哪些引脚具有85kΩ下拉电阻到GND
144 
145 /**
146  * \brief 回读和LDAC模式寄存器,[D15:D7]固定为0011 1000 0,
147  * [D5:D2]指定要回读的寄存器地址,读取寄存器的值通过该指令
148  * [D1:D0]确定如何处理写入DAC输入寄存器的数据:
149  *      #00:写入输入寄存器的数据立即复制到DAC寄存器,DAC输出更新(默认)
150  *      #01:写入输入寄存器的数据不会复制到DAC寄存器,DAC输出不更新
151  *      #10:写入输入寄存器的数据复制到相应的DAC寄存器,数据传输后DAC输出同时更新
152  */
153 #define CNTL_ADDR_RDBK_LDAC_MODE     (7 << 11)   //回读和LDAC模式,选择加载DAC(LDAC)功能的操作和/或回读哪个配置寄存器
154 #define RDBK_LDAC_MODE_EN           (1 << 6)     //#0:未启用回读。#1:[D5:D2]选择要回读的寄存器,读取结束后D6自动清除
155 #define RDBK_LDAC_MODE_IMMDEDIATELY (0 << 0)    //立即更新
156 #define RDBK_LDAC_MODE_NOT          (1 << 0)    //不更新
157 #define RDBK_LDAC_MODE_AFTER        (2 << 0)    //数据传输后更新
158 
159 /**
160  * \brief GPIO写配置寄存器,[D15:D9]固定为0100 000,D8描述见下,[D7:D0]某位为1表示该引脚为通用输出引脚,否则该引脚功能由引脚配置寄存器决定(默认)
161  */
162 #define CNTL_ADDR_GPIO_W_CONF        (8 << 11)   //GPIO写配置,选择哪些引脚是GPIO输出
163 #define GPIO_W_CONF_IO7_BUSY    (1 << 8)    //#0:表示I/O7未配置为BUSY功能。#1:I/O7引脚配置为BUSY功能,D7也必须设置为1
164 
165 /**
166  * \brief GPIO写数据寄存器,[D15:D8]固定为0100 1000,[D7:D0]确定引脚输出电平
167  */
168 #define CNTL_ADDR_GPIO_W_DATA        (9 << 11)   //向GPIO写数据
169 
170 
171 /**
172  * \brief GPIO读配置寄存器,[D15:D11]固定为0101 0,[D9:D8]:固定为0。[D7:D0]某位为0则表示该引脚输入/输出功能由配置寄存器决定,为1表示这是一个通用的输入引脚
173  */
174 #define CNTL_ADDR_GPIO_R_CONF        (10 << 11)  //GPIO读配置,选择哪些引脚是GPIO输入
175 #define GPIO_R_CONF_EN_RDBK     (1 << 10)   //#0:[D7:D0]确定哪些引脚为通用输入,#1:写一个SPI操作会计时(clocks)GPIO引脚的状态
176 
177 /**
178 * \brief 断电/参考控制寄存器,[D15:D11]固定为0101 1,D8固定为0,[D7:D0]某位为0则表示通道处于正常工作模式(默认),为1时如果通道配置为DAC,则该通道断电
179  */
180 #define CNTL_ADDR_POW_DOWN_REF_CNTL  (11 << 11)  //断电/参考控制,关闭DAC并启用/禁用参考
181 #define POW_DOWN_REF_CNTL_PD_ALL    (1 << 10)    //#0:参考和DAC断电状态由D9及[D7:D0]确定(默认)。#1:基准、DAC和ADC断电
182 #define POW_DOWN_REF_CNTL_EN_REF    (1 << 9)     //#0:参考和buffer断电,如果使用外部参考,则设置该位。#1:基准及buffer通电,参考源为VREF引脚
183 
184 /**
185  * \brief GPIO开漏配置寄存器,[D15:D8]固定为0110 0000,[D7:D0]某位为1表示该引脚为开漏输出引脚,引脚也必须设置为数字输出引脚。为0则表示改引脚设置为上/下拉
186  */
187 #define CNTL_ADDR_GPIO_OD_CONF       (12 << 11)  //GPIO开漏配置,为GPIO选择开漏或上/下拉
188 
189 /**
190  * \brief 三态配置寄存器,[D15:D8]固定为0110 1000,[D7:D0]:#0:输入/输出功能由引脚配置寄存器决定。#1:该引脚为三态输出
191  */
192 #define CNTL_ADDR_GPIO_3_STAT_CONF   (13 << 11)  //三态配置,选择哪些引脚是三态
193 #define CNTL_ADDR_RESERV             (14 << 11)  //保留
194 
195 /**
196  * \brief 软件复位写入序列:0111 1101 1010 1100,即0x7DAC
197  */
198 #define CNTL_ADDR_SOFT_REST          (15 << 11)  //软件复位
199 /**
200  * @}
201  */
202 
203 /**
204  * @}
205  */
206  
207  
208 /**
209  * \brief IO引脚配置寄存器
210  *      +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
211  *      |D15|D14|D13|D12|D11|D10|D9 |D8 |D7 |D6 |D5 |D4 |D3 |D2 |D1 |D0 |
212  *      +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
213  *      | 0 |   寄存器地址  |   保留    |IO7|IO6|IO5|IO4|IO3|IO2|IO1|IO0|
214  *      +---+---------------+-----------+---+---+---+---+---+---+---+---+
215  * @{
216  */
217  
218 /**
219  * \brief IO引脚配置寄存器地址,[D14:D11]选择功能,[D7:D0]选择是否使能该功能
220  * @{
221  */
222 #define IO_CONF_ADDR_ADC_PIN            (4 << 11)   //配置为ADC引脚
223 #define IO_CONF_ADDR_DAC_PIN            (5 << 11)   //配置为DAC引脚
224 #define IO_CONF_ADDR_PULL_DOWN          (6 << 11)   //配置为下拉(默认配置为上拉)
225 #define IO_CONF_ADDR_GPIO_W_CONF        (8 << 11)   //配置为GPIO写
226 #define IO_CONF_ADDR_GPIO_R_CONF        (10 << 11)  //配置为GPIO读
227 #define IO_CONF_ADDR_GPIO_OD_CONF       (12 << 11)  //配置为GPIO开漏
228 #define IO_CONF_ADDR_3_STAT_CONF        (13 << 11)  //配置为三态
229 /**
230  * @}
231  */
232  
233 /**
234  * @}
235  */
236  
237 /**
238 * \brief 通用控置寄存器,[D15:D10] 固定为0 0011 0,[D3:D0]固定为0000
239  * @{
240  */
241 #define GP_COTL_ADC_BUF_PRECHARGE       (1 << 9)    //#0:ADC缓冲器不用于对ADC预充电,如果ADC缓冲区已经启用,则始终通电(默认)
242                                                     //#1:ADC缓冲器用于对ADC预充电,如果ADC缓冲区已经启用,则在转换发生时将其通电,然后断电,直到下一次转换发生
243 #define GP_COTL_ADC_BUF_EN              (1 << 8)    //#0:ADC缓冲器禁能(默认),#1:ADC缓冲器使能                                          
244 #define GP_COTL_LOCK                    (1 << 7)    //#0:可以更改输入/输出引脚配置寄存器的内容(默认),#1:不能更改……
245 #define GP_COTL_ALL_DAC                 (1 << 6)    //#0:对于未来的DAC写入,DAC地址位确定写入哪个DAC(默认)
246                                                     //#1:对于未来的DAC写入,DAC地址位将被忽略,配置为DAC的所有通道将使用相同的数据进行更新
247 #define GP_COTL_ADC_RANGE_REFx2         (1 << 5)    //#0:ADC增益为0~Vref(默认)。#1:ADC增益为0~2Vref
248 #define GP_COTL_DAC_RANGE_REFx2         (1 << 4)    //#0:ADC增益为0~Vref(默认)。#1:DAC增益为0~2Vref
249 /**
250  * @}
251  */
252  
253 
254 /**
255  * \brief 函数声明
256  * @{
257  */ 
258 /**
259  * /brief 初始化AD5592R
260  */
261 extern void AD5592R_Init(void);
262 
263 /**
264  * \brief AD5592R硬件复位
265  */
266 extern void AD5592R_HW_Reset(void);
267 
268 /**
269  * \brief 读取AD5592R的寄存器
270  *
271  * \param[in] addr:寄存器地址
272  *
273  * \note D1和D0用来选择LDAC模式,每当调用一次该函数时,都会将模式设定为DAC即时更
274  *       新模式,需要修改的话,可以用一个变量保存。
275  */
276 extern u16 AD5592R_Read_Register(ad5592r_addr_t addr);
277 
278 /**
279  * \brief 读取AD5592R的寄存器
280  *
281  * \note 这个函数主要是用来测试,读出来15个寄存器的值。芯片复位后读取,其中data[6]为0x00FF,data[7]为0x005C,其他寄存器的值都为0,如果读出的结果都为0xFFFF,那可能通信出现问题了
282  */
283 extern void AD5592R_Read_All_Register(u16 data[16]);
284 
285 /**
286  * \brief 通用控制寄存器配置
287  *
288  * \param[in] flag:可以加入如下标志:
289  *                  #GP_COTL_ADC_BUF_PRECHARGE: ADC缓冲器用于对ADC预充电,不设置则禁用(默认)
290  *                  #GP_COTL_ADC_BUF_EN:        使能ADC缓冲器,不设置则禁能(默认)
291  *                  #GP_COTL_LOCK:              不能改变I/Ox引脚配置寄存器的内容,不设置则可以改变(默认)
292  *                  #GP_COTL_ALL_DAC:           (一个数据)写入所有DAC,不设置则由DAC地址决定写入哪个DAC(默认)
293  *                  #GP_COTL_ADC_RANGE_REFx2:   ADC增益为0 V至2 × VREF,不设置则为1倍(默认)
294  *                  #GP_COTL_DAC_RANGE_REFx2:   DAC增益为0 V至2 × VREF,不设置则为1倍(默认)
295  */
296 extern void AD5592R_GP_Contol_Set(u16 flag);
297 
298 
299 /**
300  * \brief 将指定的引脚配置为指定的功能
301  *
302  * \param[in] func:设定的功能#ADC_PIN_CONF:配置为ADC引脚
303  *                            #DAC_PIN_CONF:配置为DAC引脚
304  *                            #PD_CONF:下拉配置,设定为85kΩ下拉(默认就是这个)
305  *                            #GPIO_W_CONF:GPIO写配置,意思就是将引脚配置为GPIO输出
306  *                            #GPIO_R_CONF:GPIO读配置,意思就是将引脚配置为GPIO输入
307  *                            #GPIO_OD_CONF:GPIO开漏配置,意思就是将引脚配置为开漏输出,否则为推挽输出(默认)
308  *                            #GPIO_3_STAT_CONF:三态配置                 
309  * \param[in] pin:选择需要配置的引脚,取值为AD5592R_PIN_0~AD5592R_PIN_7,可以按
310  *                 位或。
311  *                 
312  *                 
313  * \param[in] flag:根据func的值,可以传入一些特殊标志,具体如下:
314  *                  1、如果写入的func值为 GPIO_W_CONF,则传入的flag可以加入
315  *                     AD5592R_PIN_7_BUSY,表示将PIN7设定为BUSY引脚。
316  *                  2、如果写入的func值为GPIO_R_CONF,则传入的flag可以加入
317  *                     GPIO_R_CONF_EN_RDBK,表示下一个SPI操作输出GPIO引脚的状态,
318  *                     并将状态通过返回值返回。
319  *                  
320  *
321  */
322 extern u8 AD5592R_Pin_Config(ad5592r_addr_t func, u8 pin, u16 flag);
323 
324 /**
325  * \brief 给8个GPIO写入数据
326  *
327  * \param[in] value:要写入的值
328  */
329 extern void AD5592R_GPIO_Write(u8 value);
330 
331 /**
332  * \brief 给DAC通道写入数据
333  *
334  * \param[in] channel:0~7有效,指定DAC通道
335  * \param[in] value:要写入的值,低12位有效
336  */
337 extern void AD5592R_DAC_Write_Data(u8 channel, u16 value);
338 
339 /**
340  * \brief 配置DAC通道回读
341  *
342  * \param[in] channel:0~7有效,指定DAC通道
343  * \param[in] value:要写入的值,低12位有效
344  *
345  * \todo 指的是当某个DAC通道使能以后,每次写DAC数据后的下一个时钟周期读出数据?
346  *       还是说每次使能回读之后的下一个时钟周期读出数据?本函数写的是后者。
347  */
348 extern u16 AD5592R_DAC_Readback(u8 channel);
349 
350 /**
351  * \brief 设定关断DAC和内部基准电压源
352  *
353  * \param[in] value:#true:关断基准电压源、 DAC和ADC
354  *                   #false:基准电压源和DAC关断状态由D9和D7至D0决定(默认)。
355  */
356 extern void AD5592R_PD_ALL_Set(u8 value);
357 
358 /**
359  * \brief 选择基准电压源
360  *
361  * \param[in] value:    #REF_INTERNAL:使用内部基准电压源 
362  *                       #REF_EXTERNAL:使用外部基准电压源
363  */
364 extern void AD5592R_Ref_Set(ref_select_t value);
365 
366 /**
367  * \brief 选择关断DAC
368  *
369  * \param[in] pin:选择需要配置的引脚,取值为AD5592R_PIN_0~AD5592R_PIN_7,可以按
370  *                 位或。
371  * \param[in] mode:    #MORMAL_MODE:选择的引脚设置为正常模式 
372  *                      #PD_MODE:引脚若配置为DAC则关断
373  */
374 extern void AD5592R_PD_DAC(u8 pin, pd_mode_t mode);
375 
376 /**
377  * \brief ADC序列寄存器设置
378  *
379  * \prarm[in] channel:0~7有效,指定需要加入转换序列的ADC通道
380  * \prarm[in] flag:可以加入如下标志:
381  *                 #ADC_SEQ_REP:使能序列重复,不设置则禁用序列重复(默认)
382  *                 #ADC_SEQ_TEMP:使能温度指示器回读,不设置则禁用温度指示器回读(默认)
383  */
384 extern void AD5592R_ADC_Sequence_set(u8 channel, u16 flag);
385 
386 
387 /**
388  * \brief AD5592R软件复位
389  */
390 extern void AD5592R_Soft_Reset(void);
391 
392 /**
393  * @}
394  */
395 
396 #endif

 

标签:GPIOB,Pin,代码,STM32,SPI,InitStructure,AD5592R,GPIO
来源: https://www.cnblogs.com/Suzkfly/p/16475202.html