2024-10-18 10:24 AM - last edited on 2024-10-18 10:38 AM by SofLit
STM32G0B1CBT6
#define ADC0_OBJ_COUNT 9
const uint8_t ch_remap[ADC0_OBJ_COUNT] = {ADC_CHANNEL_0, ADC_CHANNEL_1, ADC_CHANNEL_2, ADC_CHANNEL_3, ADC_CHANNEL_4, ADC_CHANNEL_5, ADC_CHANNEL_6, ADC_CHANNEL_7, ADC_CHANNEL_10};
//const uint8_t ch_remap[ADC0_OBJ_COUNT] = {0 , 1, 2, 3, 4, 5, 6, 7, 10};
uint32_t adc1_value[ADC0_OBJ_COUNT];
static void MX_ADC1_Init(void) {
ADC_ChannelConfTypeDef sConfig = {0};
hadc1.Instance = ADC1;
hadc1.Init.ClockPrescaler = ADC_CLOCK_SYNC_PCLK_DIV4;
hadc1.Init.Resolution = ADC_RESOLUTION_12B;
hadc1.Init.DataAlign = ADC_DATAALIGN_RIGHT;
hadc1.Init.ScanConvMode = ADC_SCAN_DISABLE;
hadc1.Init.EOCSelection = ADC_EOC_SEQ_CONV;
hadc1.Init.LowPowerAutoWait = DISABLE;
hadc1.Init.LowPowerAutoPowerOff = DISABLE;
hadc1.Init.ContinuousConvMode = DISABLE;
hadc1.Init.NbrOfConversion = 1; // 1 konverze najednou
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.SamplingTimeCommon1 = ADC_SAMPLETIME_160CYCLES_5;
hadc1.Init.SamplingTimeCommon2 = ADC_SAMPLETIME_160CYCLES_5;
hadc1.Init.OversamplingMode = DISABLE;
hadc1.Init.TriggerFrequencyMode = ADC_TRIGGER_FREQ_LOW;
if (HAL_ADC_Init(&hadc1) != HAL_OK) {
Error_Handler();
}
// Inicializujte první kanál jako výchozí
sConfig.Channel = ADC_CHANNEL_0;
sConfig.Rank = ADC_REGULAR_RANK_1;
sConfig.SamplingTime = ADC_SAMPLINGTIME_COMMON_1;
if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK) {
Error_Handler();
}
}
void adc1_update(void) {
ADC_ChannelConfTypeDef sConfig = {0};
for (uint8_t i = 0; i < ADC0_OBJ_COUNT; i++) {
/* Configure Regular Channel: add channel to sequence */
sConfig.Channel = ch_remap[i];
sConfig.Rank = ADC_RANK_CHANNEL_NUMBER;
//sConfig.SamplingTime = ADC_SAMPLINGTIME_COMMON_1;
HAL_ADC_ConfigChannel(&hadc1, &sConfig);
// Spustíme konverzi
HAL_ADC_Start(&hadc1);
HAL_ADC_PollForConversion(&hadc1, HAL_MAX_DELAY);
adc1_value[i] = HAL_ADC_GetValue(&hadc1);
adc_obj[i].curr = kalman_filter(&kalman_filters[i], adc1_value[i]);
/* Configure Regular Channel: remove channel from sequence */
sConfig.Channel = ch_remap[i];
sConfig.Rank = ADC_RANK_NONE;
HAL_ADC_ConfigChannel(&hadc1, &sConfig);
}
}
Where is mistake ? It measures only CH0 and copies to all buffer spaces 0-8. I would like to used DMA which worsk fine but DMA can do 8 ch RANKS only i need 12 in future slow measuring of resitors
2024-10-19 10:28 PM
You set number of conversion to 1 and your rank selection is channel 0. So that is the only channel being used.
If want 8 channels then select 8, and adjust each of the ranks to select the channels in the order you want.
And in your code you will have 8 channel configurations. In your case, your code only showed 1 configuration
static void MX_ADC1_Init(void)
{
/* USER CODE BEGIN ADC1_Init 0 */
/* USER CODE END ADC1_Init 0 */
ADC_ChannelConfTypeDef sConfig = {0};
/* USER CODE BEGIN ADC1_Init 1 */
/* USER CODE END ADC1_Init 1 */
/** 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_DIV2;
hadc1.Init.Resolution = ADC_RESOLUTION_12B;
hadc1.Init.DataAlign = ADC_DATAALIGN_RIGHT;
hadc1.Init.ScanConvMode = ADC_SCAN_SEQ_FIXED;
hadc1.Init.EOCSelection = ADC_EOC_SINGLE_CONV;
hadc1.Init.LowPowerAutoWait = DISABLE;
hadc1.Init.LowPowerAutoPowerOff = DISABLE;
hadc1.Init.ContinuousConvMode = ENABLE;
hadc1.Init.NbrOfConversion = 1;
hadc1.Init.ExternalTrigConv = ADC_SOFTWARE_START;
hadc1.Init.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_NONE;
hadc1.Init.DMAContinuousRequests = ENABLE;
hadc1.Init.Overrun = ADC_OVR_DATA_PRESERVED;
hadc1.Init.SamplingTimeCommon1 = ADC_SAMPLETIME_1CYCLE_5;
hadc1.Init.OversamplingMode = DISABLE;
hadc1.Init.TriggerFrequencyMode = ADC_TRIGGER_FREQ_HIGH;
if (HAL_ADC_Init(&hadc1) != HAL_OK)
{
Error_Handler();
}
/** Configure Regular Channel
*/
sConfig.Channel = ADC_CHANNEL_0;
sConfig.Rank = ADC_RANK_CHANNEL_NUMBER;
if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK)
{
Error_Handler();
}
/** Configure Regular Channel
*/
sConfig.Channel = ADC_CHANNEL_1;
if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK)
{
Error_Handler();
}
/** Configure Regular Channel
*/
sConfig.Channel = ADC_CHANNEL_4;
if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK)
{
Error_Handler();
}
/** Configure Regular Channel
*/
sConfig.Channel = ADC_CHANNEL_6;
if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK)
{
Error_Handler();
}
/** Configure Regular Channel
*/
sConfig.Channel = ADC_CHANNEL_7;
if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK)
{
Error_Handler();
}
/** Configure Regular Channel
*/
sConfig.Channel = ADC_CHANNEL_8;
if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK)
{
Error_Handler();
}
/** Configure Regular Channel
*/
sConfig.Channel = ADC_CHANNEL_9;
if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK)
{
Error_Handler();
}
/** Configure Regular Channel
*/
sConfig.Channel = ADC_CHANNEL_10;
if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK)
{
Error_Handler();
}
/** Configure Regular Channel
*/
sConfig.Channel = ADC_CHANNEL_11;
if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK)
{
Error_Handler();
}
/* USER CODE BEGIN ADC1_Init 2 */
/* USER CODE END ADC1_Init 2 */
}
With Ranks you get only 8 channels. To get 12 you need to use regular Sequencer. The ADC conversion goes in order from the lowest ADCx and goes forward, or backwards if selected.
2024-10-20 12:28 AM - edited 2024-10-20 12:35 AM
@Karl Yamashita dont right understand your code...
And your mistake is use
HAL_ADC_ConfigChannel(&hadc1, &sConfig)
this only add new channel , but not remove previous. Then Start ADC only get first...
And subject is DMA , then why you dont ask DMA? If your MCU have ADC1 and ADC2 you can split to two DMA.
FMI where you read about 8 RANK limit?
Solved: ADC multichannel with DMA with more than 8 ADC cha... - STMicroelectronics Community
2024-10-20 08:34 AM
this only add new channel , but not remove previous. Then Start ADC only get first...
Not sure why you want to do unnecessary coding, removing and adding ADC channels? The Sequencer and DMA does all the hard work for you. Each channel's value is saved in it's own index of the array.
And subject is DMA , then why you dont ask DMA? If your MCU have ADC1 and ADC2 you can split to two DMA.
The code i posted is using the DMA. Otherwise i would not be able to enable DMA Continuous Requests
FMI where you read about 8 RANK limit?
Solved: ADC multichannel with DMA with more than 8 ADC cha... - STMicroelectronics Community
The GUI only allows you to select up to 8 Ranks. Even the link you posted shows what to do, if you want more than 8 channels.
2024-10-25 11:50 PM
Thanks for reply. Now It seems to read all defined ADC1 channels via DMA to buffer. There is one item abou .ioc configuration, beside it sometimes freezes under win10 It shows this erros but unable to roll or check what is wrong. Is there any solution/update for .ioc confirugration gui
2024-10-26 07:40 AM
Not sure offhand what the error is about. Upload the ioc file.
2024-10-26 10:33 AM
2024-10-26 10:39 AM
Also not sure about Freertos setups mainly ISR. I think that sometimes it freezes probably in ISR dma uart which works as rs485 with last char timeout int. It continue to run hal tick all isr seems to work dma works adc values continue in uprates buffer but freertos does not enter tasks. It seems to hang in somwhere after osDaly in some yields If i pause debuger. Still entering uart isr repeatedly.