打印
[Kinetis]

K60--滴答定时器(SysTick)实现精准延时

[复制链接]
4151|5
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
energy1|  楼主 | 2015-2-10 14:32 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
昨天写代码时用到了延时,野火例程里面用到的低功耗定时器(LPTMR)最低只能延时1ms。那我需要的是us级的延时该怎么办呢?先分析一下LPTMR用到的时钟。野火库里面LPTMR时钟源有四种:MCGIRCLK、LPO、ERCLK32K、OSCERCLK。而他用到的是LPO-1KHz,最低延时1ms。本来是想将时钟源配置为MCGIRCLK,但编译失败了。代码如下:
void time_delay_us(uint32 us)

{
    // Make sure the clock to the LPTMR is enabled
    MCG_C2    |= MCG_C2_IRCS_MASK;       //Fast internal reference clock selected

    MCG_C1   |=  MCG_C1_IRCLKEN_MASK;   //MCGIRCLK  active

    SIM_SCGC5 |= SIM_SCGC5_LPTIMER_MASK;

    //Set the compare value to the number of us to delay
    LPTMR0_CMR = us;

    //Clock name : MCGIRCLK      Clock source : MCG   4M/4=1M
    LPTMR0_PSR = LPTMR_PSR_PRESCALE(2) | LPTMR_PSR_PCS(0) | LPTMR_PSR_PBYP_MASK  

    // Start the timer
    LPTMR0_CSR |= LPTMR_CSR_TEN_MASK;

    //Wait for counter to reach compare value
    while (!(LPTMR0_CSR & LPTMR_CSR_TCF_MASK));

    // Clear Timer Compare Flag
    LPTMR0_CSR &= ~LPTMR_CSR_TEN_MASK;

    return;
}
希望有大神能帮我看看,上面的该怎么配置。
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
由于上面那种行不通,我突然想起了滴答定时器(SysTisk),查遍了芯片手册只发现这个:

为毛连个寄存器都不提!!!
嗯,先冷静一下。。。对了,MK60DZ10.h里面提到的都是寄存器。打开看看:
额。。。貌似有点多。它的寄存器名字和STM32里SysTick的寄存器名字差不多,含义也差不多,于是移植就此展开。

相关帖子

沙发
energy1|  楼主 | 2015-2-10 14:32 | 只看该作者
/////////////////////////////////////////////////////////////////////////////////////////////
SysTick.c
#include "common.h"
#include "SysTick.h"
static volatile u32 TimingDelay;
extern u32 core_clk_mhz;


/**********************************************
* 函数名:SysTick_Init
* 描述  :启动系统滴答定时器 SysTick
* 输入  :无
* 输出  :无
* 调用  :外部调用
**********************************************/
void SysTick_Init(void)
{
/* core_clk_mhz*1000          1ms中断一次
* core_clk_mhz*10     10us中断一次
* core_clk_mhz               1us中断一次
           T = ticks * (1/f)
*/
if (SysTick_Config(core_clk_mhz))
{
/* Capture error */
while (1);
}
// 关闭滴答定时器  
SYST_CSR &= ~ SysTick_CSR_ENABLE_MASK;
}


/**********************************************
* 函数名:TimingDelay_Decrement
* 描述  :获取节拍程序
* 输入  :无
* 输出  :无
* 调用  :在 SysTick 中断函数 SysTick_Handler()调用
**********************************************/
void TimingDelay_Decrement(void)
{
if (TimingDelay != 0x00)
{
            TimingDelay--;
}
}


/**********************************************
* 函数名:Delay_us
* 描述  :us延时程序,1us为一个单位
* 输入  :- nTime
* 输出  :无
* 调用  :Delay_us( 1 ) 则实现的延时为 1us
*       :外部调用
**********************************************/
void Delay_us(volatile u32 nTime)
{
TimingDelay = nTime;


// 使能滴答定时器  
SYST_CSR |=  SysTick_CSR_ENABLE_MASK;


while(TimingDelay != 0);
}
/////////////////////////////////////////////////////////////////////////////////////////////
SysTick.h
#ifndef __SYSTICK_H
#define __SYSTICK_H


#include  "include.h"


void SysTick_Init(void);
void Delay_us(volatile u32 nTime);
void TimingDelay_Decrement(void);     //中断调用


#endif /* __SYSTICK_H */
/////////////////////////////////////////////////////////////////////////////////////////////////

使用特权

评论回复
板凳
energy1|  楼主 | 2015-2-10 14:33 | 只看该作者
[size=15.199999809265137px]上面两个文件是我根据STM32里面的代码修改的。添加到野火库driver里面。接下来在include.h里面添加#include "SysTick.h"、并将其路径添加到预编译中:

使用特权

评论回复
地板
energy1|  楼主 | 2015-2-10 14:33 | 只看该作者
然后
1、在isr.c添加中断函数
void SysTick_IRQHandler()
{
    TimingDelay_Decrement();
}
2、重新宏定义中断号,重映射中断向量表里的中断函数地址,使其指向我们所定义的中断服务函数。在isr.h中添加
#undef  VECTOR_015
#define VECTOR_015    SysTick_IRQHandler
extern void SysTick_IRQHandler();

使用特权

评论回复
5
energy1|  楼主 | 2015-2-10 14:35 | 只看该作者
3、由于SysTick属于内核器件,所以将其配置函数放在arm_ch4.h中:
static inline u32 SysTick_Config(u32 ticks)
{
       if (ticks > SysTick_RVR_RELOAD_MASK)  return (1);        /* Reload value impossible */
       SYST_CSR = 0x00U;  

       SYST_RVR  =      SysTick_RVR_RELOAD(ticks-1) ;            /* set reload register */

       SYST_CVR  =      SysTick_CVR_CURRENT(0);                  /* Load the SysTick Counter Value */

       SYST_CSR  =      SysTick_CSR_CLKSOURCE_MASK |
                        SysTick_CSR_TICKINT_MASK   |
                        SysTick_CSR_ENABLE_MASK;                 /* Enable SysTick IRQ and SysTick Timer */

       return (0);                                              /* Function successful */

}

使用特权

评论回复
6
energy1|  楼主 | 2015-2-10 14:36 | 只看该作者
4、在common.h中找到:#include "MK60DZ10.h"定义的地方   ,将其放在#include "arm_math.h"  和#include "arm_cm4.h"定义之前。
5、最后在主程序中进行初始化SysTick_Init();后,就可以使用Delay_us( x);了,精准的xus延时。
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
上面使用的基础是野火K60库,已通过测试,希望对大家有帮助。有什么问题,大家一起讨论。PS:希望有大神能帮我解决开头的那个问题。

使用特权

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

本版积分规则

94

主题

422

帖子

10

粉丝