参阅 :STM32输入捕获形式设置并用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 controlleris configured in reset mode.
For example, you can measure the period (in TIMx_CCR1 register) and the duty cycle (inTIMx_CCR2 register)
of the PWM applied on TI1 using the following procedure (dependingon CK_INT frequency and prescaler value):
Select the active input for TIMx_CCR1: write the CC1S bits to 01 in the TIMx_CCMR1register (TI1 selected).
Select the active polarity for TI1FP1 (used both for capture in TIMx_CCR1 and counterclear): 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_CCMR1register (TI1 selected).
Select the active polarity for TI1FP2 (used for capture in TIMx_CCR2): write the CC2Pand 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 theTIMx_SMCR register.
Enable the captures: write the CC1E and CC2E bits to ‘1’ in the TIMx_CCER register.
STM32的PWM输入形式设置并用DMA接纳数据
项目中需求进行红外学习,假如选用输入捕获的方法,由于定时器只能捕获上升沿或许下降沿,
所以只能取得周期,而不能得到详细的红外波的凹凸电平的时刻.
所以选用PWM输入的方法进行捕获.选用的是PA8脚,对应TIM1的通道1.
/********************************************************************** 函数**********************************************************************//********************************************************************** 接口函数:初始化红外学习模块**********************************************************************/void inf_infrared_study_init( void ){//初始化io口inf_init_io( );//初始化中止//inf_init_irq();//初始化定时器inf_init_timer( );//翻开DMAinf_infrared_study_open_dma( 1 );//翻开定时器inf_infrared_study_open_timer( 1 );}/********************************************************************** 初始化io口**********************************************************************/static void inf_init_io( void ){//界说IO初始化结构体GPIO_InitTypeDef GPIO_InitStructure;//初始化时钟RCC_APB2PeriphClockCmd( RCC_APB2Periph_GPIOB, ENABLE );//管脚初始化 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8;//设置为输入 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;//初始化 GPIO_Init( GPIOA, &GPIO_InitStructure );}/********************************************************************** 初始化中止**********************************************************************/static void inf_init_irq( void ){//界说外部中止结构体EXTI_InitTypeDef EXTI_InitStructure;//初始化中止脚复用时钟RCC_APB2PeriphClockCmd( RCC_APB2Periph_AFIO, ENABLE );//装备中止源GPIO_EXTILineConfig( GPIO_PortSourceGPIOB, GPIO_PinSource1 );// 装备下降沿触发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 );}/********************************************************************** 初始化定时器**********************************************************************/static void inf_init_timer( void ){//界说定时器结构体TIM_TimeBaseInitTypeDef timInitStruct;//输入捕获结构体TIM_ICInitTypeDef tim_icinit;//界说DMA结构体DMA_InitTypeDef DMA_InitStructure;//发动DMA时钟RCC_AHBPeriphClockCmd( RCC_AHBPeriph_DMA1, ENABLE );//DMA1通道装备DMA_DeInit( DMA1_Channel2 );//外设地址DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t) ( &TIM1->CCR1 );//内存地址DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t) Rx_Buf_Tim_Dma1;//dma传输方向单向DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;//设置DMA在传输时缓冲区的长度DMA_InitStructure.DMA_BufferSize = RX_LEN_TIM_DMA;//设置DMA的外设递加形式,一个外设DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;//设置DMA的内存递加形式DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;//外设数据字长DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord;//内存数据字长DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord;//设置DMA的传输形式//DMA_InitStructure.DMA_Mode = DMA_Mode_Normal;DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;//设置DMA的优先等级DMA_InitStructure.DMA_Priority = DMA_Priority_High;//设置DMA的2个memory中的变量相互拜访DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;DMA_Init( DMA1_Channel2, &DMA_InitStructure );//发动DMA时钟RCC_AHBPeriphClockCmd( RCC_AHBPeriph_DMA1, ENABLE );//DMA1通道装备DMA_DeInit( DMA1_Channel3 );//外设地址DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t) ( &TIM1->CCR2 );//内存地址DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t) Rx_Buf_Tim_Dma2;//dma传输方向单向DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;//设置DMA在传输时缓冲区的长度DMA_InitStructure.DMA_BufferSize = RX_LEN_TIM_DMA;//设置DMA的外设递加形式,一个外设DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;//设置DMA的内存递加形式DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;//外设数据字长DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord;//内存数据字长DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord;//设置DMA的传输形式//DMA_InitStructure.DMA_Mode = DMA_Mode_Normal;DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;//设置DMA的优先等级DMA_InitStructure.DMA_Priority = DMA_Priority_High;//设置DMA的2个memory中的变量相互拜访DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;DMA_Init( DMA1_Channel3, &DMA_InitStructure );//敞开时钟RCC_APB2PeriphClockCmd( RCC_APB2Periph_TIM1, ENABLE );//从头将Timer设置为缺省值TIM_DeInit( TIM1 );//选用内部时钟供给时钟源TIM_InternalClockConfig( TIM1 );//预分频timInitStruct.TIM_ClockDivision = TIM_CKD_DIV1;//计数频率为500ns跳转1次 timInitStruct.TIM_Prescaler = SystemCoreClock / 1 - 1;//向上计数 timInitStruct.TIM_CounterMode = TIM_CounterMode_Up;timInitStruct.TIM_RepetitionCounter = 0;//这个值实际上便是TIMX->ARR,延时开始时从头设定即可 timInitStruct.TIM_Period = 0xffff;//初始化定时器TIM_TimeBaseInit( TIM1, &timInitStruct );//输入捕获装备//挑选通道tim_icinit.TIM_Channel = TIM_Channel_1;//硬件滤波tim_icinit.TIM_ICFilter = 0x0;//触发捕获的电平tim_icinit.TIM_ICPolarity = TIM_ICPolarity_Falling;//每次检测到触发电平都捕获tim_icinit.TIM_ICPrescaler = TIM_ICPSC_DIV1;//通道方向挑选tim_icinit.TIM_ICSelection = TIM_ICSelection_DirectTI;//初始化//TIM_ICInit(TIM1,&tim_icinit);TIM_PWMIConfig( TIM1, &tim_icinit );//制止ARR预装载缓冲器 //TIM_ARRPreloadConfig(TIM1, DISABLE); //输入跳变挑选TIM_SelectInputTrigger( TIM1, TIM_TS_TI1FP1 );//从机形式:复位形式TIM_SelectSlaveMode( TIM1, TIM_SlaveMode_Reset );//主从形式挑选TIM_SelectMasterSlaveMode( TIM1, TIM_MasterSlaveMode_Enable );//装备定时器的DMATIM_DMAConfig( TIM1, TIM_DMABase_CCR1, TIM_DMABurstLength_2Bytes );//发生DMA恳求信号TIM_DMACmd( TIM1, TIM_DMA_CC1, ENABLE );//装备定时器的DMATIM_DMAConfig( TIM1, TIM_DMABase_CCR2, TIM_DMABurstLength_2Bytes );//发生DMA恳求信号TIM_DMACmd( TIM1, TIM_DMA_CC2, ENABLE );//翻开定时器TIM_Cmd( TIM1, ENABLE );}/********************************************************************** 接口函数:翻开定时器*参数:state:状况:0:封闭,1:翻开**********************************************************************/void inf_infrared_study_open_timer( uint8_t state ){if ( state ){TIM_Cmd( TIM1, ENABLE );}else{TIM_Cmd( TIM1, DISABLE );}}/********************************************************************** 接口函数:翻开中止*参数:state:状况:0:封闭,1:翻开**********************************************************************/void inf_infrared_study_open_irq( uint8_t state ){//界说中止结构体NVIC_InitTypeDef NVIC_InitStructure;if ( state ){//翻开中止NVIC_InitStructure.NVIC_IRQChannel = EXTI1_IRQn; //通道设置为外部中止线NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1; //中止抢占先等级NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; //中止呼应优先级NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //翻开中止NVIC_Init( &NVIC_InitStructure ); //初始化}else{//封闭中止NVIC_InitStructure.NVIC_IRQChannel = EXTI1_IRQn; //通道设置为外部中止线NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1; //中止抢占先等级NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; //中止呼应优先级NVIC_InitStructure.NVIC_IRQChannelCmd = DISABLE; //翻开中止NVIC_Init( &NVIC_InitStructure ); //初始化}}/********************************************************************** 接口函数:翻开DMA*参数:state:状况:0:封闭,1:翻开**********************************************************************/void inf_infrared_study_open_dma( uint8_t state ){if ( state ){//设置传输数据长度//DMA_SetCurrDataCounter(DMA1_Channel3,RX_LEN_TIM_DMA);//翻开DMADMA_Cmd( DMA1_Channel2, ENABLE );DMA_Cmd( DMA1_Channel3, ENABLE );}else{DMA_Cmd( DMA1_Channel2, DISABLE );DMA_Cmd( DMA1_Channel3, ENABLE );}}/********************************************************************** 接口函数:得到DMA接纳帧长*回来:帧长**********************************************************************/uint16_t inf_infrared_study_dma_rx_len( void ){//取得接纳帧帧长return ( RX_LEN_TIM_DMA - DMA_GetCurrDataCounter( DMA1_Channel2 ) );}