STM32 input Capture Mode settings and receive data with DMA
Blog link:Http://blog.csdn.net/jdh99, Author: jdh, reprinted please note.
Environment:
HOST: WIN7
Development Environment: MDK4.72
MCU: STM32F103
Note:
The project requires infrared learning, so the input capture is used to obtain the level change time, and the data is placed in the DMA. This can avoid frequent interruption of CPU resources.
PB1, corresponding to TIM3 Channel 4.
Source code:
/*************************************** ******************************* Interface functions: initialize the infrared learning module ************************************ * ********************************/void inf_infrared_study_init (void) {// initialization io port inf_init_io (); // initialization interrupt // inf_init_irq (); // initialization timer inf_init_timer (); // enable DMA inf_infrared_study_open_dma (1 ); // enable the timer inf_infrared_study_open_timer (1 );} /*************************************** * ****************************** initialize the io port ****** **************************************** * **********************/static void inf_init_io (void) {// define the IO initialization struct GPIO_InitTypeDef GPIO_InitStructure; // initialize the clock RCC_APB2PeriphClockCmd (enabled, ENABLE); // pin initialization period = GPIO_Pin_1; // set it to input bytes = bytes; // initialize GPIO_Init (GPIOB, & GPIO_InitStructure );} /*************************************** ******* **************************************** * *********************/static void inf_init_irq (void) {// define the External Interrupt struct EXTI_InitTypeDef EXTI_InitStructure; // initialize the interrupt pin reuse clock reset (enabled, ENABLE); // configure the interrupt source GPIO_EXTILineConfig (GPIO_PortSourceGPIOB, GPIO_PinSource1 ); // The configuration descent edge triggers EXTI_ClearITPendingBit (EXTI_Line1); break = EXTI_Line1; break = EXTI_Trigger_Falling; break = break; break = ENABLE; EXTI_Init (& EXTI_InitStructure );} /*************************************** ******* **************************************** * *********************/static void inf_init_timer (void) {// define the timer struct TIM_TimeBaseInitTypeDef timInitStruct; // input the capture struct TIM_ICInitTypeDef tim_icinit; // define the DMA struct DMA_InitTypeDef DMA_InitStructure; // ENABLE the DMA clock handler (ENABLE ); // DMA1 Channel 3 configure DMA_DeInit (DMA1_Channel3); // peripheral address bandwidth = (uint32_t) (& TIM3-> CCR4); // memory address bandwidth = (uint32_t) Rx_Buf_Tim_Dma; // One-way dma transmission direction = DMA_DIR_PeripheralSRC; // set the DMA buffer length limit = RX_LEN_TIM_DMA during transmission; // set the DMA peripheral incremental mode, One peripheral memory = DMA_PeripheralInc_Disable; // set the memory increment mode of DMA to DMA_MemoryInc_Enable; // The data font length of the peripheral device, namely DMA_PeripheralDataSize_HalfWord; // The data font length of the memory, namely DMA_MemoryDataSize_HalfWord; // set the DMA transmission mode. // region = DMA_Mode_Normal; DMA_InitStructure.DMA_Mode = DMA_Mode_Circular; // set the priority of the DMA parameter to DMA_Priority_High; // set the variables in the two memory of DMA to access each other = DMA_M2M_Disable; DMA_Init (DMA1_Channel3, & DMA_InitStructure); // ENABLE the RCC_APB1PeriphClockCmd (enabled, ENABLE ); // reset Timer to the default value TIM_DeInit (TIM3); // use the internal clock to provide TIM_InternalClockConfig (TIM3) to TIM3; // pre-division timInitStruct. TIM_ClockDivision = TIM_CKD_DIV1; // The counting frequency is NS and timInitStruct is redirected once. TIM_Prescaler = SystemCoreClock/2000000-1; // count timInitStruct up. TIM_CounterMode = TIM_CounterMode_Up; timInitStruct. TIM_RepetitionCounter = 0; // This value is actually TIMX-> ARR. You can reset timInitStruct when the delay starts. TIM_Period = 0 xffff; // initialization timer 3TIM_TimeBaseInit (TIM3, & timInitStruct); // input capture configuration // select channel tim_icinit.TIM_Channel = TIM_Channel_4; // hardware filter period = 0x0; // The level required to trigger the capture = TIM_ICPolarity_Falling; // capture frequency = TIM_ICPSC_DIV1 each time the trigger is detected; // The Channel Direction is TIM_ICSelection_DirectTI; // initialize TIM_ICInit (TIM3, & tim_icinit); // disable arr pre-loaded buffer TIM_ARRPreloadConfig (TIM3, DISABLE); // select TIM_SelectInputTrigger (TIM3, TIM_TS_TI2FP2) for input hop changes; // The Slave Mode: reset mode TIM_SelectSlaveMode (TIM3, expires); // select TIM_SelectMasterSlaveMode (TIM3, expires) in Master/Slave Mode; // configure the DMA TIM_DMAConfig (TIM3, TIM_DMABase_CCR4, expires) of the timer ); // generate the DMA request signal TIM_DMACmd (TIM3, TIM_DMA_CC4, ENABLE); // ENABLE the timer TIM_Cmd (TIM3, ENABLE );} /*************************************** ******************************* interface functions: enable the timer * parameter: state: Status: 0: Off, 1: open *************************************** * ****************************/void inf_infrared_study_open_timer (uint8_t state) {if (state) {TIM_Cmd (TIM3, ENABLE) ;}else {TIM_Cmd (TIM3, DISABLE );}} /*************************************** ******************************* interface functions: open interrupt * parameter: state: Status: 0: Off, 1: open *************************************** * ****************************/void inf_infrared_study_open_irq (uint8_t state) {// define the interrupt structure NVIC_InitTypeDef NVIC_InitStructure; if (state) {// enable the interrupt NVIC_InitStructure.NVIC_IRQChannel = extistmirqn; // the channel is set to the external disconnection Limit = 1; // interrupt preemptive ranking priority; Priority: NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; // ENABLE NVIC_Init (& NVIC_InitStructure ); // initialization} else {// disable the interrupt NVIC_InitStructure.NVIC_IRQChannel = exti?irqn; // the channel is set to the external disconnection Threshold = 1; // The disconnection Threshold = 0; // priority of the interrupt response NVIC_InitStructure.NVIC_IRQChannelCmd = DISABLE; // enable the interrupt NVIC_Init (& NVIC_InitStructure ); // initialization }}/********************************** ************************************ interface functions: enable DMA * parameter: state: Status: 0: disabled, 1: open *************************************** * ****************************/void inf_infrared_study_open_dma (uint8_t state) {if (state) {// set the length of the transmitted data // configure (DMA1_Channel3, RX_LEN_TIM_DMA); // open DMADMA_Cmd (DMA1_Channel3, ENABLE);} else {DMA_Cmd (DMA1_Channel3, DISABLE );}} /*************************************** ******************************* interface functions: returns the DMA received frame length: frame Length ************************************** * *****************************/uint16_t inf_infrared_study_dma_rx_len (void) {// get the receipt frame length return (RX_LEN_TIM_DMA-DMA_GetCurrDataCounter (DMA1_Channel3 ));}
Note:
The timer except TIM6 and TIM7 can only capture the rising or falling edge, but not the bilateral edge.
#define TIM_ICPolarity_Rising ((uint16_t)0x0000)#define TIM_ICPolarity_Falling ((uint16_t)0x0002)#define TIM_ICPolarity_BothEdge ((uint16_t)0x000A)#define IS_TIM_IC_POLARITY(POLARITY) (((POLARITY) == TIM_ICPolarity_Rising) || \ ((POLARITY) == TIM_ICPolarity_Falling))#define IS_TIM_IC_POLARITY_LITE(POLARITY) (((POLARITY) == TIM_ICPolarity_Rising) || \ ((POLARITY) == TIM_ICPolarity_Falling)|| \ ((POLARITY) == TIM_ICPolarity_BothEdge))