【嵌入式硬件芯片开发笔记】4-20mA DAC芯片AD5421配置流程
16位、串行输入、环路供电、4 mA至20 mA DAC
可用于HART协议相关电路 同AD5700配合使用
AD5421的SPI和普通的不一样
回读时要发两段 CS中间拉高一次
数据在SCLK上升沿逐个输出,而且在 SCLK下降沿有效
固CPOL为低电平,CPHA为2 edge
可选择开启CRC校验
一般接的是4-20mA
在加载DAC、强制报警电流、复位、启动VLOOP/温度测量 或无操作命令字节后写入的16 Bits数据字为无关位
上电后寄存器复位,看门狗开启,默认值1s,在1s内没有收到SPI信号,则FAULT置高。
/*!* @brief 操作AD5421** @param [in] hspi: AD5421对应的SPI* [in] add: 寄存器地址* [in] data: 数据(读数据可以不管)* [in] WriteNotRead: true为写,false为读** @return dat_16: 返回数据*/
uint16_t Ctrl_AD5421(SPI_HandleTypeDef *hspi,uint8_t add,uint16_t data,bool WriteNotRead)
{uint16_t dat_16=0;uint8_t dat_buf[3];memset(dat_buf,0,sizeof(dat_buf));if(WriteNotRead){dat_buf[0]=add&0x7F;dat_buf[1]=data>>8;dat_buf[2]=data&0x00FF;SPI_Send_x_Read_y(&hspi2,dat_buf,3,0,30,true);}else{dat_buf[0]=add|0x80;dat_buf[1]=0;dat_buf[2]=0;SPI_Send_x_Read_y(&hspi2,dat_buf,3,0,30,true);dat_buf[0]=AD5421_NOP;dat_16=SPI_Send_x_Read_y(&hspi2,dat_buf,1,2,30,false)&0x0000FFFF;}return dat_16;
}/*!* @brief 操作AD5421的DAC** @param [in] current_v: 要输入的电流值* [in] WriteNotRead: true为写入并加载DAC,false为读DAC并返回电流值** @return current: 返回的DAC寄存器中对应的电流值*/
float Ctrl_AD5421_DAC(float current_v,bool WriteNotRead)
{float current=0.0f;current=current_v;uint16_t dat_16=0;if(WriteNotRead){ if(current>19.9998f){dat_16=0xFFFF;}else if(current<4.0f){dat_16=0;}else{dat_16=(current-4.0f)*0x10000/16.0f;}Ctrl_AD5421(&hspi2,AD5421_DAC,dat_16,true); Ctrl_AD5421(&hspi2,AD5421_Load_DAC,0,true);}else{dat_16=Ctrl_AD5421(&hspi2,AD5421_DAC,0,false);current=16.0f*dat_16/0x10000+4.0f;Ctrl_AD5421(&hspi2,AD5421_Load_DAC,0,true);}return current;
}/*!* @brief 操作AD5421的ADC** @param [in] adc_flag: 0 测量VLOOP,1 测量芯片温度* [in] EnableNotDisable: true为写入并加载DAC,false为读DAC并返回电流值** @return dat_float: ADC测量值*/
float Ctrl_AD5421_ADC(uint8_t adc_flag,bool EnableNotDisable)
{float dat_float=0.0f;uint16_t dat_16=0; if(EnableNotDisable){dat_16=Ctrl_AD5421(&hspi2,AD5421_Control,0,false);Ctrl_AD5421(&hspi2,AD5421_Control,dat_16|(1<<7),true);}else{Ctrl_AD5421(&hspi2,AD5421_Control,dat_16&(~(1<<7)),true);return dat_float;}Ctrl_AD5421(&hspi2,AD5421_Load_ADC,0,true);delay_us(50);if(adc_flag){dat_16=Ctrl_AD5421(&hspi2,AD5421_Control,0,false);Ctrl_AD5421(&hspi2,AD5421_Control,dat_16|(1<<8),true);dat_16=Ctrl_AD5421(&hspi2,AD5421_Fault,0,false); dat_float= (-1.559)*(dat_16&0x00FF)+312;printf("[INFO] AD5421_TEMP: %0.4f\n",dat_float);}else{dat_16=Ctrl_AD5421(&hspi2,AD5421_Control,0,false);Ctrl_AD5421(&hspi2,AD5421_Control,dat_16&(~(1<<8)),true);dat_16=Ctrl_AD5421(&hspi2,AD5421_Fault,0,false);dat_float=2.5f/256.0f*(dat_16&0x00FF);printf("[INFO] AD5421_VLOOP: %0.4f\n",dat_float);}return dat_float;
}/*!* @brief 初始化AD5421** @param None** @return None*/
void Init_AD5421(void)
{ Ctrl_AD5421(&hspi2,AD5421_RESET,0,true);delay_us(50);Ctrl_AD5421(&hspi2,AD5421_Control,0xFC00,true); Ctrl_AD5421_DAC(20,true);Ctrl_AD5421_ADC(0,true);
}