参考: STM32的PWM输入模式设置并用DMA接收数据

Input capture mode

The input stage samples the corresponding TIx input to generate a filtered signal TIxF.

Then, an edge detector with polarity selection generates a signal (TIxFPx)

which can be used as trigger input by the slave mode controller or as the capture command.

It is prescaled before the capture register (ICxPS).

In Input capture mode, the Capture/Compare Registers (TIMx_CCRx) are used to latch the value of the counter

after a transition detected by the corresponding ICx signal.

When a capture occurs, the corresponding CCXIF flag (TIMx_SR register) is set and an interrupt

or a DMA request can be sent if they are enabled.

If a capture occurs while the CCxIF flag was already high, then the over-capture flag CCxOF (TIMx_SR register) is set.

CCxIF can be cleared by software by writing it to ‘0’ or by reading the captured data stored in the TIMx_CCRx register.

CCxOF is cleared when you write it to ‘0’.

The following example shows how to capture the counter value in TIMx_CCR1 when TI1 input rises.

To do this, use the following procedure:

 Select the active input:
TIMx_CCR1 must be linked to the TI1 input, so write the CC1S bits to 01 in the TIMx_CCMR1 register.
As soon as CC1S becomes different from 00, the channel is configured in input and the TIMx_CCR1 register becomes read-only.

 Program the input filter duration you need with respect to the signal you connect to the timer
(by programming ICxF bits in the TIMx_CCMRx register if the input is a TIx input).
Let’s imagine that, when toggling, the input signal is not stable during at must 5 internal clock cycles.
We must program a filter duration longer than these 5 clock cycles.
We can validate a transition on TI1 when 8 consecutive samples with the new level have been detected (sampled at fDTS frequency).
Then write IC1F bits to 0011 in the TIMx_CCMR1 register.

 Select the edge of the active transition on the TI1 channel by writing CC1P and CC1NP bits to 0
in the TIMx_CCER register (rising edge in this case).

 Program the input prescaler. In our example, we wish the capture to be performed at each valid transition,
so the prescaler is disabled (write IC1PS bits to ‘00’ in the TIMx_CCMR1 register).

 Enable capture from the counter into the capture register by setting the CC1E bit in the TIMx_CCER register.
 If needed, enable the related interrupt request by setting the CC1IE bit in the TIMx_DIER register,
and/or the DMA request by setting the CC1DE bit in the TIMx_DIER register.

When an input capture occurs:
 The TIMx_CCR1 register gets the value of the counter on the active transition.
 CC1IF flag is set (interrupt flag). CC1OF is also set if at least two consecutive captures occurred whereas the flag was not cleared.
 An interrupt is generated depending on the CC1IE bit.
 A DMA request is generated depending on the CC1DE bit.
In order to handle the overcapture, it is recommended to read the data before the overcapture flag.
This is to avoid missing an overcapture which could happen after reading the flag and before reading the data.

Note:

IC interrupt and/or DMA requests can be generated by software by setting the corresponding CCxG bit in the TIMx_EGR register.

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

本文博客链接:http://blog.csdn.net/jdh99,作者:jdh

环境:

主机:WIN7

开发环境:MDK4.72

MCU:STM32F103

说明:

项目中需要进行红外学习,于是采用输入捕获取得电平变化时间.并将数据放在DMA中.这样可以避免频繁中断消耗CPU资源.

采用的是PB1脚,对应TIM3的通道4.

/*********************************************************************
*                            接口函数:初始化红外学习模块
**********************************************************************/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_1;//设置为输入           GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; //初始化                GPIO_Init(GPIOB, &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通道3配置
    DMA_DeInit(DMA1_Channel3);//外设地址DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)(&TIM3->CCR4);//内存地址DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)Rx_Buf_Tim_Dma;//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_APB1PeriphClockCmd(RCC_APB1Periph_TIM3,ENABLE);//重新将Timer设置为缺省值
    TIM_DeInit(TIM3);//采用内部时钟给TIM3提供时钟源
    TIM_InternalClockConfig(TIM3);//预分频timInitStruct.TIM_ClockDivision = TIM_CKD_DIV1;    //计数频率为500ns跳转1次             timInitStruct.TIM_Prescaler = SystemCoreClock / 2000000 - 1;     //向上计数                  timInitStruct.TIM_CounterMode = TIM_CounterMode_Up;     timInitStruct.TIM_RepetitionCounter = 0;//这个值实际上就是TIMX->ARR,延时开始时重新设定即可    timInitStruct.TIM_Period = 0xffff;                                 //初始化定时器3TIM_TimeBaseInit(TIM3, &timInitStruct);//输入捕获配置//选择通道tim_icinit.TIM_Channel = TIM_Channel_4;//硬件滤波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(TIM3,&tim_icinit);//禁止ARR预装载缓冲器
    TIM_ARRPreloadConfig(TIM3, DISABLE);  //输入跳变选择
    TIM_SelectInputTrigger(TIM3, TIM_TS_TI2FP2);//从机模式:复位模式
    TIM_SelectSlaveMode(TIM3, TIM_SlaveMode_Reset);//主从模式选择
    TIM_SelectMasterSlaveMode(TIM3, TIM_MasterSlaveMode_Enable);//配置定时器的DMA
    TIM_DMAConfig(TIM3,TIM_DMABase_CCR4,TIM_DMABurstLength_2Bytes);//产生DMA请求信号
    TIM_DMACmd(TIM3, TIM_DMA_CC4, ENABLE);//打开定时器
    TIM_Cmd(TIM3, ENABLE);
}/*********************************************************************
*                            接口函数:打开定时器
*参数:state:状态:0:关闭,1:打开
**********************************************************************/void inf_infrared_study_open_timer(uint8_t state)
{if (state){TIM_Cmd(TIM3, ENABLE);}else{TIM_Cmd(TIM3, 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);//打开DMA
        DMA_Cmd(DMA1_Channel3,ENABLE);}else{DMA_Cmd(DMA1_Channel3,DISABLE);}
}/*********************************************************************
*                            接口函数:得到DMA接收帧长
*返回:帧长
**********************************************************************/uint16_t inf_infrared_study_dma_rx_len(void)
{//获得接收帧帧长return (RX_LEN_TIM_DMA - DMA_GetCurrDataCounter(DMA1_Channel3));
}

注意:

除TIM6和TIM7之外的定时器都只能采用上升沿或者下降沿捕捉而不能采用双边沿捕捉.

#define  TIM_ICPolarity_Rising             ((uint16_t)0x0000)
#define  TIM_ICPolarity_Falling            ((uint16_t)0x0002)
#define  TIM_ICPolarity_BothEdge           ((uint16_t)0x000A)
#define IS_TIM_IC_POLARITY(POLARITY) (((POLARITY) == TIM_ICPolarity_Rising) || ((POLARITY) == TIM_ICPolarity_Falling))
#define IS_TIM_IC_POLARITY_LITE(POLARITY) (((POLARITY) == TIM_ICPolarity_Rising) || ((POLARITY) == TIM_ICPolarity_Falling)|| ((POLARITY) == TIM_ICPolarity_BothEdge))  

STM32输入捕获模式设置并用DMA接收数据相关推荐

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

    STM32的PWM输入模式设置并用DMA接收数据 本文博客链接:http://blog.csdn.net/jdh99,作者:jdh,转载请注明. 环境: 主机:WIN7 开发环境:MDK4.72 MC ...

  2. 【蓝桥杯嵌入式】【STM32】13_PWM输入捕获模式

    文章目录 前言 1.PWM输入模式 2.硬件设计 3.软件设计 前言   STM32的定时器输入捕获模式可以通过更改输入捕获极性实现PWM的输入捕获,但实际上STM32也包含有非常方便的PWM输入捕获 ...

  3. stm32 输入捕获学习(一)

    输入捕获模式可以用来测量脉冲宽度或者测量频率.STM32 的定时器,除了 TIM6 和 TIM7,其他定时器都有输入捕获功能.STM32 的输入捕获,简单地说就是通过检测 TIMx_CHx 上的边沿信 ...

  4. stm32 输入捕获 测量脉宽

    选用通用定时器TIM5的CH1. PA0接一个按键,默认接GND,当按键按下时,IO口被拉高,此时,可利用定时器的输入捕获功能,测量按键按下的这段高电平的时间. 宏定义方便程序升级.移植,举个例子: ...

  5. STM32 输入捕获 测量频率 PWM占空比

    看了网上关于STM32输入捕获的资料,有几篇介绍的很不错,但是内容上还有一点问题,稍加修改,大家可以参考一下. 重要概念理解(对于理解输入捕获功能很重要,特别看了数据手册CCR1\CCR2\CCR3\ ...

  6. STM32输入捕获实验

    STM32 输入捕获工作过程(通道1为例) 通过检测TIMx_CHx上的边沿信号,在边沿信号发生跳变(比如上升沿/下降沿)的时候,将当前定时器的值(TIMx_CNT)存放到对应的捕获/比较寄存器(TI ...

  7. STM32——输入捕获

    输入捕获简介: STM32F4除了基本定时器TIM6和TIM7,其他定时器都具有输入捕获功能.输入捕获可以对输入的信号的上升沿,下降沿或者双边沿进行捕获,通常用于测量输入信号的脉宽.测量 PWM 输入 ...

  8. STM32 输入捕获的脉冲宽度及频率计算

    输入捕获模式可以用来测量脉冲宽度或者测量频率.STM32 的定时器,除了 TIM6 和 TIM7,其他定时器都有输入捕获功能.以下是对脉冲宽度及频率的计算. 1.脉冲宽度 如下图所示,采集该高电平脉冲 ...

  9. STM32输入捕获-脉宽测量

    目录 1. 输入捕获简介 2. 硬件设计 3. 软件设计 3.1 cubemx设置 3.2 程序开发 1. 输入捕获简介 在输入捕获模式下,当检测到ICx信号上相应的边沿后,计数器的当前值被锁存到捕获 ...

最新文章

  1. C# 驱动连接 MongoDB ReplSet
  2. 更新假设raw file(audio file format) How to convert endianness
  3. 回溯法解决01背包问题
  4. MTK 驱动 Kernel-3.18中如何配置和使用spi
  5. dicom worklist、pacs环境搭建
  6. 十本数据结构与算法书籍推荐
  7. js 新年倒计时 代码
  8. 什么是工业DTU?工业DTU特点及应用领域分析
  9. 批量删除微博(转载)
  10. 杨华杰 清华大学计算机,软件工程课程设计机票预订系统【参考】.doc
  11. c语言产生瑞利分布随机数,瑞利分布的随机数
  12. unity-IL2CPP工程打包失败记录
  13. 转专业计算机类面试自我介绍,转专业面试自我介绍
  14. T---EXCEL表格换行
  15. 美国oracle球场,【Dubnation翻译】甲骨文球馆的恢弘“绝唱”
  16. 大商创MySQL不支持_大商创配置文件config.php详解
  17. 【JavaSE】02-变量、数据类型和运算符
  18. (翻译)2016美国数学建模MCM D题 翻译:测量协会信息网络的演变和影响
  19. Chapter5.2:频率响应法
  20. Linux磁盘分区论文3000字,磁盘分区对齐详解与配置 – Linux篇

热门文章

  1. 博士生DIY超级显微镜,直接看到原子!网友:太极客了,一下省出几十万元
  2. 它来了!无人车穿梭在深圳的“宇宙最强街道”
  3. 华为开源自研AI框架MindSpore!自动微分、并行加持,一次训练,可多场景部署...
  4. 不戴口罩还想出门?硬核口罩佩戴检测模型向你发出警告
  5. 为什么Android变得对商业世界至关重要?
  6. Error:java: Compilation failed: internal java compiler
  7. ONOS项目首赢11000次下载 Oracle发布云路由
  8. Docker命令查询
  9. 生成器generator
  10. MSSQL2000+asp.net+论坛安装过程