Я пытаюсь запустить код, который я нашел здесь некоторое время назад, который позволяет выбрать канал АЦП из нескольких каналов и при необходимости прочитать его индивидуально. Нет прямого доступа к памяти. Использую STM32L4R5. Моя идея состоит в том, чтобы просто подтвердить правильность чтения АЦП, включив и выключив светодиоды состояния, если какой-то уровень доступен, и он пока не работает (светодиод состояния всегда включен). В качестве источника входного сигнала я использую вывод GPIO, установленный на высокий уровень, который проходит через резистор 1 кОм и светодиод, поэтому напряжение составляет около 0,7 В. Я вызываю __HAL_RCC_ADC_CLK_ENABLE (); и __HAL_RCC_GPIOC_CLK_ENABLE (); в HAL_ADC_MspInit (). Функция status_led () не отображается, но я ее часто использую, никаких проблем с ней.
Остальной код выглядит следующим образом:
uint32_t pdlvl=0;
int main(void)
{
HAL_Init();
SystemClock_Config();
MX_GPIO_Init();
MX_ADC1_Init();
MX_TIM1_Init();
// Test ADC reading voltage input
//
while(1){
pdlvl=read_ADC_channel(ADC_CHANNEL_13);
if(pdlvl<10){
status_led(4,1);
status_led(3,0);
}
if(pdlvl>10){
status_led(3,1);
status_led(4,0);
}
}
} // end of main
static void MX_ADC1_Init(void)
{
ADC_ChannelConfTypeDef sConfig = {0};
hadc1.Instance = ADC1;
hadc1.Init.ClockPrescaler = ADC_CLOCK_ASYNC_DIV1;
hadc1.Init.Resolution = ADC_RESOLUTION_12B;
hadc1.Init.DataAlign = ADC_DATAALIGN_RIGHT;
hadc1.Init.ScanConvMode = DISABLE;
hadc1.Init.EOCSelection = ADC_EOC_SINGLE_CONV;
hadc1.Init.LowPowerAutoWait = DISABLE;
hadc1.Init.ContinuousConvMode = DISABLE;
hadc1.Init.NbrOfConversion = 1;
hadc1.Init.DiscontinuousConvMode = DISABLE;
hadc1.Init.ExternalTrigConv = ADC_SOFTWARE_START;
hadc1.Init.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_NONE;
hadc1.Init.DMAContinuousRequests = DISABLE;
hadc1.Init.Overrun = ADC_OVR_DATA_PRESERVED;
hadc1.Init.OversamplingMode = DISABLE;
if (HAL_ADC_Init(&hadc1) != HAL_OK)
{
Error_Handler();
}
sConfig.Channel = ADC_CHANNEL_13;
sConfig.Rank = ADC_RANK_NONE;
sConfig.SamplingTime = ADC_SAMPLETIME_640CYCLES_5;
sConfig.SingleDiff = ADC_SINGLE_ENDED;
sConfig.OffsetNumber = ADC_OFFSET_NONE;
if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK)
{
Error_Handler();
}
sConfig.Channel = ADC_CHANNEL_14;
if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK)
{
Error_Handler();
}
}
Инициализация пина
static void MX_GPIO_Init(void)
{
GPIO_InitTypeDef GPIO_InitStruct = {0};
__HAL_RCC_GPIOC_CLK_ENABLE();
GPIO_InitStruct.Pin = ROUT1_Pin|ROUT2_Pin; // ADC_CHANNEL_13 and ADC_CHANNEL_14
GPIO_InitStruct.Mode = GPIO_MODE_ANALOG_ADC_CONTROL;
GPIO_InitStruct.Pull = GPIO_NOPULL;
HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);
}
Теперь сложная часть с предварительной настройкой каналов:
void config_ADC_channel(uint32_t channel, uint8_t val)
{
ADC_ChannelConfTypeDef sConfig;
sConfig.Channel = channel;
sConfig.SamplingTime = ADC_SAMPLETIME_640CYCLES_5;
sConfig.SingleDiff = ADC_SINGLE_ENDED;
sConfig.OffsetNumber = ADC_OFFSET_NONE;
if(val==1){
sConfig.Rank = 1;
}
else{
sConfig.Rank = ADC_RANK_NONE;
}
HAL_ADC_ConfigChannel(&hadc1, &sConfig);
}
и функция чтения
uint32_t read_ADC_channel(uint32_t channel)
{
uint32_t digital_result;
config_ADC_channel(channel, 1);
// HAL_ADCEx_Calibration_Start(&hadc1,ADC_SINGLE_ENDED);
HAL_ADC_Start(&hadc1);
HAL_ADC_PollForConversion(&hadc1, 1000);
digital_result = HAL_ADC_GetValue(&hadc1);
HAL_ADC_Stop(&hadc1);
config_ADC_channel(channel, 0);
return digital_result;
}
Есть идеи, где я ошибаюсь?
Спасибо!