STM32的PWM输入模式设置并用DMA接收数据
参考 :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接收数据的更多相关文章
- STM32输入捕获模式设置并用DMA接收数据
参考: STM32的PWM输入模式设置并用DMA接收数据 Input capture mode The input stage samples the corresponding TIx input ...
- STM32—无需中断来实现使用DMA接收串口数据
本节目标: 通过DMA,无需中断,接收不定时长的串口数据 描述:当在串口多数据传输下,CPU会产生多次中断来接收串口数据,这样会大大地降低CPU效率,同时又需要CPU去做其它更重要的事情,我们应该如何 ...
- STM32串口DMA接收数据错位——暴力解决方法
背景:两片STM32通过串口通信,为了减小CPU负担,采用DMA进行通信,发送端为STM32F103C8T6,接收端为STM32F407VET6.在调试的过程中发现,一直出现数据错位的问题,接收端尝试 ...
- STM32之串口DMA接收不定长数据
STM32之串口DMA接收不定长数据 引言 在使用stm32或者其他单片机的时候,会经常使用到串口通讯,那么如何有效地接收数据呢?假如这段数据是不定长的有如何高效接收呢? 同学A:数据来了就会进入串口 ...
- STM32使用串口1配合DMA接收不定长数据,减轻CPU载荷
STM32使用串口1配合DMA接收不定长数据,减轻CPU载荷 http://www.openedv.com/thread-63849-1-1.html 实现思路:采 用STM32F103的串口1,并配 ...
- STM32 串口USART DMA方式发送接收数据
硬件:stm32f103cbt6 软件:STM32F10x_StdPeriph_Lib_V3.5.0 文章目录 头文件 USART3_DR的地址 DMA的通道 DMA的中断 USART接收回调函数 头 ...
- STM32之PWM波形输出配置总结
一. TIMER分类: STM32中一共有11个定时器,其中TIM6.TIM7是基本定时器:TIM2.TIM3.TIM4.TIM5是通用定时器:TIM1和TIM8是高级定时器,以及2个看门狗定时器 ...
- stm32之PWM学习
下图是一个STM32普通PWM形成的图形原理说明 自动重装载寄存器(ARR)用于确定波形的频率(即周期).捕获比较寄存器(CCRx)(用于确定占空比的) PWM的工作过程如下:首先ARR寄存器里面的值 ...
- STM32之PWM君
PWM..英语好的人估计又知道这三个大写字母代表哪三个英语单词了.小弟不才,就说中文意思好了:脉冲宽度调制,玩过飞思卡尔的人估计对PWM非常的不陌生吧.电机驱动需要PWM,控制舵机的转向需要PWM,总 ...
随机推荐
- es6笔记(1) 概要
什么是ES6 ECMAScript 6.0 (简称ES6) 是继ECMAScript 5.1以后的javascript 语言的下一代标准,在2015年6月份发布. 他的目标是使javascript语言 ...
- python技巧 is 和 ==
is 判断变量是否指向同一个对象 == 判断变量引用的对象是否相等 In [2]: a=[1,2] In [3]: b=a In [4]: a == b Out[4]: True In [5]: a ...
- Python3中的内置函数
内置函数 我们一起来看看python里的内置函数.什么是内置函数?就是Python给你提供的,拿来直接用的函数,比如print,input等等.截止到python版本3.6.2,现在python一共为 ...
- 通俗理解决策树中的熵&条件熵&信息增益
参考通俗理解决策树算法中的信息增益 说到决策树就要知道如下概念: 熵:表示一个随机变量的复杂性或者不确定性. 假如双十一我要剁手买一件衣服,但是我一直犹豫着要不要买,我决定买这件事的不确定性(熵)为2 ...
- 2017/05/20 java 基础 随笔
static 关键字的特点 1.随着类的加载而加载 2.优先于对象存在 3.被类的所有对象共享 如果某个成员变量是被所有对象共享的,那么他就应该定义为静态的 4.可以通过类名调用 其实它本身也可以通过 ...
- Java基本数据类型装箱的127临界点
package wrapper.demo; public class WrapperDemo { /** * @param args */ public static void main(String ...
- Ubuntu下SSH安装
step: 1.输入命令: sudo apt-get install openssh-server 2.验证sshserver是否启动了,以下两条命令均可 ps -e | grep ssh netst ...
- NET WebAPi之断点续传下载(下)
NET WebAPi之断点续传下载(下) 前言 上一篇我们穿插了C#的内容,本篇我们继续来讲讲webapi中断点续传的其他情况以及利用webclient来实现断点续传,至此关于webapi断点续传下载 ...
- pageHelper 排序 +- 字符串处理
自己记录一下. 前端要把sort参数传过来, 1. 如果约定是下面这种形式: sort=id-name+age+ 直接在java后台进行替换就行,连正则都不用. sort = sort.replace ...
- 解决 Could not resolve com.android.tools.build:gradle:3.1.3
android studio 升级到3.1.3后总会遇到莫名其妙的错误,前几天刚解决了项目 dependencies报错的问题. 解决android studio 升级到3.0+之后 项目 dep ...