Reference: STM32 input capture mode setting and receiving data using DMA
PWM input mode
This mode is a particular case of input capture mode.
The procedure is the same except:
Two ICx signals are mapped on the same TIx input.
These 2 ICx signals are active on edges with opposite polarity.
One of the two TIxFP signals is selected as trigger input and the slave mode controller is configured in reset mode.
For example, you can measure the period (in TIMx_CCR1 register) and the duty cycle (in TIMx_CCR2 register)
of the PWM applied on TI1 using the following procedure (depending on CK_INT frequency and prescaler value):
Select the active input for TIMx_CCR1: write the CC1S bits to 01 in the TIMx_CCMR1 register (TI1 selected).
Select the active polarity for TI1FP1 (used both for capture in TIMx_CCR1 and counter clear): write the CC1P and CC1NP bits to ' 0' (active on rising edge).
Select the active input for TIMx_CCR2: write the CC2S bits to 10 in the TIMx_CCMR1 register (TI1 selected).
Select the active polarity for TI1FP2 (used for capture in TIMx_CCR2): write the CC2P and CC2NP bits to '1' (active on falling edge).
Select the valid trigger input: write the TS bits to 101 in the TIMx_SMCR register (TI1FP1 selected).
Configure the slave mode controller in reset mode: write the SMS bits to 100 in the TIMx_SMCR register.
Enable the captures: write the CC1E and CC2E bits to '1' in the TIMx_CCER register.
STM32 PWM input mode setting and receiving data using DMA
Infrared learning is required in the project. If the input capture method is used, the timer can only capture the rising edge or the falling edge.
Therefore, we can only obtain the period, but not the specific time of the high and low levels of the infrared wave.
So PWM input is used for capture. The PA8 pin is used, which corresponds to channel 1 of TIM1.
/****************************************************** ********************* * Functions *************************************************** ************************/ /****************************************************** ********************* * Interface function: Initialize infrared learning module *************************************************** ************************/ void inf_infrared_study_init( void ) { // Initialize io port inf_init_io( ); // Initialize interrupt //inf_init_irq(); // Initialize the timer inf_init_timer() ; //Open DMA inf_infrared_study_open_dma( 1 ); //Open the timer inf_infrared_study_open_timer( 1 ); } /****************************************************** ********************* * Initialize io port *************************************************** ************************/ static void inf_init_io(void) { //Define IO initialization structure GPIO_InitTypeDef GPIO_InitStructure; // Initialize the clock RCC_APB2PeriphClockCmd( RCC_APB2Periph_GPIOB, ENABLE ); //Pin initialization GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8; //Set as input GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; //initialization GPIO_Init( GPIOA, &GPIO_InitStructure ); } /****************************************************** ********************* * Initialization interrupt *************************************************** ************************/ static void inf_init_irq(void) { //Define the external interrupt structure EXTI_InitTypeDef EXTI_InitStructure; // Initialize the interrupt pin multiplexing clock RCC_APB2PeriphClockCmd( RCC_APB2Periph_AFIO, ENABLE ); //Configure interrupt source GPIO_EXTILineConfig(GPIO_PortSourceGPIOB, GPIO_PinSource1); //Configure falling edge trigger EXTI_ClearITPendingBit(EXTI_Line1); EXTI_InitStructure.EXTI_Line = EXTI_Line1; EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling; EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt; EXTI_InitStructure.EXTI_LineCmd = ENABLE; EXTI_Init( &EXTI_InitStructure ); } /****************************************************** ********************* * Initialize the timer *************************************************** ************************/ static void inf_init_timer(void) { //Define the timer structure TIM_TimeBaseInitTypeDef timInitStruct; // Input capture structure TIM_ICInitTypeDef tim_icinit; //Define DMA structure DMA_InitTypeDef DMA_InitStructure; //Start DMA clock RCC_AHBPeriphClockCmd( RCC_AHBPeriph_DMA1, ENABLE ); //DMA1 channel configuration DMA_DeInit( DMA1_Channel2 ); //Peripheral address DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t) ( &TIM1->CCR1 ); //Memory address DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t) Rx_Buf_Tim_Dma1; //dma transmission direction is one-way DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC; //Set the length of the DMA buffer during transmission DMA_InitStructure.DMA_BufferSize = RX_LEN_TIM_DMA; //Set the DMA peripheral increment mode, a peripheral DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable; //Set DMA memory increment mode DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable; //Peripheral data word length DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord; //Memory data word length DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord; //Set DMA transfer mode //DMA_InitStructure.DMA_Mode = DMA_Mode_Normal; DMA_InitStructure.DMA_Mode = DMA_Mode_Circular; //Set the DMA priority level DMA_InitStructure.DMA_Priority = DMA_Priority_High; //Set the variables in the two DMA memories to access each other DMA_InitStructure.DMA_M2M = DMA_M2M_Disable; DMA_Init( DMA1_Channel2, &DMA_InitStructure ); //Start DMA clock RCC_AHBPeriphClockCmd( RCC_AHBPeriph_DMA1, ENABLE ); //DMA1 channel configuration DMA_DeInit( DMA1_Channel3 ); //Peripheral address DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t) ( &TIM1->CCR2 ); //Memory address DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t) Rx_Buf_Tim_Dma2; //dma transmission direction is one-way DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC; //Set the length of the DMA buffer during transmission DMA_InitStructure.DMA_BufferSize = RX_LEN_TIM_DMA; //Set the DMA peripheral increment mode, a peripheral DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable; //Set DMA memory increment mode DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable; //Peripheral data word length DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord; //Memory data word length DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord; //Set DMA transfer mode //DMA_InitStructure.DMA_Mode = DMA_Mode_Normal; DMA_InitStructure.DMA_Mode = DMA_Mode_Circular; //Set the DMA priority level DMA_InitStructure.DMA_Priority = DMA_Priority_High; //Set the variables in the two DMA memories to access each other DMA_InitStructure.DMA_M2M = DMA_M2M_Disable; DMA_Init( DMA1_Channel3, &DMA_InitStructure ); //Start the clock RCC_APB2PeriphClockCmd( RCC_APB2Periph_TIM1, ENABLE ); //Reset the Timer to its default value TIM_DeInit( TIM1 ); //Use the internal clock to provide the clock source TIM_InternalClockConfig(TIM1); //Pre-scaling timInitStruct.TIM_ClockDivision = TIM_CKD_DIV1; //Counting frequency is 500ns and jumps once timInitStruct.TIM_Prescaler = SystemCoreClock / 1 - 1; //Count up timInitStruct.TIM_CounterMode = TIM_CounterMode_Up; timInitStruct.TIM_RepetitionCounter = 0; //This value is actually TIMX->ARR, and can be reset when the delay starts timInitStruct.TIM_Period = 0xffff; // Initialize the timer TIM_TimeBaseInit(TIM1, &timInitStruct); // Input capture configuration //Select channel tim_icinit.TIM_Channel = TIM_Channel_1; //Hardware filtering tim_icinit.TIM_ICFilter = 0x0; //Trigger capture level tim_icinit.TIM_ICPolarity = TIM_ICPolarity_Falling; //Capture every time a trigger level is detected tim_icinit.TIM_ICPrescaler = TIM_ICPSC_DIV1; //Channel direction selection tim_icinit.TIM_ICSelection = TIM_ICSelection_DirectTI; //initialization //TIM_ICInit(TIM1,&tim_icinit); TIM_PWMIConfig( TIM1, &tim_icinit ); //Disable ARR preload buffer //TIM_ARRPreloadConfig(TIM1, DISABLE); // Input jump selection TIM_SelectInputTrigger(TIM1, TIM_TS_TI1FP1); //Slave mode: reset mode TIM_SelectSlaveMode(TIM1, TIM_SlaveMode_Reset); //Master-slave mode selection TIM_SelectMasterSlaveMode(TIM1, TIM_MasterSlaveMode_Enable); //Configure the timer's DMA TIM_DMAConfig( TIM1, TIM_DMABase_CCR1, TIM_DMABurstLength_2Bytes ); //Generate DMA request signal TIM_DMACmd(TIM1, TIM_DMA_CC1, ENABLE); //Configure the timer's DMA TIM_DMAConfig( TIM1, TIM_DMABase_CCR2, TIM_DMABurstLength_2Bytes ); //Generate DMA request signal TIM_DMACmd(TIM1, TIM_DMA_CC2, ENABLE); //Open the timer TIM_Cmd( TIM1, ENABLE ); } /****************************************************** ********************* * Interface function: open the timer *Parameter: state: 0: closed, 1: open *************************************************** ************************/ void inf_infrared_study_open_timer( uint8_t state ) { if ( state ) { TIM_Cmd( TIM1, ENABLE ); } else { TIM_Cmd( TIM1, DISABLE ); } } /****************************************************** ********************* * Interface function: Enable interrupt *Parameter: state: 0: closed, 1: open *************************************************** ************************/ void inf_infrared_study_open_irq( uint8_t state ) { //Define the interrupt structure NVIC_InitTypeDef NVIC_InitStructure; if ( state ) { // Enable interrupt NVIC_InitStructure.NVIC_IRQChannel = EXTI1_IRQn; //Channel is set to external interrupt line NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1; //Interrupt preemption priority NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; //Interrupt response priority NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //Enable interrupt NVIC_Init( &NVIC_InitStructure ); // Initialization } else { //Disable interrupts NVIC_InitStructure.NVIC_IRQChannel = EXTI1_IRQn; //Channel is set to external interrupt line NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1; //Interrupt preemption priority NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; //Interrupt response priority NVIC_InitStructure.NVIC_IRQChannelCmd = DISABLE; // Enable interrupt NVIC_Init( &NVIC_InitStructure ); // Initialization } } /****************************************************** ********************* * Interface function: open DMA *Parameter: state: 0: closed, 1: open *************************************************** ************************/ void inf_infrared_study_open_dma( uint8_t state ) { if ( state ) { //Set the transmission data length //DMA_SetCurrDataCounter(DMA1_Channel3,RX_LEN_TIM_DMA); //Open DMA DMA_Cmd(DMA1_Channel2, ENABLE); DMA_Cmd(DMA1_Channel3, ENABLE); } else { DMA_Cmd(DMA1_Channel2, DISABLE); DMA_Cmd(DMA1_Channel3, ENABLE); } } /****************************************************** ********************* * Interface function: Get DMA receive frame length * Return: frame length *************************************************** ************************/ uint16_t inf_infrared_study_dma_rx_len( void ) { //Get the received frame length return (RX_LEN_TIM_DMA - DMA_GetCurrDataCounter( DMA1_Channel2 ) ); }
Previous article:Pulse Width Modulation Timer (PWM) in S3C2410
Next article:STM32 serial port timeout judgment method receives unknown length data
Recommended ReadingLatest update time:2024-11-16 15:53
- Popular Resources
- Popular amplifiers
- 西门子S7-12001500 PLC SCL语言编程从入门到精通 (北岛李工)
- Small AC Servo Motor Control Circuit Design (by Masaru Ishijima; translated by Xue Liang and Zhu Jianjun, by Masaru Ishijima, Xue Liang, and Zhu Jianjun)
- Intelligent Control Technology of Permanent Magnet Synchronous Motor (Written by Wang Jun)
- usb_host_device_code
Professor at Beihang University, dedicated to promoting microcontrollers and embedded systems for over 20 years.
- Innolux's intelligent steer-by-wire solution makes cars smarter and safer
- 8051 MCU - Parity Check
- How to efficiently balance the sensitivity of tactile sensing interfaces
- What should I do if the servo motor shakes? What causes the servo motor to shake quickly?
- 【Brushless Motor】Analysis of three-phase BLDC motor and sharing of two popular development boards
- Midea Industrial Technology's subsidiaries Clou Electronics and Hekang New Energy jointly appeared at the Munich Battery Energy Storage Exhibition and Solar Energy Exhibition
- Guoxin Sichen | Application of ferroelectric memory PB85RS2MC in power battery management, with a capacity of 2M
- Analysis of common faults of frequency converter
- In a head-on competition with Qualcomm, what kind of cockpit products has Intel come up with?
- Dalian Rongke's all-vanadium liquid flow battery energy storage equipment industrialization project has entered the sprint stage before production
- Allegro MicroSystems Introduces Advanced Magnetic and Inductive Position Sensing Solutions at Electronica 2024
- Car key in the left hand, liveness detection radar in the right hand, UWB is imperative for cars!
- After a decade of rapid development, domestic CIS has entered the market
- Aegis Dagger Battery + Thor EM-i Super Hybrid, Geely New Energy has thrown out two "king bombs"
- A brief discussion on functional safety - fault, error, and failure
- In the smart car 2.0 cycle, these core industry chains are facing major opportunities!
- The United States and Japan are developing new batteries. CATL faces challenges? How should China's new energy battery industry respond?
- Murata launches high-precision 6-axis inertial sensor for automobiles
- Ford patents pre-charge alarm to help save costs and respond to emergencies
- New real-time microcontroller system from Texas Instruments enables smarter processing in automotive and industrial applications
- PCB technology: PROTEL's metal slot method
- [ATmega4809 Curiosity Nano Review] Using MCC to configure TCA
- circuitpy compass
- In a blink of an eye, half of this year has passed.
- Four opportunities for RF technology in the retail market
- The shield affects the sensitivity, and the inductor close to the DCDC affects the sensitivity
- RK3288 open source motherboard is very powerful
- Hello everyone! 2021 is here, and I would like to extend my best wishes for the New Year to everyone!
- EEWORLD University Hall----Live Replay: Introduction to Intel FPGA Programmable Acceleration Platform, Approaching AI, Data Center, Genetic Engineering and Other Major Projects
- TMS320F28379D Create Project