学习记录:STM32G431CBU6的单通道ADC采样串口打印(HAL库)
一 连接
本文使用STM32G431CBU6 级联三片74HC595芯片 级联两片SN74LV4051芯片,
STM32连接595芯片的4个引脚:STCP SHCP DS OE
STM32连接4051芯片的COM引脚
4051芯片的INH引脚和A B C 引脚和595芯片连接
二 原理
STM32通过SPI协议控制595芯片,595芯片控制4051的信号,4051芯片和STM32开启ADC通道开启ADC转换。本文控制其中一条通道进行ADC转换。
三 配置
stm32cubemx配置如下:
SPI配置:
因为选择的模式Mode是Tramsmit Only Master,所以依旧要选择两个GPIO口连接STCP(PB12)和OE(PB14)
ADC配置:
选择ADC2_IN3
串口配置:
时钟树配置:
四 代码
void ShiftOut(uint32_t data) {
HAL_GPIO_WritePin(GPIOB, GPIO_PIN_12, GPIO_PIN_RESET); // 拉低RCLK
HAL_SPI_Transmit(&hspi2, (uint8_t *)&data, 3, 2000);//三片595芯片级联
HAL_GPIO_WritePin(GPIOB, GPIO_PIN_12, GPIO_PIN_SET);// 拉高RCLK,锁存数据
Delay_ms(50);
}
int main(void)
{
/* USER CODE BEGIN 1 */
/* USER CODE END 1 */
/* MCU Configuration--------------------------------------------------------*/
/* Reset of all peripherals, Initializes the Flash interface and the Systick. */
HAL_Init();
/* USER CODE BEGIN Init */
/* USER CODE END Init */
/* Configure the system clock */
SystemClock_Config();
/* USER CODE BEGIN SysInit */
/* USER CODE END SysInit */
/* Initialize all configured peripherals */
MX_GPIO_Init();
MX_SPI2_Init();
MX_ADC2_Init();
MX_USART1_UART_Init();
/* USER CODE BEGIN 2 */
/* USER CODE END 2 */
/* Infinite loop */
/* USER CODE BEGIN WHILE */
while (1)
{
/* USER CODE END WHILE */
/* USER CODE BEGIN 3 */
HAL_GPIO_WritePin(GPIOC, GPIO_PIN_15, GPIO_PIN_SET);//GPIO_PIN_RESET
Delay_ms(200);
HAL_GPIO_WritePin(GPIOC, GPIO_PIN_15, GPIO_PIN_RESET);//GPIO_PIN_SET
//运行灯闪烁
ShiftOut(0x080000); // 设置通道,我这级联三片595芯片
// 启动ADC转换
HAL_ADCEx_Calibration_Start(&hadc2,ADC_SINGLE_ENDED);//校准
HAL_ADC_Start(&hadc2);
// 等待转换完成
HAL_ADC_PollForConversion(&hadc2, 100);
// 读取ADC
uint32_t adcValue = HAL_ADC_GetValue(&hadc2); // 读取ADC
Delay_ms(50); // 延时
float voltage = adcValue / 4095.0 * 3.3 ; // 转换为电压
// 通过 UART 打印 ADC 值和电压
char msg[200];
snprintf(msg, sizeof(msg), "ADC: %ld, Voltage: %.2lf V\r\n", adcValue, voltage);
HAL_UART_Transmit(&huart1, (uint8_t*)msg, strlen(msg), 1000);
}
/* USER CODE END 3 */
}
注意:
1.打印出来如果一直是ADC:4095,通常是采样频率问题,可以尝试修改ADC的时钟树部分
2.如果打印出来的值是和实际电压有误差,一个是考虑时钟树问题,另一个是考虑ADC校准
作者:纹朷