当前位置: 首页 > news >正文

炸鸡派例程-ADC

main

int main(void)
{HAL_Init();SystemClock_Config();MX_GPIO_Init();MX_DMA_Init();MX_USART1_UART_Init();/*ADC初始化*/MX_ADC1_Init();HAL_UART_Receive_DMA(&huart1, RXbuf, 50);__HAL_UART_ENABLE_IT(&huart1, UART_IT_IDLE);while (1){printf("V:%.2f \r\n", VoltageCheck());HAL_Delay(500);}
}

ADC初始化

void MX_ADC1_Init(void)
{ADC_ChannelConfTypeDef sConfig = {0};hadc1.Instance = ADC1;  // 指定 ADC 实例为 ADC1hadc1.Init.ClockPrescaler = ADC_CLOCK_SYNC_PCLK_DIV4;  // ADC 时钟为 PCLK/4hadc1.Init.Resolution = ADC_RESOLUTION_12B;  // 设置分辨率为 12 位hadc1.Init.ScanConvMode = DISABLE;  // 禁用扫描模式hadc1.Init.ContinuousConvMode = DISABLE;  // 禁用连续转换模式,使用单次转换hadc1.Init.DiscontinuousConvMode = DISABLE;  // 禁用不连续转换模式hadc1.Init.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_NONE;  // 不使用外部触发,由软件启动转换hadc1.Init.ExternalTrigConv = ADC_SOFTWARE_START;  // 转换由软件触发hadc1.Init.DataAlign = ADC_DATAALIGN_RIGHT;  // 数据右对齐hadc1.Init.NbrOfConversion = 1;  // 转换序列中只有一个通道hadc1.Init.DMAContinuousRequests = DISABLE;  // 禁用 DMA 连续请求hadc1.Init.EOCSelection = ADC_EOC_SINGLE_CONV;  // EOC 信号在单次转换完成后产生if (HAL_ADC_Init(&hadc1) != HAL_OK) //这里调用了MSP_Init{Error_Handler();}sConfig.Channel = ADC_CHANNEL_1;       // 选择通道1(PA1)作为输入sConfig.Rank = 1;                      // 设置通道在转换序列中的优先级为第1位sConfig.SamplingTime = ADC_SAMPLETIME_3CYCLES;  // 设置采样时间为3个时钟周期if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK){Error_Handler();}
}

ADC相关参数解释

时钟分频因子

        ADC时钟分频因子:

hadc1.Init.ClockPrescaler = ADC_CLOCK_SYNC_PCLK_DIV4;

         PCLK是APB2总线的时钟。

分辨率

hadc1.Init.Resolution = ADC_RESOLUTION_12B;  // 设置分辨率为 12 位

        ADC的输出数据为12位,即可以分辨4096个不同的电压等级。

扫描模式

hadc1.Init.ScanConvMode = DISABLE;  // 禁用扫描模式

        禁用扫描模式意味着ADC不会自动依次转换多个通道,而是只转换指定的单个通道。

        在扫描模式下,ADC可以按照预设的顺序依次对多个通道进行采样。适合需要同时采集多个信号的应用场景。

不连续转换模式

hadc1.Init.DiscontinuousConvMode = DISABLE;  // 禁用不连续转换模式

        不连续转换模式用于扫描模式下,每次转换后暂停一段时间。这里禁用该模式。

连续转换模式

hadc1.Init.ContinuousConvMode = DISABLE;  // 禁用连续转换模式,使用单次转换

        禁用连续转换模式表示ADC只进行一次转换,然后停止。每次需要转换时,必须手动启动。

设置外部触发转换的边沿

hadc1.Init.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_NONE;  // 不使用外部触发,由软件启动转换

        通过调用ADC启动函数(如HAL_ADC_Start())或直接写寄存器来启动ADC转换。

        其他触发方式包括上升沿、下降沿、双边沿触发,检测到对应信号自动触发ADC转换。

设置外部触发源

hadc1.Init.ExternalTrigConv = ADC_SOFTWARE_START;  // 转换由软件触发

        转换由软件通过编程启动,而不是由外部信号触发。

        外部信号触发一般是通过定时器的输出比较事件来触发。

        定时器的输出比较事件作为ADC的触发源的配置示例: 

// 配置定时器1,每10ms触发一次ADC采样
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
TIM_TimeBaseStructure.TIM_Period = 999; // 自动重装载值
TIM_TimeBaseStructure.TIM_Prescaler = 999; // 预分频值
TIM_TimeBaseStructure.TIM_ClockDivision = 0;
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
TIM_TimeBaseInit(TIM1, &TIM_TimeBaseStructure);TIM_OCInitTypeDef TIM_OCInitStructure;
TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;
TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
TIM_OCInitStructure.TIM_Pulse = 999; // 比较值
TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;
TIM_OC1Init(TIM1, &TIM_OCInitStructure);
TIM_OC1PreloadConfig(TIM1, TIM_OCPreload_Enable);// 配置ADC外部触发源为定时器1通道1比较匹配事件
ADC_ExternalTrigConvConfig(ADC1, ADC_ExternalTrigConv_T1_TRGO);// 启动定时器
TIM_Cmd(TIM1, ENABLE);

ADC数据对齐方式

hadc1.Init.DataAlign = ADC_DATAALIGN_RIGHT;  // 数据右对齐

        右对齐则高位补零。

转换序列中的通道数量

hadc1.Init.NbrOfConversion = 1;  // 转换序列中只有一个通道

        采样序列是指ADC在一次完整的采样过程中,按照预先设定的顺序依次对多个通道进行采样的过程。包括:

        通道数量(NbrOfConversion)

        通道顺序(Rank)

        采样时间(SamplingTime)

DMA连续请求

hadc1.Init.DMAContinuousRequests = DISABLE;  // 禁用 DMA 连续请求

        禁用DMA连续请求,表示不会自动触发DMA传输。

转换结束(EOC)信号的触发方式

hadc1.Init.EOCSelection = ADC_EOC_SINGLE_CONV;  // EOC 信号在单次转换完成后产生

         使用 ADC_EOC_SINGLE_CONV,每次采样完成后都会生成一个 EOC 信号。

         使用 ADC_EOC_SEQ_CONV,只有在序列都采样完成后才会生成一个 EOC 信号

        中断:当EOC信号被设置时,可以触发一个中断服务例程(ISR),处理器可以在ISR中读取ADC转换结果并进行进一步处理。

        DMA:EOC信号可以触发DMA传输,将ADC转换结果自动传输到内存中,从而减少处理器的负担,提高系统的效率。

        在STM32中,当ADC完成一次转换后,EOC信号会被设置,处理器可以通过检查EOC标志来判断是否可以读取转换结果。

通道配置

        ADC通道。

        通道在转换序列中的优先级。

        采样时间。这里给的3个时钟周期。

设置多个通道的采样优先级的例子

ADC_MspInit

/*MCU板级支持,硬件初始化*/
void HAL_ADC_MspInit(ADC_HandleTypeDef* adcHandle)
{GPIO_InitTypeDef GPIO_InitStruct = {0};if(adcHandle->Instance==ADC1){__HAL_RCC_ADC1_CLK_ENABLE();__HAL_RCC_GPIOA_CLK_ENABLE();GPIO_InitStruct.Pin = GPIO_PIN_1;GPIO_InitStruct.Mode = GPIO_MODE_ANALOG; //GPIO配置模拟模式GPIO_InitStruct.Pull = GPIO_NOPULL;//禁用上拉或下拉确保信号源的电压直接传递到ADC输入引脚HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);}
}
void HAL_ADC_MspDeInit(ADC_HandleTypeDef* adcHandle)
{if(adcHandle->Instance==ADC1){__HAL_RCC_ADC1_CLK_DISABLE();HAL_GPIO_DeInit(GPIOA, GPIO_PIN_1);}
}

获取ADC转换结果

        例程用的是while中轮询。

float VoltageCheck()
{uint16_t dat;       // 用于存储ADC转换结果float Voltage;      // 用于存储计算后的电压值// 启动ADC转换HAL_ADC_Start(&hadc1);// 等待ADC转换完成,超时时间设置为5msHAL_ADC_PollForConversion(&hadc1, 5);// 获取ADC转换结果dat = HAL_ADC_GetValue(&hadc1);// 停止ADCHAL_ADC_Stop(&hadc1);// 将ADC值转换为电压值// 假设参考电压为3.3V,12位ADC的满量程为4096Voltage = dat * 3.3f / 4096.0f;return Voltage;     // 返回计算后的电压值
}

        这里也可以通过中断来自动获取结果,

1. 配置 ADC 为中断模式
HAL_ADC_Start_IT(&hadc1); // 启动 ADC 转换(中断模式)
2. 注册中断服务例程(ISR)
void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef* hadc)
{if (hadc->Instance == ADC1){uint32_t adcValue = HAL_ADC_GetValue(hadc); // 获取 ADC 转换结果float voltage = adcValue * 3.3f / 4096.0f;  // 转换为电压值// 在这里处理电压值// 例如,可以将电压值存储到全局变量中,或者触发其他操作}
}

        HAL_ADC_IRQHandler 函数会检查EOC标志位,并在确认转换完成后调用         HAL_ADC_ConvCpltCallback 回调函数。

http://www.dtcms.com/a/267191.html

相关文章:

  • RabbitMQ 4.1.1初体验-队列和交换机
  • 【AI论文】WorldVLA:迈向自回归动作世界模型
  • 第二章 简单程序设计
  • 盘式制动器的设计+说明书和CAD)【6张】+绛重
  • 一种结合双阶段注意力循环神经网络(DA-RNN)和卷积块注意力模块(CBAM)的滚动轴承故障诊断方法
  • Rust实用案例解析
  • 后端树形结构
  • Qt处理USB摄像头开发说明与QtMultimedia与V4L2融合应用
  • 【爬虫】逆向爬虫初体验之爬取音乐
  • 408第三季part2 - 计算机网络 - 物理层
  • 由coalesce(1)OOM引发的coalesce和repartition理解
  • 3dmax一键烘焙很多张贴图合并成一张贴图插件支持fbx/obj/blender多材质模型合并为一张贴图
  • OneCode自主UI设计体系:架构解析与核心实现
  • web前端面试-- MVC、MVP、MVVM 架构模式对比
  • Vue.js TDD开发深度指南:工具链配置与精细化测试策略
  • 爬虫工程师Chrome开发者工具简单介绍
  • Kafka消息积压的多维度解决方案:超越简单扩容的完整策略
  • 牛客刷题 — 【排序】[NOIP2010] 导弹拦截(排序枚举)
  • 光伏发电园区管理系统 - Three.js + Django 实现方案
  • React Hooks全面解析:从基础到高级的实用指南
  • 【论文解读】Referring Camouflaged Object Detection
  • SqueezeBERT:计算机视觉能为自然语言处理在高效神经网络方面带来哪些启示?
  • 7月5日星期六今日早报简报微语报早读
  • 在服务器上配置MQ注意的问题
  • Gartner《Stream Processing: 新一代数据处理范式》学习报告
  • Flink-状态恢复-isRestore分析
  • 使用影刀RPA实现每日消防巡检提醒
  • 常见高危端口风险分析与防护指南
  • PostgreSQL表操作
  • Python Fabric库【系统管理工具】全面讲解