cancel
Showing results for 
Search instead for 
Did you mean: 

ADC multi channels STM32U585

Forest.Xu
Associate II

Hi, 

I try to make a project that seems easy. but I am not good to code so I ask ChatGPT  but still I need  human GPT to help. appreciated 

1) hardware STM32U585 ( (B-U585I-IOT02A)

2) use software generate 0 to FFF and output analogue voltage to Pin PA4 by DAC1

3) PA4 connect to a PCBA that is to be tested, There are 8 test Pins in PCBA.

4) Connect 8 test Pins to ADC1 input channel Pins.

5) Read 8 Test Pins through ADC1 to compare with PA4 

Questions:

1) All the data read from ADC1 is 0. even I connected some pins to 3.3V.

2) I just need software trigger ADC1 to read 8 data (16bits/Channel) once for each DAC1 output. 

3) print the data in terminal 0ne DAC + 8 ADC data.

4) a little confused about ADC parameter setting. 

output like this 

ForestXu_0-1690845443359.png

ADC1 Setting:

ForestXu_1-1690845474707.png

Code:

/* USER CODE BEGIN 4 */
uint16_t generateDACData(uint16_t index)
{
// Calculate the DAC data based on the index (0 to DAC_DATA_MAX)
return (index % (DAC_DATA_MAX + 1));
}

void generateAndExportData(void)
{
// Start the DAC
HAL_DAC_Start(&hdac1, DAC_CHANNEL_1);

// Array to store ADC values
uint16_t adc_values[8] = {0};
uint16_t num_channels = 8;

// ADC channel configuration (common for all channels)
ADC_ChannelConfTypeDef sConfig = {0};
sConfig.Rank = ADC_REGULAR_RANK_1;
sConfig.SamplingTime = ADC_SAMPLETIME_5CYCLES;
sConfig.SingleDiff = ADC_SINGLE_ENDED;
sConfig.OffsetNumber = ADC_OFFSET_NONE;
sConfig.Offset = 0;
HAL_ADC_ConfigChannel(&hadc1, &sConfig);

// Loop to generate DAC data from 0 to DAC_DATA_MAX and read corresponding ADC data
for (uint16_t i = 0; i <= DAC_DATA_MAX; i++)
{
// Set DAC output value
HAL_DAC_SetValue(&hdac1, DAC_CHANNEL_1, DAC_ALIGN_12B_R, generateDACData(i));

// Wait for DAC conversion settling time (adjust as needed)
// This delay allows the DAC output voltage to stabilize before reading ADC
HAL_Delay(1); // You may need to adjust this delay depending on your DAC's settling time

// Start ADC conversions for all channels
HAL_ADC_Start(&hadc1);

// Read ADC values for all channels
for (uint8_t channel = 0; channel < num_channels; channel++)
{
// Wait for ADC conversion to complete (End of Conversion)
HAL_ADC_PollForConversion(&hadc1, HAL_MAX_DELAY);

// Read ADC value for the current channel
adc_values[channel] = HAL_ADC_GetValue(&hadc1);
}

// Stop ADC when all conversions are done
HAL_ADC_Stop(&hadc1);

// Print ADC values for all channels
char uart_buffer[128];
snprintf(uart_buffer, sizeof(uart_buffer),
"DAC: %d, ADC1: %d, ADC2: %d, ADC3: %d, ADC4: %d, ADC5: %d, ADC6: %d, ADC7: %d, ADC8: %d\r\n",
generateDACData(i), adc_values[0], adc_values[1], adc_values[2], adc_values[3], adc_values[4], adc_values[5], adc_values[6], adc_values[7]);

// Assuming you have UART4 configured and initialized
printf("%s", uart_buffer);
}
}


/* USER CODE END 4 */

Init:

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 */

/** Common config
*/
hadc1.Instance = ADC1;
hadc1.Init.ClockPrescaler = ADC_CLOCK_ASYNC_DIV4;
hadc1.Init.Resolution = ADC_RESOLUTION_12B;
hadc1.Init.GainCompensation = 0;
hadc1.Init.ScanConvMode = ADC_SCAN_ENABLE;
hadc1.Init.EOCSelection = ADC_EOC_SINGLE_CONV;
hadc1.Init.LowPowerAutoWait = DISABLE;
hadc1.Init.ContinuousConvMode = DISABLE;
hadc1.Init.NbrOfConversion = 8;
hadc1.Init.DiscontinuousConvMode = DISABLE;
hadc1.Init.ExternalTrigConv = ADC_SOFTWARE_START;
hadc1.Init.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_NONE;
hadc1.Init.DMAContinuousRequests = DISABLE;
hadc1.Init.TriggerFrequencyMode = ADC_TRIGGER_FREQ_LOW;
hadc1.Init.Overrun = ADC_OVR_DATA_PRESERVED;
hadc1.Init.LeftBitShift = ADC_LEFTBITSHIFT_NONE;
hadc1.Init.ConversionDataManagement = ADC_CONVERSIONDATA_DR;
hadc1.Init.OversamplingMode = DISABLE;
if (HAL_ADC_Init(&hadc1) != HAL_OK)
{
Error_Handler();
}

/** Configure Regular Channel
*/
sConfig.Channel = ADC_CHANNEL_1;
sConfig.Rank = ADC_REGULAR_RANK_1;
sConfig.SamplingTime = ADC_SAMPLETIME_5CYCLE;
sConfig.SingleDiff = ADC_SINGLE_ENDED;
sConfig.OffsetNumber = ADC_OFFSET_NONE;
sConfig.Offset = 0;
if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK)
{
Error_Handler();
}

/** Configure Regular Channel
*/
sConfig.Channel = ADC_CHANNEL_2;
sConfig.Rank = ADC_REGULAR_RANK_2;
if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK)
{
Error_Handler();
}

/** Configure Regular Channel
*/
sConfig.Channel = ADC_CHANNEL_5;
sConfig.Rank = ADC_REGULAR_RANK_3;
if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK)
{
Error_Handler();
}

/** Configure Regular Channel
*/
sConfig.Channel = ADC_CHANNEL_6;
sConfig.Rank = ADC_REGULAR_RANK_4;
if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK)
{
Error_Handler();
}

/** Configure Regular Channel
*/
sConfig.Channel = ADC_CHANNEL_7;
sConfig.Rank = ADC_REGULAR_RANK_5;
if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK)
{
Error_Handler();
}

/** Configure Regular Channel
*/
sConfig.Channel = ADC_CHANNEL_11;
sConfig.Rank = ADC_REGULAR_RANK_6;
if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK)
{
Error_Handler();
}

/** Configure Regular Channel
*/
sConfig.Channel = ADC_CHANNEL_12;
sConfig.Rank = ADC_REGULAR_RANK_7;
if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK)
{
Error_Handler();
}

/** Configure Regular Channel
*/
sConfig.Channel = ADC_CHANNEL_13;
sConfig.Rank = ADC_REGULAR_RANK_8;
if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK)
{
Error_Handler();
}
/* USER CODE BEGIN ADC1_Init 2 */

/* USER CODE END ADC1_Init 2 */

}

/**
* @brief DAC1 Initialization Function
* @PAram None
* @retval None
*/
static void MX_DAC1_Init(void)
{

/* USER CODE BEGIN DAC1_Init 0 */

/* USER CODE END DAC1_Init 0 */

DAC_ChannelConfTypeDef sConfig = {0};
DAC_AutonomousModeConfTypeDef sAutonomousMode = {0};

/* USER CODE BEGIN DAC1_Init 1 */

/* USER CODE END DAC1_Init 1 */

/** DAC Initialization
*/
hdac1.Instance = DAC1;
if (HAL_DAC_Init(&hdac1) != HAL_OK)
{
Error_Handler();
}

/** DAC channel OUT1 config
*/
sConfig.DAC_HighFrequency = DAC_HIGH_FREQUENCY_INTERFACE_MODE_DISABLE;
sConfig.DAC_DMADoubleDataMode = DISABLE;
sConfig.DAC_SignedFormat = DISABLE;
sConfig.DAC_SampleAndHold = DAC_SAMPLEANDHOLD_ENABLE;
sConfig.DAC_Trigger = DAC_TRIGGER_NONE;
sConfig.DAC_OutputBuffer = DAC_OUTPUTBUFFER_ENABLE;
sConfig.DAC_ConnectOnChipPeripheral = DAC_CHIPCONNECT_EXTERNAL;
sConfig.DAC_UserTrimming = DAC_TRIMMING_FACTORY;
sConfig.DAC_SampleAndHoldConfig.DAC_SampleTime = 20;
sConfig.DAC_SampleAndHoldConfig.DAC_HoldTime = 10;
sConfig.DAC_SampleAndHoldConfig.DAC_RefreshTime = 5;
if (HAL_DAC_ConfigChannel(&hdac1, &sConfig, DAC_CHANNEL_1) != HAL_OK)
{
Error_Handler();
}

/** Configure Autonomous Mode
*/
sAutonomousMode.AutonomousModeState = DAC_AUTONOMOUS_MODE_DISABLE;
if (HAL_DACEx_SetConfigAutonomousMode(&hdac1, &sAutonomousMode) != HAL_OK)
{
Error_Handler();
}

/** DAC channel OUT2 config
*/
if (HAL_DAC_ConfigChannel(&hdac1, &sConfig, DAC_CHANNEL_2) != HAL_OK)
{
Error_Handler();
}

 

Thank you 

Forest 

4 REPLIES 4
RhSilicon
Lead

ChatGPT crashed when I asked for a code from STM8, I didn't even try for STM32 😅. If it's Arduino, where all libraries tend to have the same base, it's even easier for ChatGPT to be able to return something functional. For STM32, each time a software version is released, the previous project may no longer work, if there are changes in the library cores.

It might be easier to learn how to make the parts separately and then put them together. ADC has tutorials on the internet, try using these keywords:

https://www.google.com/search?q=stm32+adc+multi+channel

Thank you very much. I will check! 

Pavel A.
Evangelist III

 I need  human GPT to help. 

Here you are.

😅

(It's not bad working with Arduino after all: $100 x 307 = 30.7k)

money_money.png