我用定时器3来实现LED1(PE5)亮1S,灭1S的功能,如果定时器3中断服务函数里没有if(TIM3->SR&0X0001)判断中断标志位的语句,就会变成亮0.5S,灭0.5S。这是程序:
/*******************************************
使用通用定时器3的通道2输出PWM,通过重映射到PB5上来点亮LED0
并且使用定时器3的中断服务函数,使LED1(PE5)1s亮灭翻转
********************************************/
#include<stm32f10x.h>
#include<stdio.h>
/****************************************
定时器3初始化
****************************************/
u16 count; //存储进入进入定时器3中断服务函数的次数
u8 flag; //LED1翻转标志
void tim3_init(u16 psc,u16 arr)
{
RCC->APB1ENR|=0X02; //开TIM3时钟
TIM3->SMCR&=0XFFFFFFF8; //关闭从模式,使用内部时钟72MHz(默认设置)
TIM3->CR1|=0X0080; //边沿对齐,向上计数,使用ARR预装载缓冲器
TIM3-> SC=psc; //预分频720,计数器每隔1/100000s计一次数
TIM3->ARR=arr; //自动装载初值100,计数器每隔1/1000s溢出一次
TIM3->DIER|=0X0001; //允许TIM3更新中断
NVIC->IP[29]=0X90; //TIM3中断为强张优先级2,响应优先级1
NVIC->ISER[0]|=0X20000000; //允许TIM3总中断
TIM3->CR1|=0X0001; //启动计数器
}
/*********************************
定时器3中断服务函数,实现LED1 1s亮1s灭
*********************************/
void TIM3_IRQHandler(void)
{
if(TIM3->SR&0X0001)//溢出中断
{
if((count>=1000)&&(flag==0))
{
count=0;
GPIOE->ODR&=(~(1<<5));
flag=1;
}
if((count>=1000)&&(flag==1))
{
count=0;
GPIOE->ODR|=(1<<5);
flag=0;
}
count++;
}
TIM3->SR&=0XFFFE; //清除TIM3中断标志位 应该清0,结果写为置1 10月23日16点45分
}
/***************************
主函数
***************************/
int main(void)
{
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); //中断2:2分组
RCC->APB2ENR|=0X44; //开GPIOB和GPIOE时钟
GPIOE->CRL&=0XFF0FFFFF;
GPIOE->CRL|=0X00200000; //PE5(LED1)通用推挽输出,2MHz
GPIOE->ODR|=(1<<5); //关闭LED1
tim3_init(720,100); //定时器3初始化
while(1);
}
而且,我拿原子哥定时器中断例程(例程里是亮0.25s灭0.25s)的定时器中断服务函数里去掉if(TIM3->SR&0X0001)
LED1直接就不亮了。
这是怎么回事啊,是不是每次在中断服务函数里都要判断中断标志,否则就会出现各种各样的错误吗?
|