The values read by my ADC have not sense considering my RES setup (STM32H747).
- 3 replies
- 1513 views
I am using the VREFBUF as a reference for my ADC reading and I set it up to the max (2.5 V) and used the capacitor circuit described in AN5690 p.2 Fig. 2. The code used for my ADC and VREFBUF are described here :
void VREFBUF_Init(void) {
SET_BIT(RCC_C2->APB4ENR, RCC_APB4ENR_VREFEN_Msk);
delay(1000);
SET_BIT(VREFBUF->CSR, VREFBUF_CSR_ENVR_Msk);
CLEAR_BIT(VREFBUF->CSR, VREFBUF_CSR_HIZ_Msk);
while (VREFBUF_CSR_VRR & VREFBUF_CSR_VRR_Msk != 1) {}
}void ADC_Init(void) {
/*******************Horloges**************************/
SET_BIT(RCC_C2->APB4ENR, RCC_APB4ENR_SYSCFGEN_Msk); //SYSCFG clock
delay(1000);
SET_BIT(RCC_C2->APB4ENR, RCC_APB4ENR_RTCAPBEN_Msk); //RTCAPB clock
delay(1000);
SET_BIT(RCC_C2->AHB1ENR, RCC_AHB1ENR_ADC12EN_Msk); //ADC12 clocks
delay(1000);
//SET_BIT(RCC_C2->AHB4ENR, RCC_AHB4ENR_GPIOAEN_Msk); //GPIOA clock
//delay(1000);
SET_BIT(RCC_C2->AHB4ENR, RCC_AHB4ENR_GPIOCEN_Msk); //GPIOA clock
delay(1000);
/********************Port config************************/
// SET_BIT(GPIOA->MODER, GPIO_MODER_MODE1_0);
// SET_BIT(GPIOA->MODER, GPIO_MODER_MODE1_1);
// CLEAR_BIT(GPIOA->PUPDR, GPIO_PUPDR_PUPD1_0);
// CLEAR_BIT(GPIOA->PUPDR, GPIO_PUPDR_PUPD1_1);
SET_BIT(GPIOC->MODER, GPIO_MODER_MODE4_0);
SET_BIT(GPIOC->MODER, GPIO_MODER_MODE4_1);
CLEAR_BIT(GPIOC->PUPDR, GPIO_PUPDR_PUPD4_0);
CLEAR_BIT(GPIOC->PUPDR, GPIO_PUPDR_PUPD4_1);
//SET_BIT(SYSCFG->PMCR, SYSCFG_PMCR_PA0SO_Msk);
delay(1000);//PA0_C in analog mode
/********************ADC voltage regulator***************/
CLEAR_BIT(ADC2->CR, ADC_CR_DEEPPWD_Msk); //END DEEPPWD
SET_BIT(ADC2->CR, ADC_CR_ADVREGEN_Msk); //ENABLE ADC VOLTAGE REG
delay(1000);//WAIT VOLTAGE REG
/********************ADC calibration*********************/
CLEAR_BIT(ADC2->CR, ADC_CR_ADCALDIF_Msk);
SET_BIT(ADC2->CR, ADC_CR_ADCALLIN_Msk);
SET_BIT(ADC2->CR, ADC_CR_ADCAL_Msk);
while (ADC_CR_ADCAL & ADC_CR_ADCAL_Msk != 0) {}
/******************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 );
/*******************Input Mode***************************/
CLEAR_BIT(ADC2->DIFSEL, ADC_DIFSEL_DIFSEL_0); //Single Ended
/*******************ADC Enable***************************/
SET_BIT(ADC2->ISR, ADC_ISR_ADRDY_Msk);
SET_BIT(ADC2->CR, ADC_CR_ADEN_Msk);
while (ADC_ISR_ADRDY & ADC_ISR_ADRDY_Msk != 1) {}
SET_BIT(ADC2->ISR, ADC_ISR_ADRDY_Msk);
/********************ADC RES*****************************/
SET_BIT(ADC2->CFGR, ADC_CFGR_RES_2 | ADC_CFGR_RES_1);
CLEAR_BIT(ADC2->CFGR, ADC_CFGR_RES_0);
/********************ADC Data Management*****************/
SET_BIT(ADC2->CFGR, ADC_CFGR_DMNGT_0 | ADC_CFGR_DMNGT_1);//DMA Circular mode
/********************OVRMODE*****************************/
SET_BIT(ADC2->CFGR, ADC_CFGR_OVRMOD_Msk); //Erase old data
/********************CONT/Single/Discont*****************/
SET_BIT(ADC2->CFGR, ADC_CFGR_DISCEN_Msk); // discontinuous mode
CLEAR_BIT(ADC2->CFGR, ADC_CFGR_CONT_Msk); // | ADC_CFGR_DISCEN_Msk
/********************Trigger Detection*******************/
SET_BIT(ADC2->CFGR, ADC_CFGR_EXTEN_0 | ADC_CFGR_EXTSEL_1 | ADC_CFGR_EXTSEL_3);//Trig rising edge TRGO2
CLEAR_BIT(ADC2->CFGR, ADC_CFGR_EXTEN_1 | ADC_CFGR_EXTSEL_0 | ADC_CFGR_EXTSEL_2 | ADC_CFGR_EXTSEL_4);
/********************INput Preselection******************/
SET_BIT(ADC2->PCSEL, ADC_PCSEL_PCSEL_0);//Chan 0
/********************Sample Time reg*********************/
SET_BIT(ADC2->SMPR1, ADC_SMPR1_SMP0_0); //2.5 CLCK Cycles
/********************ADC IT******************************/
SET_BIT(ADC2->IER, ADC_IER_EOCIE_Msk | ADC_IER_EOSMPIE_Msk );//| ADC_IER_EOSIE_Msk | ADC_IER_OVRIE_Msk
NVIC_EnableIRQ(ADC_IRQn);
NVIC_SetVector(ADC_IRQn, (uint32_t)&ADC_IRQHandler);
}The ADC Data is managed by the DMA which is setup this way :
void DMA_Config(void) {
/************DMA CLock Enable******************/
SET_BIT(RCC_C2->AHB1ENR, RCC_AHB1ENR_DMA1EN_Msk);
delay(1000);
/***************P2M****************************/
CLEAR_BIT(DMA1_Stream1->CR, DMA_SxCR_DIR_0 | DMA_SxCR_DIR_1);
/******************Disable FIFO*************************/
//LL_DMA_DisableFifoMode(DMA1, LL_DMA_STREAM_1);
//LL_DMA_SetMemoryBurstxfer(DMA1, LL_DMA_STREAM_1, LL_DMA_MBURST_SINGLE);
/******************Memory size**************************/
SET_BIT(DMA1_Stream1->CR, DMA_SxCR_MSIZE_0);
CLEAR_BIT(DMA1_Stream1->CR, DMA_SxCR_MSIZE_1);
/******************MEM Increment**********************/
SET_BIT(DMA1_Stream1->CR, DMA_SxCR_MINC_Msk);
/******************MEM Address to buffer**************/
DMA1_Stream1->M0AR = (uint32_t)&buff->M7toM4_1; //0x30000000;
DMA1_Stream1->M1AR = (uint32_t)&buff->M7toM4_2; //0x30000000;
/*******************Number of data transfer***********/
SET_BIT(DMA1_Stream1->NDTR, DMA_SxNDT_3 | DMA_SxNDT_1);
/***********************DMA Mode**********************/
SET_BIT(DMA1_Stream1->CR, DMA_SxCR_CIRC_Msk);//circular
SET_BIT(DMA1_Stream1->CR, DMA_SxCR_DBM_Msk);//Double Buffer Mode
/*******************Flow controller*******************/
//SET_BIT(DMA1_Stream1->CR, DMA_SxCR_PFCTRL_Msk);//ADC in control
/******************Periph size************************/
SET_BIT(DMA1_Stream1->CR, DMA_SxCR_PSIZE_0);
CLEAR_BIT(DMA1_Stream1->CR, DMA_SxCR_PSIZE_1);
/******************Peripheral no Increment*************/
CLEAR_BIT(DMA1_Stream1->CR, DMA_SxCR_PINCOS_Msk);
/******************Periph request**********************/
SET_BIT(DMAMUX1_Channel1->CCR, DMAMUX_CxCR_DMAREQ_ID_1 | DMAMUX_CxCR_DMAREQ_ID_3);//adc2_dma
// SET_BIT(DMAMUX1_Channel1->CCR, DMAMUX_CxCR_SYNC_ID_0 | DMAMUX_CxCR_SYNC_ID_1 | DMAMUX_CxCR_SYNC_ID_2);//TIM12_TRGO
// SET_BIT(DMAMUX1_Channel1->CCR, DMAMUX_CxCR_SPOL_0);//rising edge
// DMAMUX1_Channel1->CCR = 0; //Number of requests after synchro (add 1 to the reg value)
// SET_BIT(DMAMUX1_Channel1->CCR, DMAMUX_CxCR_EGE_Msk);//Event Generation end of synchro req
// SET_BIT(DMAMUX1_Channel1->CCR, DMAMUX_CxCR_SE_Msk);//Synchro Enable
/******************Periph address***********************/
DMA1_Stream1->PAR = (uint32_t)&ADC2->DR;
/******************TC IT********************************/
SET_BIT(DMA1_Stream1->CR, DMA_SxCR_TCIE_Msk | DMA_SxCR_TEIE_Msk); //TC IT
DMA1->LIFCR = DMA_LIFCR_CTCIF1;//Clear IT in LISR Register
NVIC_SetVector(DMA1_Stream1_IRQn, (uint32_t)&DMA1_Stream1_IRQHandler);
NVIC_EnableIRQ(DMA1_Stream1_IRQn);
/*******************Enable DMA****************************/
SET_BIT(DMA1_Stream1->CR, DMA_SxCR_EN_Msk);
}Now when I read the value collected by my ADC under a 12bit res setup I do expect for a signal with a 1V offset and a 500mV amplitude to read values above 4095/2 yet I read values between 400 and 500, it seems like the signal is read correctly but not it s scale (I joined a picture of my GUI made with Labview illustrating my results, the signal is a bit deformed but it is linked to speed limitation for data exchange via serial, I can not represent every sample)?? I don't get the reason as to why it does not consider the scale properly ... even if I were to have the wrong voltage Ref value the ADC readings should still be much higher considering the fact that the max voltag ref should be around 3.3V (based on my component's inputs) .
