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

发布者:紫色小猫最新更新时间:2016-05-25 来源: eefocus关键字:STM32  输入捕获  模式设置  DMA  接收数据 手机看文章 扫描二维码
随时随地手机看文章

参考: 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).

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

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

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();
    
    //打开DMA
    inf_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 / 2 - 1;     
    //向上计数                  
    timInitStruct.TIM_CounterMode = TIM_CounterMode_Up;     
    timInitStruct.TIM_RepetitionCounter = 0;
    //这个值实际上就是TIMX->ARR,延时开始时重新设定即可    
    timInitStruct.TIM_Period = 0xffff;                                 
    //初始化定时器3
    TIM_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)0x0)
#define  TIM_ICPolarity_Falling            ((uint16_t)0x2)
#define  TIM_ICPolarity_BothEdge           ((uint16_t)0xA)
#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  接收数据 引用地址:STM32输入捕获模式设置并用DMA接收数据

上一篇:STM32时钟配置方法详解
下一篇:STM32的定时器有两种捕获模式——PWM输入模式和普通输入模式

推荐阅读最新更新时间:2024-03-16 14:54

STM32网络ETH
芯片是:STM32F207VCT6 本人主要介绍STM32F207VCT6的ETH部分,基本是把ETH部分英文翻译一下,加上自己的理解。 1、基础介绍 通过DMA控制器进行介质访问控制 这部分内容应用于STM32F20X和STM32F21系列,其他的 不适用 28.1 以太网简介 部分版权 2004 2005 新思科技(美国公司)。所有权利保留,使用需要认可。 借助STM32F20X和STM32F21的以太网外设可接受和发送数据按照IEE 802.3-2002标准 以太网提供一个完整的、灵活的外设去满足不同应用和要求。它支持与外部相连(PHY)的两个标准的工业接口:默认情况使用在IEEE802.3规范找中定义
[单片机]
<font color='red'>STM32</font>网络ETH
DSP与STM32区别
如果我需要很多高级的接口,比如以太网和USB,那么我自然选STM32,如果我需要实现一些算法,那肯定会选DSP。如果你对运算速度不敏感,反正72M的速度已经比原先单片机快很多了,那当然是看你熟悉哪个,哪个价格比较好,支持比较好。 从51 AVR到DSP最大的障碍 1、应该是编译环境吧,TI的DSP都用的是CCS,CCS界面和原先IAR区别不是一般的大,比如程序导入,比如观察变量,比如烧写FLASH。恩,是的。用过了IAR那种傻瓜化的操作了之后,真是怎么弄怎么别扭,CCS真是太不友好了。但是没办法,IAR他们是专门做编译软件的,TI主要是做DSP的,TI也意识到这个问题了,所以现在推出的CCSV4好像在这方面有很大的加强。不过网
[单片机]
如何快速上手STM32学习?
单片机用处这么广,尤其是STM32生态这么火!如何快速上手学习呢? 你要考虑的是,要用STM32实现什么? 为什么使用STM32而不是用8051?是因为51的频率太低,无法满足计算需求?是51的管脚太少,无法满足众多外设的IO?是51的功耗太大,电池挺不住?是51的内存太小而你要存储的东西太多?还是51的功能太弱,而你要使用SPI、I2C、ADC、DMA? 当你需要使用STM32某些功能,而51实现不了的时候,那STM32自然不需要学习,你会直接去寻找STM32某方面的使用方法。比如要用spi协议的网卡、要使用串口通信、要使用rtos等等。 寄存器vs库函数 我的观点是:当你debug的时候寄存器很重要,当你需要理解芯片工作细
[单片机]
如何根据需求对STM32系列单片机选型
随着科技的飞速发展,单片机在各行业应用中扮演着越来越重要的角色。STM32系列单片机无疑是市场上广受欢迎的微控制器之一,凭借其丰富的产品线及卓越性能,赢得了大量用户的青睐。那么,如何根据实际需求进行STM32系列单片机选型呢?将为您提供详细的选型指导,助您打造理想的微控制器系统。 一、了解STM32系列单片机产品线 STM32系列单片机基于ARM Cortex-M内核,按性能划分为四个系列:STM32F0 (入门级)、STM32F1 (基本级)、STM32F2 (高性能) 和 STM32F4 (高性能 + DSP)。每个系列都有多个子系列,涵盖了不同的性能、外设和封装特点。因此,在选型过程中,首先要了解STM32的各个系列及其
[单片机]
STM32--对原子哥USART实验中printf重定向进行分析
原子哥的USART代码中,有一部分感觉看得不是很懂 #if 1 #pragma import(__use_no_semihosting) //标准库需要的支持函数 struct __FILE { int handle; /* Whatever you require here. If the only file you are using is */ /* standard output using printf() for debugging, no file handling */ /* is required. */ }; /* FILE is typedef
[单片机]
基于stm32的4X4矩阵键盘定时器扫描消抖法,彻底告别delay函数
经本人刻苦钻研,将51单片机上用的矩阵键盘扫描程序移植到了stm32上,同时也做了很大的改进,最大的改进莫过于消抖这块了。以前的消抖总是采用delay延时约10到20ms的时间,但这样会导致MCU在延时里空跑而造成主程序被搁置,显然,程序的实时性大打折扣,今天便在此让新手们别delay,从此走进一个崭新的扫描消抖世界!(本人也是新手——爱钻研的新手哈!^_^) //stm32矩阵键盘翻转扫描法(PB口的低8位) //将此矩阵键盘扫描程序放在定时器中断服务程序里 //每10ms进入一次中断服务程序 s8 scan_MatrixKey(void) { #define PORT GPIOB- IDR u8 colum
[单片机]
STM32的时钟树深入详解
在STM32上如果不使用外部晶振,OSC_IN和OSC_OUT的接法 如果使用内部RC振荡器而不使用外部晶振,请按照下面方法处理: 1)对于100脚或144脚的产品,OSC_IN应接地,OSC_OUT应悬空。 2)对于少于100脚的产品,有2种接法: 2.1)OSC_IN和OSC_OUT分别通过10K电阻接地。此方法可提高EMC性能。 2.2)分别重映射OSC_IN和OSC_OUT至PD0和PD1,再配置PD0和PD1为推挽输出并输出'0'。此方法可以减小功耗并(相对上面2.1)节省2个外部电阻。 HSI内部8MHz的RC振荡器的误差在1%左右,内部RC振荡器的精度通常比用HSE(外部晶振)
[单片机]
STM32数据类型基础介绍
首先说一下编程过程中几个步骤吧 第一,选择一门语言,C语言或汇编语言,嵌入式编程一般目前流行还是C,这个需要基础与时间 第二读懂了解 MCU的寄存器各寄存器的功能,尤其是一些IO口设置,各模块时钟设置比如定时器,I2C,同步异步串口,PWM等等,以前的话51的话没有这样设置。而现在MCU基本上各模块时钟都分开了。这个可以看官方数据说明书就可以了。 其实程的目的就是设置一系列寄存器.并根据你设计程序流程去执行它,期间可能加入了你设计好的一些算法,和数学公式。进行计算,或执行。 第三,你有一块你的实验板就如这次STM32推的F429,你还需要下载程序的编程器。就是把编译器编译好的代码下载到你的目标实验板上,不过ST推的多数
[单片机]
<font color='red'>STM32</font>的<font color='red'>数据</font>类型基础介绍
小广播
添点儿料...
无论热点新闻、行业分析、技术干货……
设计资源 培训 开发板 精华推荐

最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

换一换 更多 相关热搜器件
电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved