一、题目
ADC采集(使用 PA0 引脚),采集电压信号,采样率可控,通过串口发送至串口助手上,同时显示到 OLED 上。
二、基础知识
1. 逐次逼近法
二分比较确定电压值
分辨率:12 位 ADC
2. 定时器
3. 使用 DMA
预分频器:设置为 N - 1,则可进行 N 分频
自动重装载寄存器:如果想定时 m 个脉冲,就设置自动重装载寄存器为 m - 1
4. 如何控制采样率?
让 ADC 以定时器(TIM3)触发作为采样时钟,在按键回调中修改定时器的频率(Period/Prescaler),从而改变 ADC 的触发频率。具体的内容在本文中没有实现,将 GPT 回答的内容附在文末。
三、CubeMX 配置
-
RCC: 将高速外部时钟源设置为晶振

-
SYS:设置串口 debug

-
NVIC: 不用设置
-
ADC1: 设置定时器 3 触发,设置 DMA


-
TIM3: 设置内部时钟,自动重装载,预分频,ARR, 事件触发

-
USART2:输出 ADC 测量结果。

-
I2C2:

-
时钟设置:ADC1、ADC2 都依靠 APB2 的时钟线,频率不宜太快,在 F103 上不超过 14MHz。将 ADC 专用分频器改为 / 6,即将 ADC 频率改为 12MHz。

四、代码编写:
- 串口重定向:usart.c
/* USER CODE BEGIN 1 */
int fputc(int ch,FILE *f){
// 串口重定向
HAL_UART_Transmit(&huart2, (uint8_t*)&ch, 1, 0xffff);
return ch;
}
int fgetc(FILE *f){
uint8_t ch = 0;
HAL_UART_Receive(&huart2, &ch, 1, 0xffff);
return ch;
}
/* USER CODE END 1 */
- 修改 ADC 转换完成标志:stm32f1xx_it.c
/* USER CODE BEGIN PV */
extern uint8_t adcConvEnd; // 引入外部变量
/* USER CODE END PV */
/**
* @brief This function handles DMA1 channel1 global interrupt.
*/
void DMA1_Channel1_IRQHandler(void)
{
/* USER CODE BEGIN DMA1_Channel1_IRQn 0 */
/* USER CODE END DMA1_Channel1_IRQn 0 */
HAL_DMA_IRQHandler(&hdma_adc1);
/* USER CODE BEGIN DMA1_Channel1_IRQn 1 */
adcConvEnd = 1; // 触发 DMA 中断,告诉 CPU 采集完毕,程序根据该变量的变化得知采集完毕
// HAL_ADC_Start_DMA(&hadc1, adc_buff, 2

最低0.47元/天 解锁文章
1万+

被折叠的 条评论
为什么被折叠?



