基于STM32驱动ADS1118实现电压采样并输出到串口
基于STM32驱动ADS1118实现电压采样并输出到串口
一、硬件连接方案
1. 引脚连接(以STM32F103为例)
STM32引脚 | ADS1118引脚 | 功能说明 |
---|---|---|
PA4(SPI1_NSS) | CS | 片选信号(低电平有效) |
PA5(SPI1_SCK) | SCK | 时钟信号 |
PA6(SPI1_MISO) | DOUT | 数据输出 |
PA7(SPI1_MOSI) | DIN | 数据输入 |
3.3V | VDD | 电源供电 |
GND | GND | 地线 |
2. 电路设计要点
- 电源滤波:在VDD和GND间添加10μF电解电容+0.1μF陶瓷电容
- 信号完整性:
- SPI线使用22Ω电阻串联(SCK/DIN/DOUT)
- CS线添加49.9Ω上拉电阻
- 参考电压:使用内部1.25V参考(配置寄存器设置)
二、软件实现(HAL库+标准外设库)
1. SPI初始化(CubeMX配置)
// SPI1配置参数
hspi1.Instance = SPI1;
hspi1.Init.Mode = SPI_MODE_MASTER;
hspi1.Init.Direction = SPI_DIRECTION_2LINES;
hspi1.Init.DataSize = SPI_DATASIZE_8BIT;
hspi1.Init.CLKPolarity = SPI_POLARITY_LOW;
hspi1.Init.CLKPhase = SPI_PHASE_1EDGE;
hspi1.Init.NSS = SPI_NSS_SOFT;
hspi1.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_256; // 125kHz
hspi1.Init.FirstBit = SPI_FIRSTBIT_MSB;
HAL_SPI_Init(&hspi1);
2. ADS1118驱动代码
#define ADS1118_CS_PIN HAL_GPIO_WritePin(GPIOA, GPIO_PIN_4, GPIO_PIN_RESET)
#define ADS1118_CS_RELEASE HAL_GPIO_WritePin(GPIOA, GPIO_PIN_4, GPIO_PIN_SET)// 寄存器地址
#define ADS_CONFIG_REG 0x01
#define ADS_CONVERSION_REG 0x00// 配置值(16位补码格式)
uint8_t config_data[3] = {ADS_CONFIG_REG, // 寄存器地址0x85, // 单次转换+增益1+128SPS0x00 // 保留
};// 初始化ADS1118
void ADS1118_Init() {ADS1118_CS_RELEASE;HAL_Delay(100); // 复位时间HAL_SPI_Transmit(&hspi1, config_data, 3, 1000);ADS1118_CS_RELEASE;
}// 读取转换结果
int16_t ADS1118_Read() {uint8_t rx_data[2] = {0};ADS1118_CS_RELEASE;HAL_SPI_Transmit(&hspi1, (uint8_t*)&ADS_CONVERSION_REG, 1, 1000);HAL_SPI_Receive(&hspi1, rx_data, 2, 1000);ADS1118_CS_RELEASE;return (rx_data[0] << 8) | rx_data[1];
}
3. 电压计算与串口输出
// 电压转换函数
float ADS1118_GetVoltage(int16_t adc_value) {float voltage = (adc_value * 1.25f) / 32768.0f; // 内部参考电压1.25Vreturn voltage * 1000; // 转换为mV
}// 串口打印函数(重定向printf)
int fputc(int ch, FILE *f) {HAL_UART_Transmit(&huart1, (uint8_t*)&ch, 1, HAL_MAX_DELAY);return ch;
}// 主循环
int main(void) {HAL_Init();SystemClock_Config();MX_USART1_UART_Init();MX_SPI1_Init();ADS1118_Init();while(1) {int16_t adc_val = ADS1118_Read();float voltage = ADS1118_GetVoltage(adc_val);printf("ADC: %d, Voltage: %.2f mV\r\n", adc_val, voltage);HAL_Delay(1000);}
}
参考源码 使用STM32驱动ADS1118,电压采样信息打印到串口上 youwenfan.com/contentcsa/70055.html
三、关键调试技巧
1. 波形验证(示波器观察)
- SPI时序:确保SCK在CS拉低后开始,MOSI与SCK同步上升沿
- 数据有效性:DOUT在CS拉低后20μs内变为低电平表示数据就绪
2. 常见问题解决
现象 | 可能原因 | 解决方案 |
---|---|---|
数据全0 | SPI模式不匹配 | 检查CPOL/CPHA设置 |
数据跳变 | 电源噪声干扰 | 添加LC滤波(10μH+100nF) |
通信超时 | 片选信号未正确控制 | 检查CS引脚电平状态 |
电压漂移 | 参考电压不稳定 | 添加外部精密基准源(如REF3030) |
3. 性能优化
-
DMA传输:使用SPI DMA接收减少CPU占用
// DMA配置示例 DMA_HandleTypeDef hdma_spi1_rx; hdma_spi1_rx.Instance = DMA1_Channel2; hdma_spi1_rx.Init.Direction = DMA_PERIPH_TO_MEMORY; hdma_spi1_rx.Init.PeriphInc = DMA_PINC_DISABLE; hdma_spi1_rx.Init.MemInc = DMA_MINC_ENABLE; HAL_DMA_Init(&hdma_spi1_rx); HAL_SPI_Receive_DMA(&hspi1, rx_buffer, 2);
-
中断处理:使用SPI接收中断提升实时性
void SPI1_IRQHandler() {HAL_SPI_IRQHandler(&hspi1);if(__HAL_SPI_GET_FLAG(&hspi1, SPI_FLAG_RXNE)) {uint8_t data = hspi1.Instance->DR;// 处理接收数据} }
四、扩展功能实现
1. 多通道轮询采集
// 多通道配置表(差分输入)
uint8_t channel_config[4] = {0x83, 0xA3, 0xC3, 0xE3}; // AIN0-1, AIN2-3等void ADS1118_MultiChannel() {for(uint8_t i=0; i<4; i++) {HAL_SPI_Transmit(&hspi1, channel_config, 1, 1000);HAL_Delay(10);adc_val[i] = ADS1118_Read();}
}
2. 温度补偿
// 读取芯片温度(需要配置温度寄存器)
float ADS1118_ReadTemperature() {HAL_SPI_Transmit(&hspi1, (uint8_t*)0x02, 1, 1000); // Lo_thresh寄存器HAL_SPI_Transmit(&hspi1, (uint8_t*)0x03, 1, 1000); // Hi_thresh寄存器uint16_t temp_raw = ADS1118_Read();return (temp_raw * 0.03125f) - 256.0f; // 转换为摄氏度
}
五、PCB设计建议
- 电源完整性:
- 采用四层板结构,中间层为完整GND平面
- ADS1118电源引脚添加0.1μF和10μF去耦电容
- 信号完整性:
- SPI线做包地处理(两侧走GND线)
- 关键信号线做等长匹配(长度差<5mil)
- EMC防护:
- 在SPI总线上串联TVS管(SMBJ12A)
- 添加共模电感(10μH)抑制高频噪声
该方案通过SPI接口实现ADS1118的高效驱动,结合串口输出实现实时数据监控。实际应用中需根据具体硬件环境调整滤波参数和时序配置,建议通过示波器验证关键信号波形。