ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

AD5592R STM32驱动代码

2022-07-16 17:00:31  阅读:180  来源: 互联网

标签:GPIOB Pin 代码 STM32 SPI InitStructure AD5592R GPIO


一、前言

  最近项目上需要使用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

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有