Кто любит RISC в жизни, заходим, не стесняемся.
Ответить

STM32L0 ADC+TIM

Сб авг 10, 2019 09:53:44

Пытаюсь запустить ADC по таймеру.
Код:
//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 ===============================

Таймер работает, считает 1 секунду, но не запускает АЦП. Что я делаю неправильно?
Я использовал пример из RM. Я хочу, чтобы АЦП запускался по таймеру, и после приходило прерывание, где я бы забирал результат и так далее.
Вот пример из RM:
Код:
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) */
Ответить