[STM32U0] 【STM32U083测评】ADC使用

[复制链接]
3775|8
 楼主| meiyaolei 发表于 2024-4-27 09:51 | 显示全部楼层 |阅读模式
使用STM32U083的ADC下面是我例的步骤,下面是一个简化的STM32U083 ADC使用步骤概述:
  • 时钟设置
    • 首先,需要配置和使能ADC的时钟源。通常涉及选择一个合适的时钟源,主时钟源或外部时钟源,不过我看了一下板载上是没有连接,改内部时钟。
    • 配置ADC时钟分频器,确保时钟频率满足ADC的工作要求。
    • 使能ADC的时钟。
  • ADC基本配置
    • 选择合适ADC模式。STM32U083支持单次转换模式和连续转换模式。单次转换模式适用于只需要一次转换的应用场景,而连续转换模式适用于需要连续监视信号的应用,个人理解的。
    • 设置采样时间。采样时间的选择取决于输入信号的特性和所需的采样速率。较长的采样时间通常可以提高精度,但会降低转换速度。
    • 配置ADC的分辨率。STM32U083的ADC通常支持多种分辨率设置,8位、10位或12位。较高的分辨率会增加转换精度,但可能也会增加转换时间。
  • 通道选择
    • 在进行ADC转换之前,需要选择要转换的ADC通道。通常涉及到将特定GPIO(通用输入输出)引脚配置为模拟输入,我这里是ADC1。
  • 触发源设置
    • 根据需要通过外部触发源或软件触发来启动ADC转换。外部触发源可以是定时器、外部中断等,而软件触发则是通过编程控制ADC的启动,我这略过。
  • 开始转换并读取结果
    • 启动ADC转换。这可以通过软件命令或外部触发来完成。
    • 等待转换完成。这通常涉及到检查ADC的状态位,以确定转换是否完成。
    • 读取转换结果。一旦转换完成,就可以从ADC的寄存器中读取转换后的数字值。
    • 我好像还有一个停止转换,好像没用上,下面开始进行。
先上图:
在MX里面ADC的配置:
39877662c561911d90.png
KEIL平台重要代码截图:
7160662c56570d375.png

代码:
  1. while (1)  
  2. {  
  3.   // 定义一个8位无符号整数变量i,但在当前代码段中,变量i并未被使用  
  4.   uint8_t i;  
  5.   
  6.   /*## Step 1: ADC过采样初始设置  ##########*/  
  7.   
  8.   /* 开始ADC的正则组转换 */  
  9.   // 启动hadc1这个ADC句柄所代表的ADC转换  
  10.   if (HAL_ADC_Start(&hadc1) != HAL_OK)  
  11.   {  
  12.     /* ADC转换启动错误 */  
  13.     // 如果启动ADC转换失败,则调用错误处理函数  
  14.     Error_Handler();  
  15.   }  
  16.   
  17.   /* 等待ADC转换完成 */  
  18.   // 等待hadc1这个ADC句柄所代表的ADC转换完成,超时时间为10ms  
  19.   if (HAL_ADC_PollForConversion(&hadc1, 10) != HAL_OK)  
  20.   {  
  21.     /* 转换完成标志未按时设置 */  
  22.     // 如果在10ms内没有检测到转换完成标志,则调用错误处理函数  
  23.     Error_Handler();  
  24.   }  
  25.   
  26.   /* 检索ADC转换数据 */  
  27.   // 检索hadc1这个ADC句柄所代表的ADC的转换结果  
  28.   // (使用过采样比率16和右移4位来缩放数据,相当于ADC分辨率为:12位)  
  29.   // 变量uhADCxConvertedData_OVS_ratio16_shift4存储了ADC的转换结果  
  30.   uhADCxConvertedData_OVS_ratio16_shift4 = HAL_ADC_GetValue(&hadc1);  
  31.   
  32.   // 注意:代码段中并没有显示uhADCxConvertedData_OVS_ratio16_shift4的声明和定义,  
  33.   // 假定它在其他地方已经被定义为一个合适的变量来存储ADC转换结果。  
  34.   
  35.   // 此while循环没有终止条件,将无限循环执行ADC的转换和读取操作。  
  36.   // 在实际应用中,可能需要根据具体需求添加其他逻辑或条件来跳出循环。  
  37. }
下面给一个将ADC的值转成电压的代码示例:
  1. #include "stm32u0xx_hal.h"  
  2.   
  3. ADC_HandleTypeDef hadc1;  
  4.   
  5. // ADC参考电压,通常这取决于你的微控制器供电电压和ADC的配置  
  6. #define ADC_VREF    3.3f // 单位:伏特  
  7.   
  8. // 假设ADC是12位的  
  9. #define ADC_BITS    12  
  10.   
  11. // 计算ADC的最大值  
  12. #define ADC_MAX_VALUE ((1 << ADC_BITS) - 1)  
  13.   
  14. // ADC通道配置  
  15. void MX_ADC1_Init(void)  
  16. {  
  17.     ADC_ChannelConfTypeDef sConfig = {0};  
  18.   
  19.     /**Configure the global features of the ADC (Clock, Resolution, Data Alignment and number of conversion) */  
  20.     hadc1.Instance = ADC1;  
  21.     hadc1.Init.ClockPrescaler = ADC_CLOCK_SYNC_PCLK_DIV4; // 设置ADC时钟分频  
  22.     hadc1.Init.Resolution = ADC_RESOLUTION_12B; // 设置ADC分辨率为12位  
  23.     hadc1.Init.ScanConvMode = DISABLE; // 禁止扫描模式  
  24.     hadc1.Init.ContinuousConvMode = ENABLE; // 使能连续转换模式  
  25.     hadc1.Init.DiscontinuousConvMode = DISABLE; // 禁止不连续转换模式  
  26.     hadc1.Init.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_NONE; // 禁用外部触发  
  27.     hadc1.Init.ExternalTrigConv = ADC_SOFTWARE_START; // 软件启动转换  
  28.     hadc1.Init.DataAlign = ADC_DATAALIGN_RIGHT; // 右对齐  
  29.     hadc1.Init.NbrOfConversion = 1; // 设置规则序列中转换的数量  
  30.     hadc1.Init.DMAContinuousRequests = DISABLE; // 禁止DMA连续请求  
  31.     hadc1.Init.EOCSelection = ADC_EOC_SEQ_CONV; // 设置EOC选择  
  32.   
  33.     if (HAL_ADC_Init(&hadc1) != HAL_OK)  
  34.     {  
  35.         // 初始化错误处理  
  36.         Error_Handler();  
  37.     }  
  38.   
  39.     /**Configure for the selected ADC regular channel its corresponding rank in the sequencer and its sample time. */  
  40.     sConfig.Channel = ADC_CHANNEL_0; // 假设我们使用ADC通道0  
  41.     sConfig.Rank = 1;  
  42.     sConfig.SamplingTime = ADC_SAMPLETIME_55CYCLES_5; // 设置采样时间  
  43.   
  44.     if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK)  
  45.     {  
  46.         // 通道配置错误处理  
  47.         Error_Handler();  
  48.     }  
  49. }  
  50.   
  51. // ADC值转换为电压的函数  
  52. float ADC_Value_To_Voltage(uint32_t adc_value)  
  53. {  
  54.     float voltage_step = ADC_VREF / (float)ADC_MAX_VALUE; // 每个ADC值的电压增量  
  55.     float voltage = adc_value * voltage_step; // 计算电压  
  56.     return voltage;  
  57. }  
  58.   
  59. int main(void)  
  60. {  
  61.     HAL_Init(); // 初始化HAL库  
  62.     SystemClock_Config(); // 配置系统时钟,这个函数需要你自己根据硬件手册实现  
  63.   
  64.     MX_ADC1_Init(); // 初始化ADC  
  65.   
  66.     while (1)  
  67.     {  
  68.         HAL_ADC_Start(&hadc1); // 开始ADC转换  
  69.   
  70.         // 等待转换完成,你可以使用轮询或者中断的方式  
  71.         HAL_ADC_PollForConversion(&hadc1, 1000); // 等待1000ms超时  
  72.   
  73.         uint32_t adc_value = HAL_ADC_GetValue(&hadc1); // 读取ADC转换结果  
  74.   
  75.         float voltage = ADC_Value_To_Voltage(adc_value); // 将ADC值转换为电压  
  76.   
  77.         // 在这里你可以使用转换后的电压值,比如通过串口打印出来  
  78.         // ...  
  79.   
  80.         HAL_Delay(1000); // 延时1秒,然后再次读取ADC值  
  81.     }  
  82. }



magry385 发表于 2024-5-2 14:33 | 显示全部楼层
这个芯片功能非常强大
咕咕呱呱孤寡 发表于 2024-5-13 09:18 | 显示全部楼层
ADC 的转换精度是多少
15625004279 发表于 2024-6-1 10:54 | 显示全部楼层
ADC采集精度是自己配置吗
Innercourage 发表于 2024-6-22 15:58 | 显示全部楼层
ADC 的转换确实用的多,功能强大,很不错
LOVEEVER 发表于 2024-6-28 18:02 | 显示全部楼层
ADC是不是直接调用HAL库函数进行数据读取?
kepe 发表于 2024-7-31 00:51 | 显示全部楼层
在STM32U083上,ADC的时钟源可以是系统时钟的一部分,通常需要配置ADC的时钟分频器。
gaonaiweng 发表于 2024-8-29 12:25 | 显示全部楼层
在实际应用中,可能需要对 ADC 进行校准以提高测量准确性。校准通常在启动前或每次重大环境变化后进行。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

认证:工程师
简介:超越自我,为设计激发灵感和想象。

263

主题

836

帖子

6

粉丝
快速回复 在线客服 返回列表 返回顶部