打印
[STM32U0]

【STM32U083测评】ADC使用

[复制链接]
2961|8
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
使用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的配置:

KEIL平台重要代码截图:


代码:
while (1)  
{  
  // 定义一个8位无符号整数变量i,但在当前代码段中,变量i并未被使用  
  uint8_t i;  
  
  /*## Step 1: ADC过采样初始设置  ##########*/  
  
  /* 开始ADC的正则组转换 */  
  // 启动hadc1这个ADC句柄所代表的ADC转换  
  if (HAL_ADC_Start(&hadc1) != HAL_OK)  
  {  
    /* ADC转换启动错误 */  
    // 如果启动ADC转换失败,则调用错误处理函数  
    Error_Handler();  
  }  
  
  /* 等待ADC转换完成 */  
  // 等待hadc1这个ADC句柄所代表的ADC转换完成,超时时间为10ms  
  if (HAL_ADC_PollForConversion(&hadc1, 10) != HAL_OK)  
  {  
    /* 转换完成标志未按时设置 */  
    // 如果在10ms内没有检测到转换完成标志,则调用错误处理函数  
    Error_Handler();  
  }  
  
  /* 检索ADC转换数据 */  
  // 检索hadc1这个ADC句柄所代表的ADC的转换结果  
  // (使用过采样比率16和右移4位来缩放数据,相当于ADC分辨率为:12位)  
  // 变量uhADCxConvertedData_OVS_ratio16_shift4存储了ADC的转换结果  
  uhADCxConvertedData_OVS_ratio16_shift4 = HAL_ADC_GetValue(&hadc1);  
  
  // 注意:代码段中并没有显示uhADCxConvertedData_OVS_ratio16_shift4的声明和定义,  
  // 假定它在其他地方已经被定义为一个合适的变量来存储ADC转换结果。  
  
  // 此while循环没有终止条件,将无限循环执行ADC的转换和读取操作。  
  // 在实际应用中,可能需要根据具体需求添加其他逻辑或条件来跳出循环。  
}
下面给一个将ADC的值转成电压的代码示例:
#include "stm32u0xx_hal.h"  
  
ADC_HandleTypeDef hadc1;  
  
// ADC参考电压,通常这取决于你的微控制器供电电压和ADC的配置  
#define ADC_VREF    3.3f // 单位:伏特  
  
// 假设ADC是12位的  
#define ADC_BITS    12  
  
// 计算ADC的最大值  
#define ADC_MAX_VALUE ((1 << ADC_BITS) - 1)  
  
// ADC通道配置  
void MX_ADC1_Init(void)  
{  
    ADC_ChannelConfTypeDef sConfig = {0};  
  
    /**Configure the global features of the ADC (Clock, Resolution, Data Alignment and number of conversion) */  
    hadc1.Instance = ADC1;  
    hadc1.Init.ClockPrescaler = ADC_CLOCK_SYNC_PCLK_DIV4; // 设置ADC时钟分频  
    hadc1.Init.Resolution = ADC_RESOLUTION_12B; // 设置ADC分辨率为12位  
    hadc1.Init.ScanConvMode = DISABLE; // 禁止扫描模式  
    hadc1.Init.ContinuousConvMode = ENABLE; // 使能连续转换模式  
    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_SEQ_CONV; // 设置EOC选择  
  
    if (HAL_ADC_Init(&hadc1) != HAL_OK)  
    {  
        // 初始化错误处理  
        Error_Handler();  
    }  
  
    /**Configure for the selected ADC regular channel its corresponding rank in the sequencer and its sample time. */  
    sConfig.Channel = ADC_CHANNEL_0; // 假设我们使用ADC通道0  
    sConfig.Rank = 1;  
    sConfig.SamplingTime = ADC_SAMPLETIME_55CYCLES_5; // 设置采样时间  
  
    if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK)  
    {  
        // 通道配置错误处理  
        Error_Handler();  
    }  
}  
  
// ADC值转换为电压的函数  
float ADC_Value_To_Voltage(uint32_t adc_value)  
{  
    float voltage_step = ADC_VREF / (float)ADC_MAX_VALUE; // 每个ADC值的电压增量  
    float voltage = adc_value * voltage_step; // 计算电压  
    return voltage;  
}  
  
int main(void)  
{  
    HAL_Init(); // 初始化HAL库  
    SystemClock_Config(); // 配置系统时钟,这个函数需要你自己根据硬件手册实现  
  
    MX_ADC1_Init(); // 初始化ADC  
  
    while (1)  
    {  
        HAL_ADC_Start(&hadc1); // 开始ADC转换  
  
        // 等待转换完成,你可以使用轮询或者中断的方式  
        HAL_ADC_PollForConversion(&hadc1, 1000); // 等待1000ms超时  
  
        uint32_t adc_value = HAL_ADC_GetValue(&hadc1); // 读取ADC转换结果  
  
        float voltage = ADC_Value_To_Voltage(adc_value); // 将ADC值转换为电压  
  
        // 在这里你可以使用转换后的电压值,比如通过串口打印出来  
        // ...  
  
        HAL_Delay(1000); // 延时1秒,然后再次读取ADC值  
    }  
}



使用特权

评论回复
沙发
magry385| | 2024-5-2 14:33 | 只看该作者
这个芯片功能非常强大

使用特权

评论回复
板凳
咕咕呱呱孤寡| | 2024-5-13 09:18 | 只看该作者
ADC 的转换精度是多少

使用特权

评论回复
地板
15625004279| | 2024-6-1 10:54 | 只看该作者
ADC采集精度是自己配置吗

使用特权

评论回复
5
Innercourage| | 2024-6-22 15:58 | 只看该作者
ADC 的转换确实用的多,功能强大,很不错

使用特权

评论回复
6
LOVEEVER| | 2024-6-28 18:02 | 只看该作者
ADC是不是直接调用HAL库函数进行数据读取?

使用特权

评论回复
7
kepe| | 2024-7-31 00:51 | 只看该作者
在STM32U083上,ADC的时钟源可以是系统时钟的一部分,通常需要配置ADC的时钟分频器。

使用特权

评论回复
8
gaonaiweng| | 2024-8-29 12:25 | 只看该作者
在实际应用中,可能需要对 ADC 进行校准以提高测量准确性。校准通常在启动前或每次重大环境变化后进行。

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

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

156

主题

640

帖子

3

粉丝