打印
[STM32F0]

STM32F072 systick 相关疑问

[复制链接]
1362|8
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
huaiqiao|  楼主 | 2016-11-22 12:17 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
最近用到STM32F072 discovery的板子,我在建立工程的时候,想调用delay函数,所以就想到了systick。

我看了下网上说这个systick可以参考正点原子的delay.c写。那么问题来了。

正点原子在F4探索者的delay.c中这个地方。

//延时nms 
//nms:0~65535
void delay_ms(u16 nms)
{                  
        u8 repeat=nms/540;        //这里用540,是考虑到某些客户可能超频使用,
                                                //比如超频到248M的时候,delay_xms最大只能延时541ms左右了
        u16 remain=nms%540;
        while(repeat)
        {
                delay_xms(540);
                repeat--;
        }
        if(remain)delay_xms(remain);
        
}
那么我想问下,对于F0的话,这个地方该怎么写啊? 难道F0也要超频??

正点原子的delay.c如附件所示。

delay.rar (2.13 KB)



沙发
mmuuss586| | 2016-11-22 15:02 | 只看该作者
不用超频啊;
改下系数就好了呀;

如果你延时时间特别短,最多延时时间无法满足要求;

使用特权

评论回复
板凳
huaiqiao|  楼主 | 2016-11-22 16:33 | 只看该作者
mmuuss586 发表于 2016-11-22 15:02
不用超频啊;
改下系数就好了呀;

我不知道您有看如下这个地方么?

//延时nms
//注意nms的范围
//SysTick->LOAD为24位寄存器,所以,最大延时为:
//nms<=0xffffff*8*1000/SYSCLK
//SYSCLK单位为Hz,nms单位为ms
//对168M条件下,nms<=798ms
void delay_xms(u16 nms)
{                                     
        u32 temp;                  
        SysTick->LOAD=(u32)nms*fac_ms;//时间加载(SysTick->LOAD为24bit)
        SysTick->VAL =0x00;           //清空计数器
        SysTick->CTRL|=SysTick_CTRL_ENABLE_Msk ;          //开始倒数  
        do
        {
                temp=SysTick->CTRL;
        }
        while((temp&0x01)&&!(temp&(1<<16)));//等待时间到达   
        SysTick->CTRL&=~SysTick_CTRL_ENABLE_Msk;       //关闭计数器
        SysTick->VAL =0X00;       //清空计数器                      
}
//延时nms
//nms:0~65535
void delay_ms(u16 nms)
{                  
        u8 repeat=nms/540;        //这里用540,是考虑到某些客户可能超频使用,
                                                //比如超频到248M的时候,delay_xms最大只能延时541ms左右了
        u16 remain=nms%540;
        while(repeat)
        {
                delay_xms(540);
                repeat--;
        }
        if(remain)delay_xms(remain);
       
}
如果不写这个delay_ms的这个函数的话,那么紧紧靠void delay_xms(u16 nms)这个函数的话,按照nms<=0xffffff*8*1000/SYSCLK这个注解中的这个公式计算的话,对48M条件下,nms<=0xffffff*8*1000/SYSCLK=2796ms啊。也就是2s。如果是这样的话,后面的这个函数delay_ms(u16 nms)是不是就不要了呢?

使用特权

评论回复
地板
flydream0| | 2016-11-22 17:34 | 只看该作者
如果是毫秒级别,并且只是想利用systick来达到延时效果的话,可以参考这个思路:

1>定义一个全局变量,假如uint32_t DelayCount =0;
2> 在systick中断中 if(DelayCount >0) DelayCount-- ;
3>再写个延时函数
void HAL_Delay(uint32_t time)
{
   DelayCount =time;
   while(DelayCount);
}

以上仅供参考。

使用特权

评论回复
5
huaiqiao|  楼主 | 2016-11-22 18:32 | 只看该作者
本帖最后由 huaiqiao 于 2016-11-22 18:37 编辑
flydream0 发表于 2016-11-22 17:34
如果是毫秒级别,并且只是想利用systick来达到延时效果的话,可以参考这个思路:

1>定义一个全局变量,假 ...

首先,感谢回帖哈。
其实,您的这种方式,我在青风的一个帖子中也看到过。
首先建立一个延迟函数,nTime作为定时数。SysTick配置通过设置为1ms,为SystemCoreClock / 1000:
        void Delay_ms(__IO uint32_t nTime)//延迟函数,设置为MS
        {
          TimingDelay = nTime;//时钟滴答数
        
          while(TimingDelay != 0);
        }
         
        
        void Systick_Init(void)
        {
          if (SysTick_Config(SystemCoreClock / 1000))//设置为1毫秒
          {
            /* Capture error */
            while (1);
          }
        }
 并且通过TimingDelay_Decrement调动中断,代码如下:
        void TimingDelay_Decrement(void)
        {
          if (TimingDelay != 0x00)
          {
            TimingDelay--;
          }
        }
   在stm32f0xx_it.c 中定义 SysTick_Handler中断函数,函数调用TimingDelay_Decrement:
        void SysTick_Handler(void)
        {
                     TimingDelay_Decrement();//调动中断函数
        }

他这里跟您的思路是一样的。

但是他这个写得是毫秒级的延时,那么我如果按照这样的方式来的话。怎么实现毫秒,微秒的延时,是不是就有点混乱了呢?


使用特权

评论回复
6
flydream0| | 2016-11-23 11:18 | 只看该作者
huaiqiao 发表于 2016-11-22 18:32
首先,感谢回帖哈。
其实,您的这种方式,我在青风的一个帖子中也看到过。

如果是毫秒级,使用systick这种方式就可以实现,如果是微妙级,我暂时可以想到:
1 将systick换成timer外设,还是类似方法,尽量提高timer外设所在APB总线时钟频率,配合调整timer外设的预分频系数等等,目的只有一个,就是使timer的中断间隔变成微秒级,这样就可以一样的方法,估计CPU负载也会很大,需要实测验证。
2 使用定时器外设精确为你延时这段微妙级时间。
3 使用代码延时,利用精确计算时钟周期来实现,就是几个for循环,但这个精度无法保证,受其他外设,环境等影响。

。。。

使用特权

评论回复
7
wahahaheihei| | 2016-11-23 13:00 | 只看该作者
不如直接参考BSP里的程序例子。

使用特权

评论回复
8
huaiqiao|  楼主 | 2016-11-23 21:26 | 只看该作者
flydream0 发表于 2016-11-23 11:18
如果是毫秒级,使用systick这种方式就可以实现,如果是微妙级,我暂时可以想到:
1 将systick换成timer外 ...

我今天用st的f0的时钟配置工具,仿照原子的形式写了个delay.c

然后把外接的8M晶振也焊接上去了。

延时了1s来点灯,看起来是可以的。

但是这个我要用示波器再看看波形。

使用特权

评论回复
9
huaiqiao|  楼主 | 2016-11-23 21:27 | 只看该作者
wahahaheihei 发表于 2016-11-23 13:00
不如直接参考BSP里的程序例子。

BSP里面的例子中有么?

我大概看了下,好像没有。。。。。就没有认真再去看

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

10

主题

600

帖子

2

粉丝