void delay_init(u8 SYSCLK)
{
SysTick->CTRL&=0xfffffffb;

fac_us=SYSCLK/8;
fac_ms=(u16)fac_us*1000;
}

Systick主要的作用就是拿来计时,其原理和应用简述一下就是这样的:通过配置寄存器SysTick->CTRL来设定Systick的计时频率并Enable使Systick开始计数,这里的SysTick->CTRL&=0xfffffffb应该很好理解,把第2位设定为0,查找应用手册可以知道这是把Systick的计时频率设定为CPU主频(SYSCLK)的1/8。

假定我们板子默认的晶振频率是8Mhz,默认CPU工作频率(SYSCLK)是9倍频,即72M,那Systick的频率就是72/8=9Mhz。

知道了Systick的频率,下一步就是确定倒时计数器的数值,即SysTick->LOAD这个寄存器的配置。上面已经知道了,Systick的工作频率F=9Mhz=SYSCLK/8,即每秒钟计数器自减900万次,也就是说,SYSCLK/8次的自减耗时1秒,那么(8/SYSCLK)/1000,000次自减就耗时1微秒了,这也就是fac_us的值了。那么上面函数中的fac_us为什么是SYSCLK/8呢?这里先搞清楚一点,函数中SYSCLK的单位是Mhz,所以SYSCLK的值是72(这个以Mhz为单位应该是STM32基础库里面做过宏定义的),否则也不可能用一个8位整形去表示一个7200万的数值;而我们这里计算的SYSCLK是以Hz为单位的,即72Mhz/1000,000=72,所以这个SYSCLK/8是对的。

你可能还没搞清楚fac_us到底是干嘛的。很简单,fac_us就是要写入SysTick->LOAD寄存器的值,Systick的工作原理是这个寄存器的值在Systick被Enable之后就开始以设定的工作频率自减,减到0的时候就发出中断,实现定时。所以,写入fac_us到SysTick->LOAD寄存器,就是要Systick在自减了fac_us次以后发出中断,自减fac_us所耗的时间已经说了,1微秒。

下面的fac_ms应该很好理解了,就是1毫秒的计数次数,刚好是1微妙的1000倍,注意9×1000超出了8位整形的表示范围,所以要用(u16)先把fac_us转成16位变量,以保证计算的正确。

具体的应用函数是用来做延时,如下:

void delay_us(u32 nus)
{
u32 temp;
SysTick->LOAD=nus*fac_us; //时间加载
SysTick->VAL=0x00; //清空计数器
SysTick->CTRL=0x01 ; //Enable Systick,开始倒数
do
{
temp=SysTick->CTRL;
}
while(temp&0x01&&!(temp&(1<<16)));//等待时间到达
SysTick->CTRL=0x00; //Disable Systick

SysTick->VAL =0X00; //清空计数器
}

具体的寄存器配置只要看手册就知道了,这里只需要理解一句:

do
{
temp=SysTick->CTRL;
}
while(temp&0x01&&!(temp&(1<<16)));//等待时间到达

核心就是while(temp&0x01&&!(temp&(1<<16)));//等待时间到达

temp已经是Systick控制寄存器的值了,temp&0x01就是把该寄存器的值读出并且把除第一位之外位都清零(当然要通过temp变量来传递值而不是直接修改寄存器),第一位就是Systick的Enable配置信息,写入1就是Enable,写入0就是Disable,读这一位是判断Systick是否仍然处于Enable状态(可能被其他中断禁用掉),temp&(1<<16)就是读取第16位的值,这一位如果为0就表示计数器的值不是0(即还在计数),如果是1就表示计数器已经自减到0了。

那么这段就很好理解了,即判断,如果Systick还在Enable的状态,并且计数器还没数到0,就不停的循环把当前的SysTick->CTRL寄存器值写入变量temp,继续下一次判断。当Systick被Disable或者计数器数到0了,就停止循环。因为只是做延时,也不需要跳到任何中断服务那边去处理什么,只要这个循环的耗时过程完成就可以了。

Systick 延时函数详解相关推荐

  1. Linux内核中的延时函数详解

    内核中涉及的延时主要有两种实现方式:忙等待或者睡眠等待.前者阻塞程序,在延时时间到达前一直占用CPU,而后者是将进程挂起(置进程于睡眠状态并释放CPU资源).所以,前者一般用在延时时间在毫秒以内的精确 ...

  2. Delay_ms延时函数详解

    void Delay_ms(unsigned int time) {unsigned char n;while(time>0){for(n=0;n<187;++n){ asm(" ...

  3. OpenCV-Python学习之(一)waitKey()函数详解

    OpenCV-Python学习之(一)waitKey()函数详解 waitKey()函数详解 : 1.1 waitKey()--这个函数是在一个给定的时间内(单位ms)等待用户按键触发;如果用户没有按 ...

  4. matlab中xcorr函数详解

    Matlab中xcorr函数详解 引言 在matlab中查找相关函数时,找到了xcov函数和xcorr函数,仔细看了帮助文档,发现虽然计算公式不一样,但是两个函数用法相同,计算出的值也相同,于是在翻了 ...

  5. C语言网络编程:accept函数详解

    文章目录 前言 函数描述 代码实例 如何得到客户端的IP 和 端口号 前言 当使用tcp服务器使用socket创建通信文件描述符,bind绑定了文件描述符,服务器ip和端口号,listen将服务器端的 ...

  6. 【FFmpeg】函数详解(三)

    FFmpeg函数详解 14.av_write_frame 15.av_interleaved_write_frame 16.av_write_trailer 17.avio_close 18.av_i ...

  7. 【FFmpeg】函数详解(二)

    FFmpeg函数详解 9.av_dump_format 10.avio_open 11.avformat_write_header 12.avcodec_send_frame 13.avcodec_r ...

  8. 【FFmpeg】函数详解(一)

    FFmpeg函数详解 一.错误码相关 1.AVERROR 2.av_strerror 3.其他错误码解释 二.编解码 1.获取编解码器 2.申请.释放上下文环境 3.打开编码器avcodec_open ...

  9. 【ES6】Generator函数详解

    [ES6]Generator函数详解 一.Generator函数简介 基本概念 函数写法 yield关键字介绍 二.next方法的参数 三.for...of循环 四.关于普通throw()与Gener ...

最新文章

  1. 八、Linux 常用 Shell 命令,控制台的快捷键以及 Shell 编程(中)
  2. 1036:A×B问题
  3. python多个main方法_Python,main方法未运行(同一文件中有多个类)
  4. 若某计算机字长为16位,题目来源于王道论坛 某计算机字长为16位,主存地址空间...
  5. tensorflow保存内容到相对文件路径下_如何添加自定义文件系统插件
  6. bash/shell 解析命令行参数工具:getopts/getopt
  7. myeclipse 实现框架 spring+springmvc+springsecurity+myibatis+mysql用户认证和人员增删改查
  8. MVC 中使用uploadify上传图片遇到的蛋疼问题
  9. saltstack学习笔记
  10. Linux下history命令用法
  11. 树的最长路径详解(C++)
  12. java设计模式——adapter模式
  13. 更新K3官改里面都FRP到0.20版本的方法
  14. nodejs字符串如何转成json数据
  15. 高德地图行政区域划分(西安)
  16. 剑指Offer对答如流系列 - 剪绳子
  17. java fillrect_Java编写一个Applent程序,使用fillRect方法输出不同的颜色
  18. C#个人博客系统源码(前台+后台管理)
  19. 岩板铺地好吗_岩板铺大客厅路面好么 比800*800的地砖更美观大方又空气?
  20. CISP证书价值​NISP证书价值|CISP和NISP含金量如何

热门文章

  1. 互联网1分钟 |0103
  2. 【版本更新】IM 4.3.0新版本升级上线!
  3. perl学习(1) 入门
  4. ICO取缔一锤定音,投资者、发起方、交易所如何处理后续风险,保障权益?
  5. Android实训案例(七)——四大组件之中的一个Service初步了解,实现通话录音功能,抽调接口...
  6. Android高级控件(二)——SurfaceView实现GIF动画架包,播放GIF动画,自己实现功能的初体现...
  7. centos6系统优化脚本
  8. 移动前端开发基础与优化
  9. AWS - EC2 Micro Instance 添加 SWAP 分区
  10. Java中Comparable与Comparator的区别