博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
[SAN4N学习笔记]使用SysTick精准延时
阅读量:7254 次
发布时间:2019-06-29

本文共 3169 字,大约阅读时间需要 10 分钟。

一、准备工作:

     将上一节搭建的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);

}

}

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

转载于:https://www.cnblogs.com/xiaoming1989/p/3449536.html

你可能感兴趣的文章
<meta>标签基础
查看>>
Java中三种代理模式
查看>>
阅读《构建之法》十一、十二、十三章之感
查看>>
线程面试题50道
查看>>
第二阶段团队项目冲刺站立会议(六)
查看>>
Android三种播放视频的方式
查看>>
AOP方法增强自身内部方法调用无效 SpringCache 例子
查看>>
CentOS 7 安装 JDK
查看>>
正则表达式
查看>>
对配置文件内的固定内容加密解密
查看>>
epoll函数知识点
查看>>
pta l2-5(集合相似度)
查看>>
poj1019(打表预处理+数学)
查看>>
【转载】关于防火墙的初次接触
查看>>
集合和泛型 一
查看>>
php 把一个一维数组的值依次赋值到二维数组中的每一项
查看>>
CF_315C_Sereja and Contest
查看>>
vue,下级页面刷新导致路由跳转带过来的数据消失的解决方法
查看>>
border的简略
查看>>
echo
查看>>