STM32 PWM input mode setting and receiving data using DMA

Publisher:水手谷水手Latest update time:2016-06-15 Source: eefocusKeywords:STM32 Reading articles on mobile phones Scan QR code
Read articles on your mobile phone anytime, anywhere

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

 

 

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 ) );
}

 

Keywords:STM32 Reference address:STM32 PWM input mode setting and receiving data using DMA

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

STM32 firmware library naming convention
1. System file names and source file names are expressed in the form of 'stm32f10x_'. 2. Constants used in a single file are defined in that file. Constants used in multiple files are defined in header files. All constants are expressed in uppercase letters. 3. Registers are treated as constants and are also represent
[Microcontroller]
mini2440 bare metal DMA (1)
Chapter 8 Direct Memory Access (DMA) In the DMA chapter, there are four channels of DMA sources, and each source consists of 9 registers. So we only need to configure a few registers to operate DMA. Here we mainly explain channel 0 The first register DISRC pDMA- DISRC=srcAddr; //Set source address The secon
[Microcontroller]
mini2440 bare metal DMA (1)
STM32 standard IIC driver
IIC (Inter-Integrated Circuit) bus is a two-wire serial bus developed by PHILIPS for connecting Microcontrollers and their peripherals. It is also a very popular communication bus. Using IIC bus to make products can greatly reduce the difficulty of PCB wiring and the number of wiring, so many companies give priority t
[Microcontroller]
STM32 standard IIC driver
STM32 study notes one by one USART
1. Basic concepts of serial ports The Universal Synchronous Asynchronous Receiver/Transmitter (USART) provides a flexible method for full-duplex data exchange with external devices using the industry standard NRZ asynchronous serial data format. USART uses a fractional baud rate generator to provide a wide range of
[Microcontroller]
STM32 study notes one by one USART
STM32 ADC DMA USART comprehensive learning
Learn STM32 ADC conversion and write and debug programs on the development board. Four tasks: 1. AD collects one channel in interrupt mode (single) 2.AD continuously collects four channels in interrupt mode 3. AD collects one channel in DMA mode, and the DMA depth is one level 4. AD collects four channels in
[Microcontroller]
LED lighting design pulse modulation PWM circuit detailed explanation
LED lighting has received widespread attention as a new generation of lighting. Relying solely on LED packaging cannot produce good lighting fixtures. This article mainly explains how to use LED characteristics for design from the aspects of electronic circuits, thermal analysis, and opti
[Power Management]
LED lighting design pulse modulation PWM circuit detailed explanation
STM32 dma mode sends pulses for position control
Considering that there is no FPGA on the existing board, the design of DMA pulse position control is as follows Two buffs short buff1 ; short buff2 ; store frequency values, that is, the value of the ARP register. The length of the array is 1000, considering the highest pulse frequency. If the maximum frequenc
[Microcontroller]
【STM32】Some understanding of FSMC
(1) Address in FSMC: I have read many tutorials online, and they are almost identical. I am confused. Regarding the address line, many people wrote: "For example, to set FSMC_A16 high, just operate on the address: 60000000 + 2^16*2". I have been struggling with the question of why "*2" is needed. I have been thinking
[Microcontroller]
【STM32】Some understanding of FSMC
Latest Microcontroller Articles
  • Download from the Internet--ARM Getting Started Notes
    A brief introduction: From today on, the ARM notebook of the rookie is open, and it can be regarded as a place to store these notes. Why publish it? Maybe you are interested in it. In fact, the reason for these notes is ...
  • Learn ARM development(22)
    Turning off and on interrupts Interrupts are an efficient dialogue mechanism, but sometimes you don't want to interrupt the program while it is running. For example, when you are printing something, the program suddenly interrupts and another ...
  • Learn ARM development(21)
    First, declare the task pointer, because it will be used later. Task pointer volatile TASK_TCB* volatile g_pCurrentTask = NULL;volatile TASK_TCB* vol ...
  • Learn ARM development(20)
    With the previous Tick interrupt, the basic task switching conditions are ready. However, this "easterly" is also difficult to understand. Only through continuous practice can we understand it. ...
  • Learn ARM development(19)
    After many days of hard work, I finally got the interrupt working. But in order to allow RTOS to use timer interrupts, what kind of interrupts can be implemented in S3C44B0? There are two methods in S3C44B0. ...
  • Learn ARM development(14)
  • Learn ARM development(15)
  • Learn ARM development(16)
  • Learn ARM development(17)
Change More Related Popular Components

EEWorld
subscription
account

EEWorld
service
account

Automotive
development
circle

About Us Customer Service Contact Information Datasheet Sitemap LatestNews


Room 1530, 15th Floor, Building B, No.18 Zhongguancun Street, Haidian District, Beijing, Postal Code: 100190 China Telephone: 008610 8235 0740

Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved 京ICP证060456号 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号