查看: 758|回复: 0

【SAN4N学习笔记】使用SysTick精准延时

[复制链接]

该用户从未签到

发表于 2015-12-8 09:19:04 | 显示全部楼层 |阅读模式
分享到:
一、准备工作:
这一节主要讲如何使用系统的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);

  • }

  • }
复制代码
好了,下载程序到板子,这下是不是延时很准?
回复

使用道具 举报

您需要登录后才可以回帖 注册/登录

本版积分规则

关闭

站长推荐上一条 /2 下一条

手机版|小黑屋|与非网

GMT+8, 2024-4-25 13:39 , Processed in 0.112452 second(s), 17 queries , MemCache On.

ICP经营许可证 苏B2-20140176  苏ICP备14012660号-2   苏州灵动帧格网络科技有限公司 版权所有.

苏公网安备 32059002001037号

Powered by Discuz! X3.4

Copyright © 2001-2024, Tencent Cloud.