目录
概要
验证方案时用到了AD7172芯片,24位AD,分辨率是真的高,无敌。但是前级放大电路不给力,所以放弃这版方案了。代码贴出来供大家参考,写的一般如果有错误轻点喷,谢谢。
PS:整体代码是根据ADI给的代码改写的
整体架构流程
为了更好的移植性,以及复用代码。先写框架,然后通过注册函数的方式实例化对象,通过对象调用设备(简单说就是结构体,函数指针)。
文件构成:
ad717x_Frame.c、ad717x_Frame.h【框架文件 里面有PAD7172_Struct结构体】
ad7172_2_regs.h【AD7172的寄存器定义文件】
Ad7172Spi.c、Ad7172Spi.h【硬件层、和MCU相关的文件、移植只需要重写这个文件】
AD7172Config.c、AD7172Config.h【实例化文件、配置PAD7172_Struct结构体、链接硬件和框架】
主要寄存器
.....手册是中文的自己看吧,配合代码不难
使用方法:
AD7172Config.c【实例化文件】 在这里写一下主要配置参数
void AD7172ParmInit(void){
gAd7172.regs = ad7172_2_regs;
gAd7172.num_regs = sizeof(ad7176_2_regs) / sizeof(ad7176_2_regs[0]);
gAd7172.active_device = ID_AD7172_2;
gAd7172.num_channels = 2;
// 转化模式设置
gAd7172.mode = CONTINUOUS;
// 设置极性 false 为单极性 Ture 为双极性
gAd7172.setups[0].bi_unipolar = 0;
gAd7172.setups[1].bi_unipolar = 0;
// 设置参考源
gAd7172.setups[0].ref_source = EXTERNAL_REF;
gAd7172.setups[1].ref_source = EXTERNAL_REF;
// 设置buff 7172不需要
// gAd7172.setups[0].ref_buff = 0;
// gAd7172.setups[0].input_buff = 0;
// 设置 滤波和速率
// gAd7172.filter_configuration[0].enhfilt
// 输出速率
gAd7172.filter_configuration[0].odr = sps_100;
gAd7172.filter_configuration[1].odr = sps_100;
// 设置通道映射寄存器 选择当前有效的通道、各通道使用哪些输入以及该通道使用何种设置来配置ADC。
gAd7172.chan_map[0].analog_inputs.ainp.pos_analog_input = AIN0;
gAd7172.chan_map[0].analog_inputs.ainp.neg_analog_input = REF_M;
gAd7172.chan_map[1].analog_inputs.ainp.pos_analog_input = AIN1;
gAd7172.chan_map[1].analog_inputs.ainp.neg_analog_input = REF_M;
// 使用四种设置中的哪一种来配置ADC。设置由四个寄存器组成:设置配置寄存器、滤波器配置寄存器、失调寄存器和增益寄存器。
gAd7172.chan_map[0].setup_sel = 0;
gAd7172.chan_map[1].setup_sel = 0;
// 1为开 0为关闭
gAd7172.chan_map[0].channel_enable = 1;
gAd7172.chan_map[1].channel_enable = 1;
gAd7172.spi_write_and_read = stm32_spi_write_and_read;
gAd7172.SetCsPin = SetAD7172CsPin;
gAd7172.spi_receive = stm32_spi_receive;
gAd7172.GetDinPin = spi_miso_input;
AD717X_Init(&gAd7172);
}
然后通过后台Loop循环调用下面函数即可工作(连续读取)
/*************************************************************
** Function name: AD7176Loop
** Descriptions: 读取ADC数据的主循环函数 需要根据ADC的配置来 循环调用
** Input parameters: None
** Output parameters: None
** Returned value: None
** Remarks: None
*************************************************************/
void AD7176Loop(void){
AD717X_OnlyRead32(&gAd7172);
Var_WriteHoldReg32(&gdev_ADC0, gAd7172.adcValue[0]);
Var_WriteHoldReg32(&gdev_ADC1, gAd7172.adcValue[1]);
}
/*************************************************************
** Function name: GetAD7176ADCChannel
** Descriptions: 提供ADC数据的接口
** Input parameters: channel: 要获取的通道 0:ADC0 1:ADC1 2:ADC2 3:ADC
** Output parameters: None
** Returned value: None
** Remarks: None
*************************************************************/
int32_t GetAD7176ADCChannel(uint8_t channel){
return AD717X_GetChannelValue(&gAd7172, channel);
}
硬件层:
如果你使用的是STM32 HAL库,基本上不需要改变
/*************************************************************
** Function name: SetAD7172CsPin
** Descriptions: 操作AD7172的片选引脚
** Input parameters: None
** Output parameters: None
** Returned value: None
** Remarks: None
*************************************************************/
void SetAD7172CsPin(uint8_t state){
HAL_GPIO_WritePin(AD_CS_GPIO_Port,AD_CS_Pin,(GPIO_PinState )state);
}
/**
* @brief Write/read multiple messages to/from SPI.
* @param desc - The SPI descriptor.
* @param msgs - The messages array.
* @param len - Number of messages.
* @return 0 in case of success, errno codes otherwise.
*/
int32_t stm32_spi_transfer(struct no_os_spi_msg *msgs, uint32_t len)
{
for (uint32_t i = 0; i < len; i++) {
// CS 拉低
// gdesc->port->BSRR = NO_OS_BIT(sdesc->chip_select->number) << 16;
SetAD7172CsPin(0);
// 如果CS拉低之后需要延迟 则delay
if(msgs[i].cs_delay_first){
// no_os_udelay(msgs[i].cs_delay_first);
}
HAL_SPI_TransmitReceive(&hspi1, msgs[i].tx_buff, msgs[i].rx_buff, msgs[i].bytes_number, AD7172SPI_TIMEOUT_MS);
if(msgs[i].cs_delay_last){
// no_os_udelay(msgs[i].cs_delay_last);
}
if (msgs[i].cs_change){
/* De-assert CS */
// gdesc->port->BSRR = NO_OS_BIT(sdesc->chip_select->number);
SetAD7172CsPin(1);
}
if(msgs[i].cs_change_delay){
// no_os_udelay(msgs[i].cs_change_delay);
}
}
return 0;
}
int32_t stm32_spi_write_and_read(uint8_t *data, uint16_t bytes_number)
{
struct no_os_spi_msg msg = {
.bytes_number = bytes_number,
.cs_change = true,
.rx_buff = data,
.tx_buff = data,
};
if (!bytes_number)
return 0;
return stm32_spi_transfer(&msg, 1);
}
int32_t stm32_spi_receive(uint8_t *data, uint16_t bytes_number){
struct no_os_spi_msg msg = {
.bytes_number = bytes_number,
.cs_change = true,
.rx_buff = data,
.tx_buff = data,
};
if (!bytes_number)
return 0;
HAL_SPI_Receive(&hspi1, msg.rx_buff, msg.bytes_number, AD7172SPI_TIMEOUT_MS);
return 0;
}
// SPI 的 MISO信号引脚 读取功能
uint8_t spi_miso_input(void){
return (uint8_t)HAL_GPIO_ReadPin(GPIOA,GPIO_PIN_6);
}
小结
完整代码放CSDN可以下载。