MCP3421与STM32电压采集实现
MCP3421是一款18位高精度Σ-Δ模数转换器(ADC),它通过I2C接口与微控制器通信,能够实现高精度的电压测量。基于STM32和MCP3421的电压采集代码,包含初始化和读取数据的步骤,代码基于STM32的HAL库进行开发。
MCP3421与STM32电压采集实现
MCP3421是一款高精度、低噪声的模数转换器,通过I2C接口与微控制器通信。
硬件连接
MCP3421引脚 | STM32引脚 | 说明 |
---|---|---|
VDD | 3.3V | 电源 |
VSS | GND | 地 |
SDA | I2C_SDA | I2C数据线 |
SCL | I2C_SCL | I2C时钟线 |
Vin+ | 模拟输入正极 | 待测电压正极 |
Vin- | 模拟输入负极 | 待测电压负极 |
软件实现
1. 宏定义和变量声明
#include "main.h"
#include "i2c.h"#define MCP3421_ADDRESS 0xD0 // MCP3421的I2C地址(8位格式),具体地址取决于芯片的地址引脚配置
#define MCP3421_READ_BIT 0x01
#define MCP3421_WRITE_BIT 0x00// MCP3421配置字节
#define MCP3421_START_CONV 0x80 // 开始转换位
#define MCP3421_CHANNEL_0 0x00 // 通道选择位
#define MCP3421_CHANNEL_1 0x20
#define MCP3421_12_BIT 0x00 // 分辨率选择位
#define MCP3421_14_BIT 0x04
#define MCP3421_16_BIT 0x08
#define MCP3421_18_BIT 0x0C
#define MCP3421_GAIN_1 0x00 // 增益选择位
#define MCP3421_GAIN_2 0x01
#define MCP3421_GAIN_4 0x02
#define MCP3421_GAIN_8 0x03uint8_t configReg = 0; // 全局变量存储配置字节
2. MCP3421初始化函数
void MCP3421_Init(void) {// 配置MCP3421为18位分辨率、增益为1、连续转换模式configReg = MCP3421_START_CONV | MCP3421_CHANNEL_0 | MCP3421_18_BIT | MCP3421_GAIN_1;uint8_t configData[2] = {0};configData[0] = configReg;HAL_I2C_Master_Transmit(&hi2c1, MCP3421_ADDRESS, configData, 1, HAL_MAX_DELAY);
}
3. 读取ADC值函数
int32_t MCP3421_ReadADC(void) {uint8_t adcData[4] = {0};int32_t result = 0;// 读取4字节数据(18位数据 + 配置字节)HAL_I2C_Master_Receive(&hi2c1, MCP3421_ADDRESS | MCP3421_READ_BIT, adcData, 4, HAL_MAX_DELAY);// 检查转换是否完成(最高位为0表示转换完成)while (adcData[3] & 0x80) {HAL_Delay(1); // 等待转换完成HAL_I2C_Master_Receive(&hi2c1, MCP3421_ADDRESS | MCP3421_READ_BIT, adcData, 4, HAL_MAX_DELAY);}// 处理18位有符号数据// 数据格式:第1字节高8位,第2字节低8位,第3字节的低2位为最低有效位result = (adcData[0] << 10) | (adcData[1] << 2) | (adcData[2] >> 6);// 处理符号位(18位有符号数)if (result & 0x00020000) {// 如果是负数,进行符号扩展result |= 0xFFFC0000;}return result;
}
4. 将ADC值转换为电压值
float MCP3421_ConvertToVoltage(int32_t adcValue) {// MCP3421在18位模式下的LSB值(增益=1时)// 参考电压默认2.048V,LSB = 2.048V / 2^17 = 15.625μVconst float LSB = 15.625e-6; // 单位:伏特return adcValue * LSB;
}
5. 主循环中的使用示例
int main(void) {HAL_Init();SystemClock_Config();MX_I2C1_Init();MCP3421_Init();while (1) {int32_t adcValue = MCP3421_ReadADC();float voltage = MCP3421_ConvertToVoltage(adcValue);printf("ADC值: %ld, 电压: %.6f V\n", adcValue, voltage);HAL_Delay(1000); // 每秒读取一次}
}
参考代码 mcp34211 stm32 实现电压采集 源代码 www.youwenfan.com/contentcsh/56212.html
关键配置说明
- I2C地址:MCP3421的I2C地址通常为0xD0(8位格式),具体取决于地址引脚的配置。
- 分辨率选择:代码中配置为18位模式(
MCP3421_18_BIT
),可根据需要选择12、14或16位模式。 - 增益设置:增益设置为1(
MCP3421_GAIN_1
),可根据输入信号幅度调整为2、4或8倍增益。 - 数据读取:MCP3421在18位模式下输出24位数据(3字节),我们需要将其转换为18位有符号整数。
- 电压转换:根据数据手册,18位模式下的LSB值为15.625μV(增益=1,参考电压=2.048V)。
调试建议
- 使用逻辑分析仪或示波器检查I2C信号,确保通信正常。
- 注意MCP3421的转换时间,在18位模式下最高精度转换需要约66.67ms。
- 确保电源稳定,噪声会影响高精度ADC的性能。
这个代码提供了MCP3421与STM32通信的基本框架