英文:
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.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论