前言:看了官方驱动,比较繁琐复杂,在此根据芯片手册内容并针对测量ADC电压值使用场景重写驱动。诸位有需要的同行可以自行修改相应为位进行使用。
注:图片截自立创商城,侵权必删。
一、驱动步骤
参考数据手册中压力传感器的读取方式,去除不必要的步骤。
1.ADC复位
根据手册描述,对芯片连续写入64个1即可完成复位。
2.配置ADC控制寄存器
ADC控制寄存器可以配置数据连续读取、状态寄存器使能、内部基准电压使能、模式选择、ADC工作模式、ADC时钟源等。
15:13位:0 0 0
12位(DOUT_RDY_DEL):0 (此时控制SCLK无效沿到DOUT/RDY高电平时间延迟为10ns)
11位(CONT_READ):0(不开启连续读取 采用标准SPI通信)
10位(DATA_STATUS):1 (状态寄存器不使能)
9位(CS_EN):1 (DOUT/RDY引脚在SCLK无效沿之后继续用作DOUT引脚。当CS变为高电平时,该引脚变为RDY引脚)
8位(REF_EN):1 (内部基准电压使能)
7:6位(POWER_MODE):11 (全功率)
5:2位(Mode):0 0 0 0 (连续转换模式)
1:0位(CLK_SET):01 (内部时钟)
综上
ADC_CONTROL | 15 | 14 | 13 | 12 | 11 | 10 | 9 | 8 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
0 | 0 | 0 | 0 | 0 | 1 | 1 | 1 | 1 | 1 | 0 | 0 | 0 | 0 | 0 | 1 |
ADC_CONTROL = 0x7C1
3.配置通道寄存器
通过各寄存器,用户可以配置通道(AINP输入和AINM输入),使能或禁用通道,以及选择设置。设
置可从用户定义的8种不同选项中选择。当ADC转换时,它会自动遍历所有使能的通道。
15位(Enable):1 (通道使能)
14:12位(Setup):0 0 0 (设置为0分配给该通道)
11:10(0):0 0 (置0正常工作)
9:5(AINP):0 0 0 0 0 (正模拟输入为AIN0)
4:0(AINM):0 0 0 0 1 (负模拟输入为AIN1)
综上
CHANNEL_0 | 15 | 14 | 13 | 12 | 11 | 10 | 9 | 8 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
1 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 |
CHANNEL_0 = 0x8001
4.配置配置寄存器
没有打错字,就是要配置“配置寄存器”:-)。AD7124-8有8个配置寄存器: CONFIG_0至CONFIG_7。每个配置寄存器与一种设置相关联,即CONFIG_x与设置x相关联。
在配置寄存器中可以配置基准电压源、极性、基准电压缓冲器的使能或禁用。
15:12位(0):0 0 0 0 (置0正常工作)
11位(bipolar):0 (单极性工作模式)
10:9位(Burnout):0 0 (开路检测电流源关闭)
8位(REF_BUFP): 1 (缓冲正基准电压输入)
7位(REF_BUFM):1 (缓冲负基准电压输入)
6位(AIN_BUFP):1 (缓冲所选正模拟输入引脚)
5位(AIN_BUFM):1 (缓冲所选负模拟输入引脚)
4:3位(REF_SEL):10 (选择内部基准电压源)
2:0位(PGA):0 0 0 (增益为0)
综上
CONFIG_0 | 15 | 14 | 13 | 12 | 11 | 10 | 9 | 8 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 1 | 1 | 1 | 1 | 0 | 0 | 0 | 0 |
CONFIG_0 = 0x01F0
4.配置滤波器寄存器
在滤波器寄存器中可以设置滤波器类型和输出字速率
23:21位(Filter):0 0 0 (sin4滤波器)
20为(REJ60):0 (在中国过滤50HZ就够了)
19:17位(POST_FILTER):0 0 0 (保留)
16位(SINGLE_CYCLE):0 (无需单周期转换使能)
15:11位(0):0 0 0 0 (置0正常工作)
10:0为(FS):1 0 0 1 1 (十进制19 输出数据速率大概为1kHZ)
注输出数据速率计算公式:
综上
CONFIG_0 | 23 | 22 | 21 | 20 | 19 | 18 | 17 | 16 | 15 | 14 | 13 | 12 |
0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | |
11 | 10 | 9 | 8 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 | |
0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 0 | 1 | 1 |
CONFIG_0 = 0x000013
5.配置灵活性
16种通道配置,8种配置配置和滤波器配置。
二、STM32CubeMX配置
使用硬件SPI,CS引脚配置成输出模式即可。
三、代码编写
主要基于是基于AD7124的写寄存器和读寄存器开展。各种宏定义见文末Ad7124.h文件。
1.AD7124复位
/**
* @brief AD7124复位 连续写入64个1
* @param 无
* @retval 无
*/
void AD7124_Reset(void)
{
uint8_t pData[8] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};
AD7124_CS_LOW
HAL_SPI_Transmit(&AD7124_SPI, pData, 8, AD7124_SPI_TIMEOUT);
AD7124_CS_HIGHT
}
2.AD7124写寄存器函数
/**
* @brief AD7124写寄存器
* @param 传感器地址
* @param 写入长度
* @param 写入数组地址
* @retval 成功返回0 其他失败
*/
HAL_StatusTypeDef AD7124_Write_Register(uint8_t addr, uint8_t *data, uint16_t data_size)
{
uint8_t pData[data_size + 1];
uint8_t ret;
pData[0] = AD7124_COMM_REG_WEN | AD7124_COMM_REG_WR | AD7124_COMM_REG_RA(addr);
for (uint16_t i = 1; i <= data_size; i++) {
pData[i] = data[i - 1];
}
AD7124_CS_LOW
ret = HAL_SPI_Transmit(&AD7124_SPI, pData, (data_size + 1), AD7124_SPI_TIMEOUT);
AD7124_CS_HIGHT
return ret;
}
3.AD7124读寄存器函数
/**
* @brief AD7124读寄存器
* @param 传感器地址
* @param 读取长度
* @param 存储数组地址
* @retval 成功返回0 其他失败
*/
HAL_StatusTypeDef AD7124_Read_Register(uint8_t addr, uint8_t *data, uint16_t data_size)
{
uint8_t pData = AD7124_COMM_REG_WEN | AD7124_COMM_REG_RD | AD7124_COMM_REG_RA(addr);
uint8_t ret;
AD7124_CS_LOW
ret = HAL_SPI_Transmit(&AD7124_SPI, &pData, 1, AD7124_SPI_TIMEOUT);
ret = HAL_SPI_Receive(&AD7124_SPI, data, data_size, AD7124_SPI_TIMEOUT);
AD7124_CS_HIGHT
return ret;
}
4.配置ADC控制寄存器、通道寄存器和滤波器寄存器
在AD7124初始化函数统一配置,实测在写入寄存器前后添加延时,不然会写入失败。
/**
* @brief AD7124初始化
* @param 无
* @retval 无
*/
void Ad7124_Init(void)
{
uint8_t pData[3];
pData[0] = (uint8_t)(0x7C1 >> 8);
pData[1] = (uint8_t)0x7C1;
AD7124_Reset(); // ADC复位
HAL_Delay(AD7124_DELAY_TIME);
AD7124_Write_Register(AD7124_ADC_CTRL_REG, pData, 2); // 配置ADC控制寄存器
HAL_Delay(AD7124_DELAY_TIME);
pData[0] = (uint8_t)(0x8001 >> 8);
pData[1] = (uint8_t)0x8001;
AD7124_Write_Register(AD7124_CH1_MAP_REG, pData, 2); // 配置通道寄存器
HAL_Delay(AD7124_DELAY_TIME);
pData[0] = (uint8_t)(0x01F0 >> 8);
pData[1] = (uint8_t)0x01F0;
AD7124_Write_Register(AD7124_CFG0_REG, pData, 2); // 配置配置寄存器
HAL_Delay(AD7124_DELAY_TIME);
pData[0] = (uint8_t)(0x000013 >> 16);
pData[1] = (uint8_t)(0x000013 >> 8);
pData[2] = (uint8_t)(0x000013);
AD7124_Write_Register(AD7124_FILT0_REG, pData, 3); // 配置滤波器寄存器
HAL_Delay(AD7124_DELAY_TIME);
}
5.读取ADC值
直接读取ADC寄存器数据值,将读取到的值重新合并即可获取ADC电压值。
/**
* @brief AD7124读取ADC值
* @param 无
* @retval 无
*/
void Ad7124_Read_Adc(void)
{
uint8_t rData[3];
uint32_t rData32;
float ADC_Data;
AD7124_Read_Register(AD7124_DATA_REG, rData, 3);
rData32 = (rData[0] << 16) | (rData[1] << 8) | rData[2];
ADC_Data = (rData32 * 2.5) / 16777215;
printf("%f\r\n", ADC_Data);
}
ADC电压值转换关系
四、效果
测量1.67V电压效果如下
附录(Ad7124.h文件)
#ifndef __AD7124_H__
#define __AD7124_H__
/* AD7124 Register Map */
#define AD7124_COMM_REG 0x00
#define AD7124_STATUS_REG 0x00
#define AD7124_ADC_CTRL_REG 0x01
#define AD7124_DATA_REG 0x02
#define AD7124_IO_CTRL1_REG 0x03
#define AD7124_IO_CTRL2_REG 0x04
#define AD7124_ID_REG 0x05
#define AD7124_ERR_REG 0x06
#define AD7124_ERREN_REG 0x07
#define AD7124_CH0_MAP_REG 0x09
#define AD7124_CH1_MAP_REG 0x0A
#define AD7124_CH2_MAP_REG 0x0B
#define AD7124_CH3_MAP_REG 0x0C
#define AD7124_CH4_MAP_REG 0x0D
#define AD7124_CH5_MAP_REG 0x0E
#define AD7124_CH6_MAP_REG 0x0F
#define AD7124_CH7_MAP_REG 0x10
#define AD7124_CH8_MAP_REG 0x11
#define AD7124_CH9_MAP_REG 0x12
#define AD7124_CH10_MAP_REG 0x13
#define AD7124_CH11_MAP_REG 0x14
#define AD7124_CH12_MAP_REG 0x15
#define AD7124_CH13_MAP_REG 0x16
#define AD7124_CH14_MAP_REG 0x17
#define AD7124_CH15_MAP_REG 0x18
#define AD7124_CFG0_REG 0x19
#define AD7124_CFG1_REG 0x1A
#define AD7124_CFG2_REG 0x1B
#define AD7124_CFG3_REG 0x1C
#define AD7124_CFG4_REG 0x1D
#define AD7124_CFG5_REG 0x1E
#define AD7124_CFG6_REG 0x1F
#define AD7124_CFG7_REG 0x20
#define AD7124_FILT0_REG 0x21
#define AD7124_FILT1_REG 0x22
#define AD7124_FILT2_REG 0x23
#define AD7124_FILT3_REG 0x24
#define AD7124_FILT4_REG 0x25
#define AD7124_FILT5_REG 0x26
#define AD7124_FILT6_REG 0x27
#define AD7124_FILT7_REG 0x28
#define AD7124_OFFS0_REG 0x29
#define AD7124_OFFS1_REG 0x2A
#define AD7124_OFFS2_REG 0x2B
#define AD7124_OFFS3_REG 0x2C
#define AD7124_OFFS4_REG 0x2D
#define AD7124_OFFS5_REG 0x2E
#define AD7124_OFFS6_REG 0x2F
#define AD7124_OFFS7_REG 0x30
#define AD7124_GAIN0_REG 0x31
#define AD7124_GAIN1_REG 0x32
#define AD7124_GAIN2_REG 0x33
#define AD7124_GAIN3_REG 0x34
#define AD7124_GAIN4_REG 0x35
#define AD7124_GAIN5_REG 0x36
#define AD7124_GAIN6_REG 0x37
#define AD7124_GAIN7_REG 0x38
#define AD7124_REGISTER_NUM 57
/* Communication Register bits */
#define AD7124_COMM_REG_WEN (0 << 7)
#define AD7124_COMM_REG_WR (0 << 6)
#define AD7124_COMM_REG_RD (1 << 6)
#define AD7124_COMM_REG_RA(x) ((x) & 0x3F)
#define AD7124_SPI_TIMEOUT 10
#define AD7124_DELAY_TIME 200
#define AD7124_CS_GPIO GPIOB
#define AD7124_CS_PIN GPIO_PIN_12
#define AD7124_SPI hspi2
#define AD7124_CS_LOW HAL_GPIO_WritePin(AD7124_CS_GPIO, AD7124_CS_PIN, GPIO_PIN_RESET);
#define AD7124_CS_HIGHT HAL_GPIO_WritePin(AD7124_CS_GPIO, AD7124_CS_PIN, GPIO_PIN_SET);
void AD7124_Reset(void);
HAL_StatusTypeDef AD7124_Read_Register(uint8_t addr, uint8_t *data, uint16_t data_size);
HAL_StatusTypeDef AD7124_Write_Register(uint8_t addr, uint8_t *data, uint16_t data_size);
#endif /* __AD7124_H__ */