近来学习STM32F103RB单片机,买了miniSTM32开发板,练习Capture时出现了一个奇怪的现象,不知如何解决,特请教各位前辈:
使用TIM3 CH1(PA6)输出频率为1KHz的PWM,使用TIM2 CH2捕获PWM输出的高电平时间,捕获后利用串口将捕获的时间发送到PC。出现的问题如下:
TIM2捕获计时分频为71,捕获周期为1000,TIM打开溢出中断和捕获中断,初始化时默认上升沿开始捕获,捕获到上升沿时将计数器清0,并且将开始捕获标记置位,捕获边沿改为下降沿捕获,在高电平期间发生计时溢出,则溢出计数+1,奇怪的是如果TIM2的自动重载值设定为1000,当PWM占空比小于1/2时,捕获时间正常,当PWM占空比超过1/2时,捕获所得的时间会多出一个溢出周期的时间。当将捕获定时器的溢出周期改为除1000以外的其他值,则不论占空比为多少,捕获时间都正常,不知道这是什么原因,请各位不吝赐教,代码如下:
/*****************************************************
STM32捕获程序
利用TIM3——1生成PWM波(PA6),利用TIM2 CH2捕获生成的PWM(PA1)
*****************************************************/
#include "..\include\Capture.h"
#include <stdio.h>
static uchar IRQNum=0; //溢出中断次数
u8 StartCapture=False;
u8 CaptureFinish=False;
u16 CaptureTime=0;
/*****************************************************
Capture初始化程序
*****************************************************/
void CaptureInit(void)
{
RCC->APB1ENR|=1<<0; //使能TIM2时钟
RCC->APB2ENR|=1<<2; //使能PORTA时钟
GPIOA->CRL&=0xFFFFFF0F;
GPIOA->CRL|=((UpperLowerInput<<2)|Input)<<4; //上下拉输入
GPIOA->ODR|=1<<1; //上拉输入
TIM2->CCMR1&=~(3<<8);
TIM2->CCMR1|=1<<8; //CC2通道被配置为输入,IC2映射在TI2上
TIM2->CCMR1&=0x0FFF;
TIM2->CCMR1|=2<<12; //输入滤波器为4
TIM2->CCER&=~(1<<5); //上升沿有效
TIM2->CCMR1&=~(3<<10); //输入预分频为0
TIM2->CCER|=1<<4; //使能捕获
TIM2->DIER|=1<<2; //允许捕获中断
TIM2->PSC=71; //预分频为72
TIM2->ARR=1000; //频率为1K
TIM2->SR&=~(1); //清除更新中断
TIM2->SR&=~(1<<2); //清除捕获中断
TIM2->DIER|=1; //允许溢出中断
TIM2->CR1|=1; //开启TIMER3
MY_NVIC_Init(2,1,TIM2_IRQn,2); //使能中断
}
/*****************************************************
Capture中断程序
*****************************************************/
void TIM2_IRQHandler(void)
{
if(TIM2->SR&1) //发生溢出中断
{
if(StartCapture)
{
IRQNum++;
}
TIM2->SR&=~(1);
}
if(TIM2->SR&1<<2) //发生捕获中断
{
if(StartCapture)
{
CaptureTime=IRQNum*1000+TIM2->CCR2;
TIM2->CCER&=~(1<<5); //上升沿有效
CaptureFinish=True;
StartCapture=False;
IRQNum=0;
TIM2->CCR2=0;
}
else
{
TIM2->CNT=0;
IRQNum=0;
TIM2->CCR2=0;
TIM2->CCER|=1<<5; //下降沿有效
StartCapture=True;
}
TIM2->SR&=~(1<<2); //清除捕获中断
}
}
/*********************************************************
Capture进程
*********************************************************/
void CaptureProcess(void)
{
if(CaptureFinish)
{
CaptureFinish=False;
printf("High Level Time:%d us\n",CaptureTime);
}
}
|