请教STM32的555定时器器DMA问题

cortex_m3_stm32嵌入式学习笔记(十):输入捕捉实验(定时器的输入捕捉)
时间: 20:21:01
&&&& 阅读:7346
&&&& 评论:
&&&& 收藏:0
标签:输入捕获模式可以用来测量脉冲宽度或者测量频率。 STM32 的定时器,除了 TIM6 和 TIM7,其他定时器都有输入捕获功能。 STM32 的输入捕获,简单的说就是通过检测 TIMx_CHx 上的边沿信号,在边沿信号发生跳变(比如上升沿/下降沿)的时候,将当前定时器的值(
TIMx_CNT)存放到对应的通道的捕获/比较寄存器( TIMx_CCRx)里面,完成一次捕获。同时还可以配置捕获时是否触发中断/DMA 等。
本章我们用到 TIM2_CH1 来捕获高电平脉宽,也就是要先设置输入捕获为上升沿检测,记录发生上升沿的时候
TIM2_CNT 的值。然后配置捕获信号为下降沿捕获,当下降沿到来时,发生捕获,并记录此时的 TIM2_CNT 值。这样,前后两次 TIM2_CNT 之差,就是高电平的脉宽,同时 TIM2 的计数频率我们是知道的,从而可以计算出高电平脉宽的准确时间。
至于为什么TIM2_CH1来测量WK_UP的脉宽。。看图:
显然,TIM_CH1是连在PA0上的。。
本节实验是在上节PWM的基础上改动的
#include &timer.h&
#include &led.h&
#include &sys.h&
#include &usart.h&
//PWM 输出初始化
//arr:自动重装值
//psc:时钟预分频数
void TIM1_PWM_Init(u16 arr,u16 psc)
GPIO_InitTypeDef GPIO_InitS
TIM_TimeBaseInitTypeDef
TIM_TimeBaseS
TIM_OCInitTypeDef
TIM_OCInitS
RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM1, ENABLE);//
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA , ENABLE);
//使能GPIO外设时钟使能
//设置该引脚为复用输出功能,输出TIM1 CH2的PWM脉冲波形
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8; //TIM_CH2
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
//复用推挽输出
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &GPIO_InitStructure);
TIM_TimeBaseStructure.TIM_Period = //设置在下一个更新事件装入活动的自动重装载寄存器周期的值
TIM_TimeBaseStructure.TIM_Prescaler = //设置用来作为TIMx时钟频率除数的预分频值
TIM_TimeBaseStructure.TIM_ClockDivision = 0; //设置时钟分割:TDTS = Tck_tim
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
//TIM向上计数模式
TIM_TimeBaseInit(TIM1, &TIM_TimeBaseStructure); //根据TIM_TimeBaseInitStruct中指定的参数初始化TIMx的时间基数单位
TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM2; //选择定时器模式:TIM脉冲宽度调制模式2
TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_E //比较输出使能
TIM_OCInitStructure.TIM_Pulse = 0; //设置待装入捕获比较寄存器的脉冲值
TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_H //输出极性:TIM输出比较极性高
TIM_OC1Init(TIM1, &TIM_OCInitStructure);
//根据TIM_OCInitStruct中指定的参数初始化外设TIMx
TIM_CtrlPWMOutputs(TIM1,ENABLE); //MOE 主输出使能
TIM_OC1PreloadConfig(TIM1, TIM_OCPreload_Enable);
//CH1预装载使能
TIM_ARRPreloadConfig(TIM1, ENABLE); //使能TIMx在ARR上的预装载寄存器
TIM_Cmd(TIM1, ENABLE);
//使能TIM1
void TIM2_Cap_Init(u16 arr,u16 psc)
TIM_ICInitTypeDef
TIM2_ICInitS
GPIO_InitTypeDef GPIO_InitS
TIM_TimeBaseInitTypeDef
TIM_TimeBaseS
NVIC_InitTypeDef NVIC_InitS
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE); //使能TIM2时钟
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
//使能GPIOA时钟
GPIO_InitStructure.GPIO_Pin
= GPIO_Pin_0;
//PA0 清除之前设置
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPD; //PA0 输入
GPIO_Init(GPIOA, &GPIO_InitStructure);
GPIO_ResetBits(GPIOA,GPIO_Pin_0);
//PA0 下拉
//初始化定时器2 TIM2
TIM_TimeBaseStructure.TIM_Period = //设定计数器自动重装值
TIM_TimeBaseStructure.TIM_Prescaler =
//预分频器
TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1; //设置时钟分割:TDTS = Tck_tim
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
//TIM向上计数模式
TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure); //根据TIM_TimeBaseInitStruct中指定的参数初始化TIMx的时间基数单位
//初始化TIM2输入捕获参数
TIM2_ICInitStructure.TIM_Channel = TIM_Channel_1; //CC1S=01
选择输入端 IC1映射到TI1上
TIM2_ICInitStructure.TIM_ICPolarity = TIM_ICPolarity_R //上升沿捕获
TIM2_ICInitStructure.TIM_ICSelection = TIM_ICSelection_DirectTI; //映射到TI1上
TIM2_ICInitStructure.TIM_ICPrescaler = TIM_ICPSC_DIV1;
//配置输入分频,不分频
TIM2_ICInitStructure.TIM_ICFilter = 0x00;//IC1F=0000 配置输入滤波器 不滤波
TIM_ICInit(TIM2, &TIM2_ICInitStructure);
//中断分组初始化
NVIC_InitStructure.NVIC_IRQChannel = TIM2_IRQn;
//TIM2中断
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 2;
//先占优先级2级
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
//从优先级0级
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //IRQ通道被使能
NVIC_Init(&NVIC_InitStructure);
//根据NVIC_InitStruct中指定的参数初始化外设NVIC寄存器
TIM_ITConfig(TIM2,TIM_IT_Update|TIM_IT_CC1,ENABLE);//允许更新中断 ,允许CC1IE捕获中断
TIM_Cmd(TIM2,ENABLE );
//使能定时器2
u8 TIM2CH1_CAPTURE_STA=0; //输入捕获状态
//bit7:捕获完成标志
//bit6:捕获到高点平标志
//bit5~0:捕获到高电平后定时器溢出的次数
u32 TIM2CH1_CAPTURE_VAL;//输入捕获值
void TIM2_IRQHandler(void)
if((TIM2CH1_CAPTURE_STA&0X80)==0)//还未成功捕获
if (TIM_GetITStatus(TIM2, TIM_IT_Update) != RESET)
if(TIM2CH1_CAPTURE_STA&0X40)//已经捕获到高电平了
if((TIM2CH1_CAPTURE_STA&0X3F)==0X3F)//高电平太长了
TIM2CH1_CAPTURE_STA|=0X80;//标记成功捕获了一次
TIM2CH1_CAPTURE_VAL=0XFFFF;
}else TIM2CH1_CAPTURE_STA++;
if (TIM_GetITStatus(TIM2, TIM_IT_CC1) != RESET)//捕获1发生捕获事件
if(TIM2CH1_CAPTURE_STA&0X40)
//捕获到一个下降沿
TIM2CH1_CAPTURE_STA|=0X80;
//标记成功捕获到一次上升沿
TIM2CH1_CAPTURE_VAL=TIM_GetCapture1(TIM2);
TIM_OC1PolarityConfig(TIM2,TIM_ICPolarity_Rising); //CC1P=0 设置为上升沿捕获
//还未开始,第一次捕获上升沿
TIM2CH1_CAPTURE_STA=0;
TIM2CH1_CAPTURE_VAL=0;
TIM_SetCounter(TIM2,0);
TIM2CH1_CAPTURE_STA|=0X40;
//标记捕获到了上升沿
TIM_OC1PolarityConfig(TIM2,TIM_ICPolarity_Falling);
//CC1P=1 设置为下降沿捕获
TIM_ClearITPendingBit(TIM2, TIM_IT_CC1|TIM_IT_Update); //清除中断标志位
前两个初始化的函数没什么好说的,看最后那个中断服务函数。分析一下测量脉冲的原理:
先看一下这个变量
u8 TIM2CH1_CAPTURE_STA=0; //输入捕获状态
//bit7:捕获完成标志
//bit6:捕获到高点平标志
//bit5~0:捕获到高电平后定时器溢出的次数首先当第一次触发捕获中断的,程序进入中断服务函数,判断是否捕获完成,很显然还没完成(因为TIM2CH1_CAPTURE_STA初始值为0),然后进入捕捉中断服务的if语句
因为在上面的初始化函数中设置的上升沿捕捉,而第一次进来TIM2CH1_CAPTURE_STA&0X40很明显等于0,这是开始改动捕捉方式,改为下降沿捕捉(对称式捕捉?。。),最关键的是令TIM2CH1_CAPTURE_STA的第6为1,ok等待下一次捕捉中断触发就可以算一次完整的捕捉了,当然这里还有一个问题,有可能你在等的时候定时器溢出了。。这时候我们就借助更新中断(我觉得叫它溢出中断更形象啊)来统计溢出次数,溢出次数很巧妙的记在了TIM2CH1_CAPTURE_STA的0-5位,但如果时间还长TIM2CH1_CAPTURE_STA的第5位也溢出了怎么办?。。没办法,强制结束本次捕捉吧
#ifndef _TIMER_
#define _TIMER_
#include &sys.h&
void TIM1_PWM_Init(u16 arr,u16 psc);
void TIM2_Cap_Init(u16 arr,u16 psc);
#endif主函数
保留了PWM输出
#include &led.h&
#include &delay.h&
#include &usart.h&
#include &timer.h&
#include &sys.h&
extern u8 TIM2CH1_CAPTURE_STA;
extern u16 TIM2CH1_CAPTURE_VAL;
void init(void)
NVIC_Configuration();
delay_init();
uart_init(9600);
LED_Init();
TIM1_PWM_Init(899,0);//PWM频率80KHz
TIM2_Cap_Init(0xFFFF,72-1);//以1MHz的频率计数
int main(void)
u32 temp=0;
delay_ms(10);
TIM_SetCompare1(TIM1,TIM_GetCapture1(TIM1)+1);
if(TIM_GetCapture1(TIM1)==300)TIM_SetCompare1(TIM1,0);
if(TIM2CH1_CAPTURE_STA&0X80)//成功捕获到了一次高电平
temp=TIM2CH1_CAPTURE_STA&0X3F;
temp*=65536;
//溢出时间总和
temp+=TIM2CH1_CAPTURE_VAL;
//得到总的高电平时间
printf(&HIGH:%d us\r\n&,temp); //打印总的高点平时间
TIM2CH1_CAPTURE_STA=0;
//开启下一次捕获
&&国之画&&&& &&&&chrome插件
版权所有 京ICP备号-2
迷上了代码!您所在位置: &
&nbsp&&nbsp&nbsp&&nbsp
STM32高级定时器通用定时器和基本定时器的编程指南.pdf 65页
本文档一共被下载:
次 ,您可全文免费在线阅读后下载本文档。
下载提示
1.本站不保证该用户上传的文档完整性,不预览、不比对内容而直接下载产生的反悔问题本站不予受理。
2.该文档所得收入(下载+内容+预览三)归上传者、原创者。
3.登录后可充值,立即自动返金币,充值渠道很便利
需要金币:50 &&
这些是STM32开发的必备文档,非常实用,值得收藏!
你可能关注的文档:
······
Same as STM32F-1
通用定时器
? STM32F2众多定时器概览及其功能框图
? 时间基单元
? 影子寄存器
? 计数器模式和时钟选择
? 比较捕获矩阵
? 输入功能
? 捕获输入、测量输入PWM频率和脉宽
? 输出功能
? 比较输出、产生PWM输出、单脉冲输出、强制电平输出
? 同步单元
? 定时器可以被外部信号同步
? 工作在从模式下
? 定时器可以通过内连带到相互同步
? 分别工作在主模式和从模式下
? 定时器的标志、中断和DMA
? STM32F2众多定时器概览及其功能框图
? 时间基单元
? 影子寄存器
? 计数器模式和时钟选择
? 比较捕获矩阵
? 输入功能
? 捕获输入、测量输入PWM频率和脉宽
? 输出功能
? 比较输出、产生PWM输出、单脉冲输出、强制电平输出
? 同步单元
? 定时器可以被外部信号同步
? 工作在从模式下
? 定时器可以通过内连带到相互同步
? 分别工作在主模式和从模式下
? 定时器的标志、中断和DMA
STM32F2上的众多定时器概览
? 每个芯片上都有14个定时器
? 无论引脚数量
? 14个定时器分成三类
? 2个高级定时器:TIM1 & TIM8
? 用于马达控制
? 各自拥有4个通道,带互补输出以及霍尔接口
? 10个通用定时器
? 各自拥有4个通道:TIM2 & TIM3 & TIM4 & TIM5
? 各自拥有2个通道:TIM9 & TIM12
? 各自拥有1个通道:TIM10 & TIM11 & TIM13 & TIM14
? 2个基本定时器:TIM6 & TIM7
? 仅作计数使用,无通道
STM32F2上的众多定时器概览(2 )
14个定时器
定时器精度
定时器类型
正在加载中,请稍后...STM32学习笔记,定时器,PWM,ADC,UART,DMA_百度文库
两大类热门资源免费畅读
续费一年阅读会员,立省24元!
STM32学习笔记,定时器,PWM,ADC,UART,DMA
&&STM32学习笔记,定时器,PWM,ADC,UART,DMA
阅读已结束,下载文档到电脑
想免费下载本文?
定制HR最喜欢的简历
下载文档到电脑,方便使用
还剩20页未读,继续阅读
定制HR最喜欢的简历
你可能喜欢

我要回帖

更多关于 定时器 的文章

 

随机推荐