OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 9776|回复: 5

STM32F2 定时器 做延时 问题

[复制链接]

2

主题

8

帖子

0

精华

新手上路

积分
49
金钱
49
注册时间
2013-7-4
在线时间
3 小时
发表于 2013-7-4 10:34:19 | 显示全部楼层 |阅读模式
 大家好,我是刚用STM32不久的,现在研究定时器做延时的问题。我发现STM32定时器是不是有问题啊,我按照正常配置的,先配置TIM5为每10us进一次中断,然后计算N个10us,就通过计算一个数值的减,来判断进入了多少次中断,也就知道经过了多少个10us,然后计算MS时,就调用10us的延时,就调用计算N个10us的函数,跑100次就好了。但是,这个程序有问题,不知道是不是我设置的有问题:

//设置TIM5
void DelayTIM5_Configuration(void)
{
        TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;  
        NVIC_InitTypeDef NVIC_InitStructure;
        RCC_ClocksTypeDef             RCC_ClocksStatus;
        uint16_t PrescalerValue = 0;
        
        PrescalerValue=(RCC_ClocksStatus.PCLK1_Frequency*2)/1000000-1;   //Prescal to 1MHz  

        /* TIM5 clock enable */
        RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM5, ENABLE);    
        /* Enable the TIM5 gloabal Interrupt */
        NVIC_InitStructure.NVIC_IRQChannel = TIM5_IRQn;
        NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
        NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
        NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
        NVIC_Init(&NVIC_InitStructure);                                        
        // TIM5 clock enable [TIM3定时器允许]
        RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM5, ENABLE);                
        // TIM5 configuration 
        TIM_TimeBaseStructure.TIM_Period = 9;          //ARR的值
        TIM_TimeBaseStructure.TIM_Prescaler = PrescalerValue;//59
        TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1;  // 时钟分割
        TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;  //计数方向向上计数
        TIM_TimeBaseInit(TIM5, &TIM_TimeBaseStructure);                
        // Clear TIM5 update pending flag[清除TIM5溢出中断标志] 
        TIM_ClearFlag(TIM5, TIM_FLAG_Update);
        //ARR预装载缓冲器
        TIM_ARRPreloadConfig(TIM5, ENABLE);
        // Enable TIM5 Update interrupt [TIM5溢出中断允许]
        TIM_ITConfig(TIM5, TIM_IT_Update, ENABLE);      
        // TIM5 enable counter [TIM5计数]
        TIM_Cmd(TIM5,DISABLE);                            
}

//开启定时器,关闭定时器设置:
void starTimer(void)
{
        TIM_ClearFlag(TIM5, TIM_FLAG_Update);
        TIM_SetCounter(TIM5, 0);
        TIM_Cmd(TIM5,ENABLE);
}
void stopTimer(void)
{
        TIM_Cmd(TIM5,DISABLE);
        TIM_ClearFlag(TIM5, TIM_FLAG_Update);
        TIM_SetCounter(TIM5, 0);
}

//DELAY 10us函数
void delay10Us(unsigned int n_10us)
{
//         int i;
//         for(i=0;i<500;i++);
        starTimer();
        gTimerCount = n_10us;
        gTimerOutFlag = 0;
        while(!gTimerOutFlag);
        stopTimer();
}

//DELAY 1ms函数
void delay1Ms(unsigned int n_1ms)
{
        starTimer();
        while(n_1ms != 0)
        {
                gTimerCount = 100;
                gTimerOutFlag = 0;
                while(!gTimerOutFlag);
                n_1ms --;
        }
        stopTimer();
}

//计算用的变量的定义:
volatile unsigned short gTimerCount = 0;
unsigned char  gTimerOutFlag = 0;

//中断函数:
void TIM5_IRQHandler(void)
{        
        if(TIM_GetITStatus(TIM5,TIM_IT_Update)!=RESET)
        {
                TIM_ClearITPendingBit(TIM5,TIM_FLAG_Update);
                                
                                gTimerCount--;
                                if (gTimerCount)
                                {
                                        return;
                                }
                                else
                                {
                                        gTimerOutFlag=1;
                                }                                
        }
}

现在情况是,10us计算,基本上没有太大问题,可以正常工作,计算ms上,数值小一点,也是没问题的,但是当我写上500 ms时,立刻就不行了,但是神奇的是,下面的其他程序,我如果改动了一些,他竟然有时候又能正常工作了,但是下面程序跟定时器无关啊,而且有时候又跑进了HardFault_Handler。坑爹啊,这样怎么弄啊,STM32定时器咋这么复杂啊
正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

2

主题

8

帖子

0

精华

新手上路

积分
49
金钱
49
注册时间
2013-7-4
在线时间
3 小时
 楼主| 发表于 2013-7-4 11:27:41 | 显示全部楼层
还请原点大哥给与指导啊~~高手们也帮帮忙啊
回复 支持 反对

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165540
金钱
165540
注册时间
2010-12-1
在线时间
2117 小时
发表于 2013-7-4 14:21:09 | 显示全部楼层
回复【楼主位】peterhzm:
---------------------------------
不要用中断的方式做延时,尤其不好...
另外F2应该也有systick, 何不用这个?TIM5可以用来做其他很多用处的...
我是开源电子网www.openedv.com站长,有关站务问题请与我联系。
正点原子STM32开发板购买店铺http://openedv.taobao.com
正点原子官方微信公众平台,点击这里关注“正点原子”
回复 支持 反对

使用道具 举报

2

主题

8

帖子

0

精华

新手上路

积分
49
金钱
49
注册时间
2013-7-4
在线时间
3 小时
 楼主| 发表于 2013-7-4 17:10:34 | 显示全部楼层
回复【3楼】正点原子:

回复【楼主位】peterhzm:
---------------------------------
不要用中断的方式做延时,尤其不好...
另外F2应该也有systick, 何不用这个?TIM5可以用来做其他很多用处的...

---------------------------------
原子大哥,为什么不能呀?用51的时候,我都一直用中断来做延时的,也没有什么问题,但是用了STM32之后就好多的问题。
systick也可以,这个做延时的话,好像就不能停了
回复 支持 反对

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165540
金钱
165540
注册时间
2010-12-1
在线时间
2117 小时
发表于 2013-7-4 21:56:27 | 显示全部楼层
回复【4楼】peterhzm:
---------------------------------
当有其他中断的时候,你的定时器中断,可能干扰到其他中断的执行.
另外,能不开中断就不开,增加CPU负担.
另外,在多任务的时候,你用中断延时,如果有多个任务同时要用延时,很可能就会出问题了.
还有,你如果在中断里面调用延时,又该如何处理?可能导致永远也退不出来了.

stm32的systick,很好做延时的,我们的例程就一直用的是systick做延时.
我是开源电子网www.openedv.com站长,有关站务问题请与我联系。
正点原子STM32开发板购买店铺http://openedv.taobao.com
正点原子官方微信公众平台,点击这里关注“正点原子”
回复 支持 反对

使用道具 举报

3

主题

11

帖子

0

精华

新手上路

积分
44
金钱
44
注册时间
2014-12-29
在线时间
0 小时
发表于 2015-2-3 19:13:06 | 显示全部楼层
你外部晶振是多少?
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则



关闭

原子哥极力推荐上一条 /2 下一条

正点原子公众号

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2025-6-26 02:08

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

快速回复 返回顶部 返回列表