• [SAN4N学习笔记]使用SysTick精准延时


    一、准备工作:

         将上一节搭建的LED工程复制一份,命名为“2.systick”。这一节主要讲如何使用系统的SysTick节拍定时器来进行精准延时程序。

    二、程序编写:

    SysTick是CM3/CM4内核芯片提供的一个定时器,我们的板子使用的SAM4N芯片是CM4内核的,自然少不了这个定时器。

    首先在Drivers文件夹中建立delay.c和delay.h文件并添加到工程中,在delay.c中写入如下代码:

    #include "delay.h"

    uint32_t timeout=0;

    /**************************************************************************

    * 函数名:SysTick_Handler()

    * 参数  :void

    * 返回值:void

    * 描述  :系统节拍中断服务函数

    **************************************************************************/

    void SysTick_Handler(void)

    {

    /*定时计数自减1*/

        timeout--;

    }

    /**************************************************************************

    * 函数名:systick_hw_init()

    * 参数  :void

    * 返回值:void

    * 描述  :系统节拍初始化函数

    **************************************************************************/

    void systick_hw_init(void)

    {

    //选择系统节拍定时器的时钟源为系统内核时钟

    SysTick->CTRL|=0x01<<2;

    //设置重装值,配置系统节拍定时器为1ms中断一次

    /*1ms <-->SystemCoreClock/1000

    * 100us <-->SystemCoreClock/10000

    * 10us <-->SystemCoreClock/100000

    */

    SysTick->LOAD = SystemCoreClock/1000 - 1;

    //使能系统节拍时钟中断

    SysTick->CTRL|=0x02;

    //使能系统节拍时钟

    SysTick->CTRL|=0x01;

    }

    /**************************************************************************

    * 函数名:delay_ms()

    * 参数  :uint32_t n  延时的毫秒数

    * 返回值:void

    * 描述  :使用系统节拍进行精准延时函数

    **************************************************************************/

    void delay_ms(uint32_t n)

    {

       timeout = n;        //设置系统节拍延时

       while(timeout!=0);      //等待延时时间到

    }

    /**************************************************************************

    * 函数名:delay()

    * 参数  :uint32_t n  延时的循环个数

    * 返回值:void

    * 描述  :简单的循环延时函数

    **************************************************************************/

    void delay(uint32_t n)

    {

    while(n--);

    }

    虽然注释已经写得很清楚了,但还是讲一下吧,主要是systick_hw_init函数,这是初始化配置SysTick的代码,第一步先选择SysTick的时钟源,这里我选择使用系统内核时钟作为时钟源;第二步是设置SysTick的Load值,这里设置为ystemCoreClock/1000 - 1;,这样SysTick就会每毫秒中断一次,最后是开启中断和使能SysTick。

    延时主要是通过设定timeout的值,然后等待timeout为0,在Systick中断中,timeout会自减1,直到为0。这样就实现了ms级的精准延时函数delay_ms()。

    在delay.h中主要写写函数声明,如下:

    #ifndef __DELAY_H

    #define __DELAY_H

    #include "sam4n16c.h"

    /**************************************************************************

    * 函数名:SysTick_Handler()

    * 参数  :void

    * 返回值:void

    * 描述  :系统节拍中断服务函数

    **************************************************************************/

    void SysTick_Handler(void);

    /**************************************************************************

    * 函数名:systick_hw_init()

    * 参数  :void

    * 返回值:void

    * 描述  :系统节拍初始化函数

    **************************************************************************/

    void systick_hw_init(void);

    /*************************************************************************

    * 函数名:delay_ms()

    * 参数  :uint32_t n  延时的毫秒数

    * 返回值:void

    * 描述  :使用系统节拍进行精准延时函数

    **************************************************************************/

    void delay_ms(uint32_t n);

    /**************************************************************************

    * 函数名:delay()

    * 参数  :uint32_t n  延时的循环个数

    * 返回值:void

    * 描述  :简单的循环延时函数

    **************************************************************************/

    void delay(uint32_t n);

    #endif

    接下来把main.c中的delay改掉,如下:

    int main(void)

    {

    systick_hw_init();

    led_hw_init();

    while(1){

    led_hw_on();

    delay_ms(500);

    led_hw_off();

    delay_ms(500);

    }

    }

    好了,下载程序到板子,这下是不是延时很准?

  • 相关阅读:
    centos下使用yum 安装pip
    unity3d Aniso Level 摄像机近地面清楚,远地面模糊
    Unity3D 多平台 预编译 宏定义
    Mecanim的Avater
    Mecanim 学习概述
    Unity物理系统的触发器
    Unity开发 资源准备
    我的Unity学习路线
    贴图在Unity中的设置
    在Unity中为模型使用表情
  • 原文地址:https://www.cnblogs.com/xiaoming1989/p/3449536.html
Copyright © 2020-2023  润新知