cancel
Showing results for 
Search instead for 
Did you mean: 

STM32L0 ADC+TIM

1991red1991
Associate III
//Enable ADC1 begin ===========================================================================================================================================
	RCC->APB2ENR |= RCC_APB2ENR_ADC1EN;
	__NOP();
 
	ADC1->CR = 0;	//off ADC
 
	//ADC interrupt enable register
	#define EOCALIE		0
	#define AWDIE		0
	#define OVRIE		1
	#define EOSEQIE		1
	#define EOCIE		1
	#define EOSMPIE		0
	#define ADRDYIE		0
 
	ADC1->IER = (EOCALIE << ADC_IER_EOCALIE_Pos) | (AWDIE << ADC_IER_AWDIE_Pos) | (OVRIE << ADC_IER_OVRIE_Pos) |
	(EOSEQIE << ADC_IER_EOSEQIE_Pos) | (EOCIE << ADC_IER_EOCIE_Pos) | (EOSMPIE << ADC_IER_EOSMPIE_Pos) | (ADRDYIE << ADC_IER_ADRDYIE_Pos);
 
	//ADC control register
	#define ADCAL		0
	#define ADVREGEN	0
	#define ADSTP		0
	#define ADSTART		0
	#define ADDIS		0
	#define ADEN		0
 
	ADC1->CR = (ADCAL << ADC_CR_ADCAL_Pos) | (ADVREGEN << ADC_CR_ADVREGEN_Pos) | (ADSTP << ADC_CR_ADSTP_Pos) |
	(ADSTART << ADC_CR_ADSTART_Pos) | (ADDIS << ADC_CR_ADDIS_Pos) | (ADEN << ADC_CR_ADEN_Pos);
 
	//ADC configuration register 1
	#define AWDCH		0
	#define AWDEN		0
	#define AWDSGL		0
	#define DISCEN		0
	#define AUTOFF		0
	#define WAIT		0
	#define CONT		1 //1: Continuous conversion mode
	#define OVRMOD		0
	#define EXTEN		1 //01: Hardware trigger detection on the rising edge
	#define EXTSEL		4 //0100: TRG22
	#define ALIGN		0
	#define RES			0
	#define SCANDIR		1
	#define DMACFG		0 //1: DMA circular mode selected
	#define DMAEN		0 //1: DMA enabled
 
	ADC1->CFGR1 = (AWDCH << ADC_CFGR1_AWDCH_Pos) | (AWDEN << ADC_CFGR1_AWDEN_Pos) | (AWDSGL << ADC_CFGR1_AWDSGL_Pos) |
	(DISCEN << ADC_CFGR1_DISCEN_Pos) | (AUTOFF << ADC_CFGR1_AUTOFF_Pos) | (WAIT << ADC_CFGR1_WAIT_Pos) | (CONT << ADC_CFGR1_CONT_Pos) |
	(OVRMOD << ADC_CFGR1_OVRMOD_Pos) | (EXTEN << ADC_CFGR1_EXTEN_Pos) | (EXTSEL << ADC_CFGR1_EXTSEL_Pos) | (ALIGN << ADC_CFGR1_ALIGN_Pos) |
	(RES << ADC_CFGR1_RES_Pos) | (SCANDIR << ADC_CFGR1_SCANDIR_Pos) | (DMACFG << ADC_CFGR1_DMACFG_Pos) | (DMAEN << ADC_CFGR1_DMAEN_Pos);
 
	//ADC configuration register 2
	#define CKMODE		0
	#define TOVS		0
	#define OVSS		0
	#define OVSR		0
	#define OVSE		0
 
	ADC1->CFGR2 = (CKMODE << ADC_CFGR2_CKMODE_Pos) | (TOVS << ADC_CFGR2_TOVS_Pos) | (OVSS << ADC_CFGR2_OVSS_Pos) |
	(OVSR << ADC_CFGR2_OVSR_Pos) | (OVSE << ADC_CFGR2_OVSE_Pos);
 
	//ADC  sampling time register
	#define SMP			7 //001: 3.5 ADC clock cycles 111: 160.5 ADC clock cycles
 
	ADC1->SMPR = (SMP << ADC_SMPR_SMP_Pos);
 
	//ADC  channel selection register
	#define CHSEL9			1
	#define CHSEL18			1
	#define CHSEL17			1
 
	ADC1->CHSELR = (CHSEL18 << ADC_CHSELR_CHSEL18_Pos)|(CHSEL9 << ADC_CHSELR_CHSEL9_Pos)|(CHSEL17 << ADC_CHSELR_CHSEL17_Pos);
 
	//ADC common configuration register
	#define LFMEN		0
	#define VLCDEN		0
	#define TSEN		1
	#define VREFEN		1
	#define PRESC		0
 
	ADC->CCR = (LFMEN << ADC_CCR_LFMEN_Pos) | (TSEN << ADC_CCR_TSEN_Pos) |
	(VREFEN << ADC_CCR_VREFEN_Pos) | (PRESC << ADC_CCR_PRESC_Pos);
 
	NVIC_SetPriority(ADC1_COMP_IRQn,0);
	NVIC_EnableIRQ(ADC1_COMP_IRQn);
	//Enable ADC1 end ===========================================================================================================================================
 
  	//Enable TIMER22 begin ===========================================================================================================================================
  	RCC->APB2ENR |= RCC_APB2ENR_TIM22EN;
  	__NOP();
 
  	TIM22->CR1 = 0;
 
  	//TIMx control register 1
  	#define CKD		0	//00: tDTS = tCK_INT
  	#define ARPE	0	//0: TIMx_ARR register is not buffered
  	#define CMS		0	//00: Edge-aligned mode. The counter counts up or down depending on the direction bit (DIR)
  	#define DIR		0	//0: Counter used as upcounter
  	#define OPM		0	//0: Counter is not stopped at update event
  	#define URS		1	//0: 1!!!!! Any of the following events generate an update interrupt or DMA request if enabled.
  	#define UDIS	0	//0: UEV enabled
 
  	TIM22->CR1 = (CKD << TIM_CR1_CKD_Pos) | (ARPE << TIM_CR1_ARPE_Pos) | (CMS << TIM_CR1_CMS_Pos) |
  	(DIR << TIM_CR1_DIR_Pos) | (OPM << TIM_CR1_OPM_Pos) | (URS << TIM_CR1_URS_Pos) | (UDIS << TIM_CR1_UDIS_Pos);
 
  	//TIMx control register 2
  	#define TI1S	0	//0: The TIMx_CH1 pin is connected to TI1 input
  	#define MMS		2	////010: Update - The update event is selected as trigger output (TRGO)
  	#define CCDS	0	//0: CCx DMA request sent when CCx event occurs
  									//1: CCx DMA requests sent when update event occurs
  	TIM22->CR2 = (TI1S << TIM_CR2_TI1S_Pos) | (MMS << TIM_CR2_MMS_Pos) | (CCDS << TIM_CR2_CCDS_Pos);
 
  	//TIMx slave mode control register
  	#define ETP		0	//0: ETR is noninverted, active at high level or rising edge
  	#define ECE		0	//0: External clock mode 2 disabled
  	#define ETPS	0	//00: Prescaler OFF
  	#define ETF		0	//0000: No filter, sampling is done at fDTS
  	#define MSM		0	//0: No action
  	#define TS		0	//000: Internal Trigger 0 (ITR0)
  	#define SMS		0	//000: Slave mode disabled - if CEN = ?1 then the prescaler is clocked directly by the internal clock.
 
  	TIM22->SMCR = 0;
  	TIM22->SMCR = (ETP << TIM_SMCR_ETP_Pos) | (ECE << TIM_SMCR_ECE_Pos) | (ETPS << TIM_SMCR_ETPS_Pos) |
  	(ETF << TIM_SMCR_ETF_Pos) | (MSM << TIM_SMCR_MSM_Pos) | (TS << TIM_SMCR_TS_Pos)|(SMS << TIM_SMCR_SMS_Pos);;
 
  	//TIMx DMA/Interrupt enable register
  	TIM22->DIER = 0;
 
  	//TIMx status register
  	TIM22->SR = 0;
 
  	//TIMx event generation register
  	#define TG		0	//0: No action
  	#define CC4G	0	//0: No action
  	#define CC3G	0	//0: No action
  	#define CC2G	0	//0: No action
  	#define CC1G	0	//0: No action
  	#define UG		0	//0: No action
 
  	TIM22->EGR = (TG << TIM_EGR_TG_Pos) | (CC4G << TIM_EGR_CC4G_Pos) | (CC3G << TIM_EGR_CC3G_Pos) |
  	(CC2G << TIM_EGR_CC2G_Pos) | (CC1G << TIM_EGR_CC1G_Pos) | (UG << TIM_EGR_UG_Pos);
 
  	//TIMx capture/compare mode register 1
  	TIM22->CCMR1 = 0;
 
  	//TIMx capture/compare mode register 2
  	TIM22->CCMR2 = 0;
 
  	//TIMx capture/compare enable register
  	TIM22->CCER = 0;
 
  	//TIMx counter
  	TIM22->CNT = 0;
 
  	//TIMx prescaler
  	TIM22->PSC = 32000-1;
 
  	//TIMx auto-reload register
  	TIM22->ARR = 1000-1;// 1sec
 
  	//TIMx capture/compare register 1
  	TIM22->CCR1 = 0;
 
  	//TIMx capture/compare register 2
  	TIM22->CCR2 = 0;
 
  	//TIMx capture/compare register 3
  	TIM22->CCR3 = 0;
 
  	//TIMx capture/compare register 4
  	TIM22->CCR4 = 0;
 
  	//TIMx DMA control register
  	TIM22->DCR = 0;
 
  	//TIMx DMA address for full transfer
  	TIM22->DMAR = 0;
 
  	TIM22->CR1 |= TIM_CR1_CEN;
 
	#undef CKD
	#undef ARPE
	#undef CMS
	#undef DIR
	#undef OPM
	#undef URS
	#undef UDIS
 
	#undef TI1S
	#undef MMS
	#undef CCDS
 
	#undef ETP
	#undef ECE
	#undef ETPS
	#undef ETF
	#undef MSM
	#undef TS
	#undef SMS
 
	#undef TG
	#undef CC4G
	#undef CC3G
	#undef CC2G
	#undef CC1G
	#undef UG
 
  	//Enable TIMER22 end ===========================================================================================================================================

The timer counts 1 second, but does not start the ADC. ADC does not get into interruption. Why can this happen? What am I doing wrong?

2 REPLIES 2

Looks like hours of fun.

Check registers in debugger.

That timer source works in ADC.

Don't see DMA setup/configuration.

With free climbing there aren't rope lines.​

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
1991red1991
Associate III
A.8.8 Continuous conversion sequence code example - Hardware trigger
/* (1) Select HSI16 by writing 00 in CKMODE (reset value) */
/* (2) Select the external trigger on TIM22_TRGO (TRG4 i.e. EXTSEL = 100
and rising edge, the continuous mode and scanning direction */
/* (3) Select CHSEL4, CHSEL9 and CHSEL17 */
/* (4) Select a sampling mode of 111 i.e. 239.5 ADC clk to be greater
than 5us */
/* (5) Enable interrupts on EOC, EOSEQ and overrrun */
/* (6) Wake-up the VREFINT (only for Temp sensor and VRefInt) */
//ADC1->CFGR2 &= ~ADC_CFGR2_CKMODE; /* (1) */
ADC1->CFGR1 |= ADC_CFGR1_EXTEN_0 | ADC_CFGR1_EXTSEL_2 | ADC_CFGR1_CONT \
| ADC_CFGR1_SCANDIR; /* (2) */
ADC1->CHSELR = ADC_CHSELR_CHSEL4 | ADC_CHSELR_CHSEL9 \
| ADC_CHSELR_CHSEL17; /* (3 */
ADC1->SMPR |= ADC_SMPR_SMP_0 | ADC_SMPR_SMP_1 | ADC_SMPR_SMP_2; /* (4) */
ADC1->IER = ADC_IER_EOCIE | ADC_IER_EOSEQIE | ADC_IER_OVRIE; /* (5) */
ADC->CCR |= ADC_CCR_VREFEN; /* (6) */
/* Configure NVIC for ADC */
/* (1) Enable Interrupt on ADC */
/* (2) Set priority for ADC */
NVIC_EnableIRQ(ADC1_COMP_IRQn); /* (1) */
NVIC_SetPriority(ADC1_COMP_IRQn,0); /* (2) */

I used the example from the reference manual. But it doesn’t work for me, I want the ADC to start on a timer and after that an interrupt from the ADC comes in.

I do not understand why this example does not work?