英文:
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 "stm32l476xx.h"
#include "adc.h"
#define ADC1_SEQL1 0X00
void pa1_adc1_init(void)
{
	/**************configure adc gpio pin ******************/
	//enable clock access to GPIOA
	RCC->AHB2ENR |= (1U<<0);
	//set the mode of pa1 to analog  mode
	GPIOA->MODER |=(1U<<2);
	GPIOA->MODER |=(1U<<3);
	/****************configure adc periph ******************/
	// enable clock access to adc module
	RCC->AHB2ENR |=(1U<<13);
	/*******configure adc parameters****************/
	//conversion sequence start
	ADC1->SQR1 |=(1U<<7);
	ADC1->SQR1 |=(1U<<8);
	//conversion sequence length
	ADC1->SQR1 &= 0xFFFFFFF0UL;
	//Enable adc module
	// Check voltage regulator status
	ADC1->CR &= 0x00000000;
	ADC1->CR |= ADC_CR_ADVREGEN;
	while (!(ADC1->CR & ADC_CR_ADVREGEN)) {
		// Wait for voltage regulator startup time to pass
	}
	// Set ADVREGEN bit to 1
	ADC1->CR |= ADC_CR_ADVREGEN;
	// Wait for voltage regulator startup time to pass
	// Set ADEN bit to 1
	ADC1->CR |= ADC_CR_ADEN;
}
void start_conversion(void)
{
	/*start adc conversion 	 */
	ADC1->CR |=ADC_CR_ADSTART;
}
uint32_t adc_read(void)
{
	// wait for conversion to be complete
	while (!(ADC1->ISR & ADC_ISR_EOC)){}
	//read converted result from ADC1 data register
	return (ADC1->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
- 当启用时钟时,您需要有延迟(或者按照访问顺序进行读取),因为下一个寄存器访问很可能会失败。
 - ADC具有多个时钟域,仅启用数字部分是不够的。
 - 在使用之前,您应该校准ADC。
 
英文:
- 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.
 - ADC has more than one clock domain and enabling digital part is not enough
 - You should calibrate the ADC before use.
 
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。


评论