参考 :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 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输入模式设置并用DMA接收数据

项目中需要进行红外学习,如果采用输入捕获的方式,因为定时器只能捕获上升沿或者下降沿,

所以只能获得周期,而不能得到具体的红外波的高低电平的时间.

所以采用PWM输入的方式进行捕获. 采用的是PA8脚,对应TIM1的通道1.

/*********************************************************************
* 函数
**********************************************************************/ /*********************************************************************
* 接口函数:初始化红外学习模块
**********************************************************************/ void inf_infrared_study_init( void )
{
//初始化io口
inf_init_io( );
//初始化中断
//inf_init_irq();
//初始化定时器
inf_init_timer( ); //打开DMA
inf_infrared_study_open_dma( );
//打开定时器
inf_infrared_study_open_timer( );
} /*********************************************************************
* 初始化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 / - ;
//向上计数
timInitStruct.TIM_CounterMode = TIM_CounterMode_Up;
timInitStruct.TIM_RepetitionCounter = ;
//这个值实际上就是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 ); //配置定时器的DMA
TIM_DMAConfig( TIM1, TIM_DMABase_CCR1, TIM_DMABurstLength_2Bytes );
//产生DMA请求信号
TIM_DMACmd( TIM1, TIM_DMA_CC1, ENABLE ); //配置定时器的DMA
TIM_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 = ; //中断抢占先等级
NVIC_InitStructure.NVIC_IRQChannelSubPriority = ; //中断响应优先级
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //打开中断
NVIC_Init( &NVIC_InitStructure ); //初始化
}
else
{
//关闭中断
NVIC_InitStructure.NVIC_IRQChannel = EXTI1_IRQn; //通道设置为外部中断线
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = ; //中断抢占先等级
NVIC_InitStructure.NVIC_IRQChannelSubPriority = ; //中断响应优先级
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);
//打开DMA
DMA_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 ) );
}

STM32的PWM输入模式设置并用DMA接收数据的更多相关文章

  1. STM32输入捕获模式设置并用DMA接收数据

    参考: STM32的PWM输入模式设置并用DMA接收数据 Input capture mode The input stage samples the corresponding TIx input ...

  2. STM32—无需中断来实现使用DMA接收串口数据

    本节目标: 通过DMA,无需中断,接收不定时长的串口数据 描述:当在串口多数据传输下,CPU会产生多次中断来接收串口数据,这样会大大地降低CPU效率,同时又需要CPU去做其它更重要的事情,我们应该如何 ...

  3. STM32串口DMA接收数据错位——暴力解决方法

    背景:两片STM32通过串口通信,为了减小CPU负担,采用DMA进行通信,发送端为STM32F103C8T6,接收端为STM32F407VET6.在调试的过程中发现,一直出现数据错位的问题,接收端尝试 ...

  4. STM32之串口DMA接收不定长数据

    STM32之串口DMA接收不定长数据 引言 在使用stm32或者其他单片机的时候,会经常使用到串口通讯,那么如何有效地接收数据呢?假如这段数据是不定长的有如何高效接收呢? 同学A:数据来了就会进入串口 ...

  5. STM32使用串口1配合DMA接收不定长数据,减轻CPU载荷

    STM32使用串口1配合DMA接收不定长数据,减轻CPU载荷 http://www.openedv.com/thread-63849-1-1.html 实现思路:采 用STM32F103的串口1,并配 ...

  6. STM32 串口USART DMA方式发送接收数据

    硬件:stm32f103cbt6 软件:STM32F10x_StdPeriph_Lib_V3.5.0 文章目录 头文件 USART3_DR的地址 DMA的通道 DMA的中断 USART接收回调函数 头 ...

  7. STM32之PWM波形输出配置总结

    一.   TIMER分类: STM32中一共有11个定时器,其中TIM6.TIM7是基本定时器:TIM2.TIM3.TIM4.TIM5是通用定时器:TIM1和TIM8是高级定时器,以及2个看门狗定时器 ...

  8. stm32之PWM学习

    下图是一个STM32普通PWM形成的图形原理说明 自动重装载寄存器(ARR)用于确定波形的频率(即周期).捕获比较寄存器(CCRx)(用于确定占空比的) PWM的工作过程如下:首先ARR寄存器里面的值 ...

  9. STM32之PWM君

    PWM..英语好的人估计又知道这三个大写字母代表哪三个英语单词了.小弟不才,就说中文意思好了:脉冲宽度调制,玩过飞思卡尔的人估计对PWM非常的不陌生吧.电机驱动需要PWM,控制舵机的转向需要PWM,总 ...

随机推荐

  1. 通俗易懂之Tensorflow summary类 & 初识tensorboard

    前面学习的cifar10项目虽小,但却五脏俱全.全面理解该项目非常有利于进一步的学习和提高,也是走向更大型项目的必由之路.因此,summary依然要从cifar10项目说起,通俗易懂的理解并运用sum ...

  2. 01 uni-app框架学习:项目创建及底部导航栏tabBar配置

    1.创建一个项目类型选择uniapp 2. pages里新建3个页面如下 3.在pages.json中配置底部导航tabBar 效果展示:

  3. 转:Citrix虚拟化--转自CSDN

    http://blog.csdn.net/kkfloat/article/category/1430751/3

  4. USB枚举过程【转】

    转自:http://blog.csdn.net/myarrow/article/details/8270029 1. 枚举是什么?        枚举就是从设备读取一些信息,知道设备是什么样的设备,如 ...

  5. 初始ASP.NET数据控件【续 DataList】

    DataList控件  DataList控件也是一个常用的数据绑定控件,相对于GridView控件虽然没它那么强大的功能,但是灵活性却很强势.因为其本身就是一个富有弹性的控件.DataList控件可以 ...

  6. HTTP2.0新特性

    参考:http://www.tuicool.com/articles/mq2qm26

  7. nodejs抓取别人家的页面的始末

    内容:分析并获取页面调取数据的API(接口),并跨域获取数据保存在文档中(nodejs做代理-CORS) 事由以及动机 2015年9月份全国研究生数学建模竞赛的F题,旅游线路规划问题.其中需要自己去查 ...

  8. Java基础86 MySQL数据库基础知识

    本文知识点(目录): 1.MySQL数据库的概述    2.MySQL数据库的管理[对数据库的操作](查询.删除.创建数据库,以及查询和修改数据库的编码模式)    3.表的管理[对数据库 表的操作] ...

  9. SecureCRT中常用linux命令 -《转载》

    常用命令: 一.ls 只列出文件名 (相当于dir,dir也可以使用) -A:列出所有文件,包含隐藏文 件. -l:列表形式,包含文件的绝大部分属性. -R:递归显示. --help:此命令的帮助. ...

  10. maven待整理

    http://blog.csdn.net/column/details/yuguiyang-maven.html?&page=2