读取Nucleo L476RG上的ADC数值时出现无限循环问题。

huangapple go评论46阅读模式
英文:

readinf adc value on nucleo l476rg infiniteu loop problem

问题

我在尝试读取 nucleo-l476rg 微控制器上的 ADC 值(使用 adc1_in6)时遇到了这个问题:在检查状态寄存器 (ISR) 的 EOC 位时(在 "adc_read function" 中),我陷入了一个无限循环。

以下是 adc.c 文件的内容:

#include "stm32l476xx.h"
#include "adc.h"
#define ADC1_SEQL1 0X00
void pa1_adc1_init(void)
{
    /**************配置 ADC GPIO 引脚 ******************/
    // 启用对 GPIOA 的时钟访问
    RCC->AHB2ENR |= (1U << 0);
    // 将 PA1 的模式设置为模拟模式
    GPIOA->MODER |= (1U << 2);
    GPIOA->MODER |= (1U << 3);
    /****************配置 ADC 外设 ******************/
    // 启用对 ADC 模块的时钟访问
    RCC->AHB2ENR |= (1U << 13);
    /*******配置 ADC 参数****************/
    // 启动转换序列
    ADC1->SQR1 |= (1U << 7);
    ADC1->SQR1 |= (1U << 8);
    // 转换序列长度
    ADC1->SQR1 &= 0xFFFFFFF0UL;
    // 启用 ADC 模块
    // 检查电压调节器状态
    ADC1->CR &= 0x00000000;
    ADC1->CR |= ADC_CR_ADVREGEN;

    while (!(ADC1->CR & ADC_CR_ADVREGEN)) {
        // 等待电压调节器启动时间
    }

    // 将 ADVREGEN 位设置为 1
    ADC1->CR |= ADC_CR_ADVREGEN;

    // 等待电压调节器启动时间

    // 将 ADEN 位设置为 1
    ADC1->CR |= ADC_CR_ADEN;
}

void start_conversion(void)
{
    /* 启动 ADC 转换 */
    ADC1->CR |= ADC_CR_ADSTART;
}

uint32_t adc_read(void)
{
    // 等待转换完成
    while (!(ADC1->ISR & ADC_ISR_EOC)) {}
    // 从 ADC1 数据寄存器读取转换结果
    return (ADC1->DR);
}

我查阅了参考手册,检查了 ISR 寄存器是否有任何特殊要求,但它没有显示任何特殊要求。

英文:

I have this problem when trying to read the ADC value (using adc1_in6) on the nucleo-l476rg micro controlle: I get in an infinite loop when checking if the EOC bit of the status register (ISR) "adc_read function".

Here's the adc.c file content:

#include &quot;stm32l476xx.h&quot;
#include &quot;adc.h&quot;
#define ADC1_SEQL1 0X00
void pa1_adc1_init(void)
{
	/**************configure adc gpio pin ******************/
	//enable clock access to GPIOA
	RCC-&gt;AHB2ENR |= (1U&lt;&lt;0);
	//set the mode of pa1 to analog  mode
	GPIOA-&gt;MODER |=(1U&lt;&lt;2);
	GPIOA-&gt;MODER |=(1U&lt;&lt;3);
	/****************configure adc periph ******************/
	// enable clock access to adc module
	RCC-&gt;AHB2ENR |=(1U&lt;&lt;13);
	/*******configure adc parameters****************/
	//conversion sequence start
	ADC1-&gt;SQR1 |=(1U&lt;&lt;7);
	ADC1-&gt;SQR1 |=(1U&lt;&lt;8);
	//conversion sequence length
	ADC1-&gt;SQR1 &amp;= 0xFFFFFFF0UL;
	//Enable adc module
	// Check voltage regulator status
	ADC1-&gt;CR &amp;= 0x00000000;
	ADC1-&gt;CR |= ADC_CR_ADVREGEN;

	while (!(ADC1-&gt;CR &amp; ADC_CR_ADVREGEN)) {
		// Wait for voltage regulator startup time to pass
	}

	// Set ADVREGEN bit to 1
	ADC1-&gt;CR |= ADC_CR_ADVREGEN;

	// Wait for voltage regulator startup time to pass

	// Set ADEN bit to 1
	ADC1-&gt;CR |= ADC_CR_ADEN;
}

void start_conversion(void)
{
	/*start adc conversion 	 */
	ADC1-&gt;CR |=ADC_CR_ADSTART;


}

uint32_t adc_read(void)
{


	// wait for conversion to be complete
	while (!(ADC1-&gt;ISR &amp; ADC_ISR_EOC)){}
	//read converted result from ADC1 data register
	return (ADC1-&gt;DR);
}

I reviewed the reference manual to check if there are any specific requirements about the ISR register but it doesn't show anything special to do.

答案1

得分: 1

  1. 当启用时钟时,您需要有延迟(或者按照访问顺序进行读取),因为下一个寄存器访问很可能会失败。
  2. ADC具有多个时钟域,仅启用数字部分是不够的。
  3. 在使用之前,您应该校准ADC。
英文:
  1. You need to have delay (or readback as access is strongly ordered) when enable the clock as the next register access is very likely to fail.
  2. ADC has more than one clock domain and enabling digital part is not enough
  3. You should calibrate the ADC before use.

huangapple
  • 本文由 发表于 2023年2月16日 19:21:01
  • 转载请务必保留本文链接:https://go.coder-hub.com/75471529.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定