2022-08-19 08:40 AM
Considering the fact that I can no longer make a difference between waveforms sent at 1kHz (sin and triangular) I am wondering about what I did code wrong in my ADC initialization to mess up my results that much. Below is a 1kHz sin I get for my 200 kHz sampling rate (code below). I use an external Vref MAX6225ACPA to stabilize my reference.
/******Summary**********/
/*
Use ADC1 channel 13 on PC3 triggered by timer 1 (PRESC 19 and ARR 47)
ADC->DR is read by the DMA in double buffer mode and circular
*/
void ADC_Init(void) {
/*******************Clocks**************************/
SET_BIT(RCC->AHB4ENR, RCC_AHB4ENR_GPIOCEN_Msk); //GPIOA clock
// /********************Port config************************/
SET_BIT(GPIOC->MODER, GPIO_MODER_MODE3_0);
SET_BIT(GPIOC->MODER, GPIO_MODER_MODE3_1);
CLEAR_BIT(GPIOC->PUPDR, GPIO_PUPDR_PUPD3_0);
CLEAR_BIT(GPIOC->PUPDR, GPIO_PUPDR_PUPD3_1);
SET_BIT(SYSCFG->PMCR, SYSCFG_PMCR_PA0SO_Msk | SYSCFG_PMCR_PA1SO_Msk | SYSCFG_PMCR_PC2SO_Msk | SYSCFG_PMCR_PC3SO_Msk);
SET_BIT(RCC->AHB1ENR, RCC_AHB1ENR_ADC12EN_Msk); //ADC12 clocks
delay(1000);
/********************ADC voltage regulator***************/
CLEAR_BIT(ADC1->CR, ADC_CR_DEEPPWD_Msk); //END DEEPPWD
SET_BIT(ADC1->CR, ADC_CR_ADVREGEN_Msk); //ENABLE ADC VOLTAGE REG
delay(1000);//WAIT VOLTAGE REG
/******************ADC clock*****************************/
SET_BIT(ADC12_COMMON->CCR, ADC_CCR_CKMODE_0 | ADC_CCR_CKMODE_1);
/*******************ADC Prescaler************************/
SET_BIT(ADC12_COMMON->CCR, ADC_CCR_PRESC_0 | ADC_CCR_PRESC_1 | ADC_CCR_PRESC_3);
/*******************Input Mode***************************/
CLEAR_BIT(ADC1->DIFSEL, ADC_DIFSEL_DIFSEL_13); //Single Ended
/********************INput Preselection******************/
SET_BIT(ADC1->PCSEL, ADC_PCSEL_PCSEL_13);//Chan 13
/********************ADC calibration*********************/
CLEAR_BIT(ADC1->CR, ADC_CR_ADCALDIF_Msk);
SET_BIT(ADC1->CR, ADC_CR_ADCAL_Msk);
while (ADC_CR_ADCAL & ADC_CR_ADCAL_Msk != 0) {}
delay(100);
SET_BIT(ADC1->CR, ADC_CR_ADCALLIN_Msk);
SET_BIT(ADC1->CR, ADC_CR_ADCAL_Msk);
while (ADC_CR_ADCAL & ADC_CR_ADCAL_Msk != 0) {}
delay(100);
/**********************ADC BOOST*************************/
SET_BIT(ADC1->CR, ADC_CR_BOOST_0 | ADC_CR_BOOST_1);
/*******************ADC Enable***************************/
SET_BIT(ADC1->ISR, ADC_ISR_ADRDY_Msk);
SET_BIT(ADC1->CR, ADC_CR_ADEN_Msk);
while (ADC_ISR_ADRDY & ADC_ISR_ADRDY_Msk != 1) {}
SET_BIT(ADC1->ISR, ADC_ISR_ADRDY_Msk);
/********************ADC RES*****************************/
CLEAR_BIT(ADC1->CFGR, ADC_CFGR_RES_0 | ADC_CFGR_RES_1 | ADC_CFGR_RES_2);//16 bit res
/********************ADC Data Management*****************/
SET_BIT(ADC1->CFGR, ADC_CFGR_DMNGT_0 | ADC_CFGR_DMNGT_1);//DMA Circular mode
/********************OVRMODE*****************************/
SET_BIT(ADC1->CFGR, ADC_CFGR_OVRMOD_Msk); //Erase old data
/********************CONT/Single/Discont*****************/
CLEAR_BIT(ADC1->CFGR, ADC_CFGR_DISCEN_Msk); // discontinuous mode disabled
CLEAR_BIT(ADC1->CFGR, ADC_CFGR_CONT_Msk); // cont disabled
/***********************First chan to be converted**************/
SET_BIT(ADC1->SQR1, ADC_SQR1_SQ1_3 | ADC_SQR1_SQ1_2 | ADC_SQR1_SQ1_0);
/********************Trigger Detection*******************/
SET_BIT(ADC1->CFGR, ADC_CFGR_EXTEN_0 | ADC_CFGR_EXTSEL_1 | ADC_CFGR_EXTSEL_3);//Trig rising edge Timer TRGO1
CLEAR_BIT(ADC1->CFGR, ADC_CFGR_EXTEN_1 | ADC_CFGR_EXTSEL_0 | ADC_CFGR_EXTSEL_2 | ADC_CFGR_EXTSEL_4);
/********************Sample Time reg*********************/
SET_BIT(ADC1->SMPR2, ADC_SMPR2_SMP13_0 ); //2.5 CLCK Cycles| ADC_SMPR2_SMP13_1 | ADC_SMPR2_SMP13_2
/********************ADC IT******************************/
// SET_BIT(ADC1->IER, ADC_IER_EOCIE_Msk | ADC_IER_EOSMPIE_Msk | ADC_IER_OVRIE_Msk );//| ADC_IER_EOSIE_Msk | ADC_IER_OVRIE_Msk
// NVIC_EnableIRQ(ADC_IRQn);
// NVIC_SetVector(ADC_IRQn, (uint32_t)&ADC_IRQHandler);
}
2022-08-19 09:39 AM
Try with DC first.
The signal source has to be low impedance, if you want to use short sampling times.
JW
2022-08-19 11:56 AM
DC signals give me a sinus wave. I don't have anything to record a sample of the signals I get when inputting DC right now.
I will try using some capacitors when I get back.
2022-08-19 05:00 PM
EDIT: Something is amiss here. The plot shows about 20 input cycles for 200 samples instead of 1 . Check your conversion frequency.
Cheers, Hal
2022-08-20 08:06 AM
Is the following correct?
If SYSCLK is 480 MHz, Timer 1 is generating an ADC trigger at 240/(19*48) = 250KHz.
ADC prescalar is bit fields 1011 = divide by 256.
Sampling frequency is then 250KHz/256 = 0.976KHz.
Cheers, Hal
2022-08-20 08:20 AM
True, I tried this configuration because I did not understand the LL_GetCommonClock() function return value which did go up when my clock speed was supposed to go down. But using the lowest prescalers values did not really get me satisfying results (still could not differentiate close waveforms like sin and triangular ones and my DC readings remained sin). Do you think there could be a link between my adc accuracy and the ADC clock not respecting a certain value(in the datasheet of the STM32h747 all the parameters of the ADC are described for certain frequencies) ? Should I setup a PLL as an asynchronous clock for ADC and aim for the exact value?
2022-08-20 08:48 AM
The TIM1 trigger should work.
The example is not near any ADC limitations in the data sheet.
Is the signal source and 747 well grounded to each other?
Cheers, hal
2022-08-20 09:08 AM
This is what my circuit looks like, I am using the STM32h747 within the Arduino Portenta (and the schematics are quite obscure to me https://content.arduino.cc/assets/Schematic%20PDF_SL-ABX00042.pdf?_gl=1*1lvkz5d*_ga*NzIxMjUwMTMuMTYzNzc3Mjc1OA..*_ga_NEXN8H46L5*MTY2MTAxMTI3Ny4yOS4xLjE2NjEwMTEyNzkuNTguMC4w page 2 )
2022-08-20 01:20 PM
The schematic shows PC3 connected to Arduino A3. Couldn't find any other connections.
Suggest eliminate one variable by using Portena built-in references.
Perhaps someone else can spot something.
Cheers, Hal
2022-08-20 07:01 PM
Just a thought. You could use the Micro's DAC to produce a triangle or sine wave and use that to test the DAC. That way you can disconnect the signal generator while you test your software - just in case there is some sort of weird noise/ground thing going on.