火龙果MM32F3273G8P开发板MindSDK开发教程4 - 滴嗒定时器Systick的配置

news2024/11/7 11:30:08

火龙果MM32F3273G8P开发板MindSDK开发教程4 - 滴嗒定时器Systick的配置

1、Systick寄存器

Systick是ARM内核的一个外设,所以在不同芯片的代码上移植比较方便,他总共有4个寄存器,
从Systick定义中可以看到:

typedef struct
{
  __IOM uint32_t CTRL;                   /*!< Offset: 0x000 (R/W)  SysTick Control and Status Register */
  __IOM uint32_t LOAD;                   /*!< Offset: 0x004 (R/W)  SysTick Reload Value Register */
  __IOM uint32_t VAL;                    /*!< Offset: 0x008 (R/W)  SysTick Current Value Register */
  __IM  uint32_t CALIB;                  /*!< Offset: 0x00C (R/ )  SysTick Calibration Register */
} SysTick_Type;

2、轮询方式延时

一般,systick ms级别的延时,采用中断方式,load值为sysclk/1000,这样每ms产生中断,可以用来ms级别的延时,或者为freeRtos提供节拍。
同样,采用轮询方式延时,也可以实现ms级的延时,并且可以实现us级的延时。
systick的时钟源分两种,ctrl寄存器第二位为0时采用sysclk/8的时钟频率,第二位为1时采用系统时钟。
轮询方式延时采用sysclk/8分频方式,也可以采用不分频的方式。

a、 采用8分频的方式

假如系统时钟为120M,8分频后为15M,即1/15000000计一次数,1us需要15次。所以代码中倍频因子为了代码的可移植性,使其count_1us = sysclk/8000000 = 15。
相关代码:

volatile static float count_1us = 0;
volatile static float count_1ms = 0;

/**
 *  初始化滴答定时器函数
 *  轮询方式延时
*/

void BOARD_Systick_Init()
{
	// Systick CTRL 寄存器 第二位为0时,Systick时钟==Sysclk/8 ,
	// 第二位为1时,Systick = Sysclk
	SysTick->CTRL &= ~(1<<2);// 将systick使用内核时钟,根据时钟树,即120/8=15M;
	
	count_1us = (float)(CLOCK_GetBootHSEValue()/8000000);
	count_1ms = (float)1000*count_1us;
}

void BOARD_Delay1Us(uint32_t count)
{
	uint32_t ctl;

	/* reload the count value */
    SysTick->LOAD = (uint32_t)(count * count_1us);
    /* clear the current count value */
    SysTick->VAL = 0x0000U;
    /* enable the systick timer */
    SysTick->CTRL = SysTick_CTRL_ENABLE_Msk;
    /* wait for the COUNTFLAG flag set */
    do{
        ctl = SysTick->CTRL;
    }while((ctl&SysTick_CTRL_ENABLE_Msk)&&!(ctl & SysTick_CTRL_COUNTFLAG_Msk));
    /* disable the systick timer */
    SysTick->CTRL &= ~SysTick_CTRL_ENABLE_Msk;
    /* clear the current count value */
    SysTick->VAL = 0x0000U;
	
}

void BOARD_Delay1Ms(uint32_t count)
{
    uint32_t ctl;
    
    /* reload the count value */
    SysTick->LOAD = (uint32_t)(count * count_1ms);
    /* clear the current count value */
    SysTick->VAL = 0x0000U;
    /* enable the systick timer */
    SysTick->CTRL = SysTick_CTRL_ENABLE_Msk;
    /* wait for the COUNTFLAG flag set */
    do{
        ctl = SysTick->CTRL;
    }while((ctl&SysTick_CTRL_ENABLE_Msk)&&!(ctl & SysTick_CTRL_COUNTFLAG_Msk));
    /* disable the systick timer */
    SysTick->CTRL &= ~SysTick_CTRL_ENABLE_Msk;
    /* clear the current count value */
    SysTick->VAL = 0x0000U;
}

实验现象
BOARD_Delay1Ms(1000)
BOARD_Delay1Us(1000)
产生的对应波形为
在这里插入图片描述

在这里插入图片描述

b、 采用不分频的方式

设置systick的时钟=sysclk=120M,所以1us需要计数120次,1ms需要计数120*1000次。
us延时设置LOAD寄存器=sysclk/1000000;
ms延时设置LOAD寄存器=sysclk/1000;
当每次计数结束时,就是LOAD减为0的时候,CTRL寄存器的16位会置为1,我们监测这位的数值即可实现延时。这里同上面一样
实现代码

uint32_t BOARD_Systick_Init(uint32_t ticks)
{ 
  if (ticks > SysTick_LOAD_RELOAD_Msk)  return (1);            /* Reload value impossible */
                                                               
  SysTick->LOAD  = (ticks & SysTick_LOAD_RELOAD_Msk) - 1;      /* set reload register */
  NVIC_SetPriority (SysTick_IRQn, (1<<__NVIC_PRIO_BITS) - 1);  /* set Priority for Cortex-M0 System Interrupts */
  SysTick->VAL   = 0;                                          /* Load the SysTick Counter Value */
  SysTick->CTRL  = SysTick_CTRL_CLKSOURCE_Msk | 
                   SysTick_CTRL_ENABLE_Msk;                    /* Enable SysTick IRQ and SysTick Timer */
  SysTick->CTRL  &= ~SysTick_CTRL_TICKINT_Msk;
  return (0);                                                  /* Function successful */
}

void BOARD_Delay1Us( __IO uint32_t us)
{
	uint32_t i;	
	BOARD_Systick_Init(CLOCK_GetBootHSEValue() / 1000000);
	
	for(i=0;i<us;i++)
	{
		/* When the counter value decreases to 0, bit 16 of the CRTL register will be set to 1 */
		/* When set to 1, reading this bit will clear it to 0 */
		while( !((SysTick->CTRL)&(1<<16)) );
	}
	/* Turn off the SysTick timer */
	SysTick->CTRL &=~ SysTick_CTRL_ENABLE_Msk;
}

void BOARD_Delay1Ms( __IO uint32_t ms)
{
	uint32_t i;	
	BOARD_Systick_Init(CLOCK_GetBootHSEValue() / 1000);
	
	for(i=0;i<ms;i++)
	{
		/* When the counter value decreases to 0, bit 16 of the CRTL register will be set to 1 */
		/* When set to 1, reading this bit will clear it to 0 */
		while( !((SysTick->CTRL)&(1<<16)) );
	}
	/* Turn off the SysTick timer */
	SysTick->CTRL &=~ SysTick_CTRL_ENABLE_Msk;
}

中断方式延时

设置每1ms触发中断,在中断里记录中断次数,亦可实现ms级的延时。

volatile static uint32_t delay;

uint32_t BOARD_Systick_Init(uint32_t ticks)
{ 
  if (ticks > SysTick_LOAD_RELOAD_Msk)  return (1);            /* Reload value impossible */
                                                               
  SysTick->LOAD  = (ticks & SysTick_LOAD_RELOAD_Msk) - 1;      /* set reload register */
  NVIC_SetPriority (SysTick_IRQn, (1<<__NVIC_PRIO_BITS) - 1);  /* set Priority for Cortex-M0 System Interrupts */
  SysTick->VAL   = 0;                                          /* Load the SysTick Counter Value */
  SysTick->CTRL  = SysTick_CTRL_CLKSOURCE_Msk | 
                   SysTick_CTRL_ENABLE_Msk;                    /* Enable SysTick IRQ and SysTick Timer */
  SysTick->CTRL  |= SysTick_CTRL_TICKINT_Msk;
  return (0);                                                  /* Function successful */
}

void BOARD_Delay1Ms(uint32_t count)
{
    delay = count;

    while(0U != delay){
    }
}

void BOARD_Delay_Decrement(void)
{
    if (0U != delay){
        delay--;
    }
}

void SysTick_Handler(void)
{
	BOARD_Delay_Decrement();
}

4、代码

https://gitee.com/xiaoguo-tec_0/mm32-f3273.git

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/624793.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Android系统的启动流程(二):SystemServer处理过程

Android系统的启动流程&#xff08;二&#xff09;&#xff1a;SystemServer处理过程 摘要 在上篇文章中&#xff0c;我们已经将启动的进程推进到了ZygoteInit的main中&#xff0c;在ZygoteInit中我们已经知道它的main方法中的forkSystemServer方法将会启动系统服务&#xff0…

机器学习 | 支持向量机SVM | 概念了解向

概念了解向&#xff0c;参考视频&#xff1a; 【小萌五分钟】机器学习 | 支持向量机 SVM &#x1f4da;最大间隔分类器 如下图有两种不同颜色的点。我需要一个分类器告诉我&#xff0c;假设在下图中新加入一个点&#xff0c;应该将它分类至红点还是蓝点。考虑加入一条决策边界…

【4 微信小程序学习 - WXSS-WXML-WXS语法】

1 WXSS相关 1 小程序样式的写法 2 WXSS支持的选择器 3 wxss的扩展 – 尺寸单位RPX rpx是为了屏幕自适应. 4 逻辑判断 wx:if – wx:elif – wx:else 对应v-if <!-- 2.条件判断 --> <view wx:if"{{score > 90}}">优秀</view> <view wx:…

程序员兼职接单的平台列表

最近有很多程序员朋友说想要找一份合适的兼职工作&#xff0c;却苦于找不到一个正规靠谱的平台。今天我特意整理了一份超详尽的程序员兼职接单平台list&#xff0c;各位可以按需选择&#xff0c;也希望大家都能找到心仪的工作~ 中高端开发者必备的兼职接单平台&#xff1a;程序…

Ubuntu 登录提示信息`Message of The Day`(MOTD)定制与开关

一、效果 登录Ubuntu的时候&#xff0c;在控制台可能会弹出一系列提示消息&#xff0c;有欢迎消息、系统信息、更新信息等等&#xff1a; 这些提示消息被称为Message of The Day&#xff0c;简称MOTD。 Ubuntu与其它Linux版本不太一样&#xff0c;它引入了MOTD 的概念。 这些…

如何使用SonarQube+ SonarScanner分析项目

前言&#xff1a; 六一儿童节要玩程序员的玩具&#xff0c;动手试一试挺有意思的 目录 1. 安装sonarqube 2. 获取Sonarqube令牌 3. 下载安装SonarScanner 5. SonarScanner分析项目 7. 查看分析结果 8.常见问题 版本信息&#xff1a; Sonarqube7.6Sonar-scanner-4.8.0 …

[操作系统]关于进程的管理

首先注明:仍然是复习阶段,所以和课本可能有些许冲突和不同,只是图谱来自于王道考研2022操作系统,旨在快速梳理操作系统的基本知识 1.进程的定义,概念和特征: 多道程序环境下,多个程序并发执行,因此他们将会失去封闭性,不适宜于管理,所以引入了进程这种概念. 进程是程序的一次…

Python自动化测试:pytest实现关键字驱动

在上一篇文章中&#xff0c;我编写了一个非常简单的关键字驱动程序&#xff0c; 不过这个程序只是跑通了功能&#xff0c;还有很多可以优化的地方&#xff0c;这篇文章我想通过 pytest 来简化自动化测试用例的编写&#xff0c;使用的是比较基础的 pytest 功能。 下篇文章我再写…

spark安装部署

spark安装部署 需要指导私信 所有节点安装scala&#xff0c;安装scala需要安装openjdk-8-jre&#xff08;当前用户如果没有sudo权限可将其加入sudo组里&#xff09;,以ubuntu2204-LTS为例&#xff1a; $ sudo apt update $ sudo apt-get install openjdk-8-jre-headless -y (红…

【03Eclipse 窗口说明】对每个窗口和视图的功能和用途的详细说明导航栏编辑器窗口项目资源管理器

Eclipse 窗口说明 简介 Eclipse 是一款功能强大的集成开发环境&#xff08;IDE&#xff09;&#xff0c;提供了丰富的窗口和视图来支持开发工作。本教程将详细介绍 Eclipse 主要窗口和常见视图的功能和用途。 主要窗口 1. 导航栏 导航栏位于 Eclipse 窗口的顶部&#xff0…

Java学习路线(22)——测试框架Junit

一、单元测试概念 单元测试就是针对最小的功能单元编写测试代码&#xff0c;Java程序最小的功能单元是方法&#xff0c;因此&#xff0c;单元测试就是针对Java方法的测试&#xff0c;进而检查方法正确性。 二、Junit测试框架 &#xff08;一&#xff09;概念&#xff1a; Jun…

认识、使用 yarn

概念 npm 是前端开发过程中常常使用的命令&#xff0c;比如构建 Vue 项目&#xff0c;亦或下载 Vue 项目依赖但是该命令效率低下&#xff0c;且容易出错&#xff0c;有没有更好的解决方案呢?有&#xff0c;Yarn ta是一个快速、可靠且安全的 JS 包管理工具: 快速:Yamn 本地缓…

黑客松指南|如何快速注册参与Sui x KuCoin Labs Hackathon

由Sui和KuCoin Labs联合主办的夏季黑客松&#xff0c;将为开发者、设计师、创业者和区块链爱好者提供一个交流和合作的平台。参与者将有机会利用Sui的先进技术和KuCoin Labs的资源&#xff0c;开发创新的区块链应用和解决方案。 我们鼓励参与者围绕「基础设施和工具」、「NFT、…

如何使用Jemeter对HTTP进行接口压测?没有比这个更详细的教程

目录 前言 1、首先添加一线程组 2、因为是对HTTP接口进行压力测试&#xff0c;所以需要在线程组下添加一HTTP请求&#xff08;通过鼠标右键->添加->Sampler->HTTP请求 完成&#xff09; 3、紧接着就是对HTTP请求进行设置了&#xff0c;主要设置服务器名称或IP&#…

10年心路历程:一个女测试工程师功能测试转向自动化测试/开发

十年测试心路历程&#xff1a; 由于历史原因&#xff0c;大部分测试人员&#xff0c;最开始接触都是纯功能界面测试&#xff0c;随着工作年限&#xff0c;会接触到一些常用测试工具&#xff0c;比如抓包&#xff0c;数据库&#xff0c;linux等。 我大学学的计算机专业&#xff…

【力扣刷题 | 第四天】 1.两数之和 454.四数之和

1. 两数之和 - 力扣&#xff08;LeetCode&#xff09; 给定一个整数数组 nums 和一个整数目标值 target&#xff0c;请你在该数组中找出 和为目标值 target 的那 两个 整数&#xff0c;并返回它们的数组下标。 你可以假设每种输入只会对应一个答案。但是&#xff0c;数组中同…

【QT】解决继承QThread的子线程导致程序无法关闭主线程关闭太快导致子线程中的槽方法未执行

背景 使用串口进行通信 一共有三个线程 主线程负责界面的显示子线程1负责检测当前系统可用的串口子线程2负责差串口通信 子线程实现 在发生问题的最初&#xff0c;因为要一直检测当前系统的可用线程&#xff0c;所以线程1我使用继承自QThread实现的线程&#xff0c;其中重写ru…

github下载的项目如何上传到gitee

1、安装git 省略 2、github下载项目 如何注册、登录省略 3、上传到gitee 注册账号 省略 新建仓库 iot-plat创建过了&#xff0c;用iot-plat1演示 创建完的仓库 此处的https地址要记住&#xff0c;等会要用到 到本地项目目录 项目里面 Git命令操作 空白处右键&#xff…

CSP-S 第一轮笔试重点题

CSP-S提高组笔试题重点题汇总&#xff1a; 今天我给大家分享一些 CSP-S 第一轮笔试中的一些重点题&#xff0c;包含讲解。 第一题&#xff1a; 1.十进制小数13.375对应的二进制数是&#xff08;&#xff09;。 A.1101.011 B.1011.011 C.1101.101 D.1010.01 解析&#x…

一起学SF框架系列5.3-模块Beans-bean与Spring容器的交互方式

正常情况下&#xff0c;应用中的bean同spring容器关系如下图&#xff1a; 尽管应用bean是Spring容器创建并建立依赖关系&#xff0c;应用只需使用bean即可&#xff0c;因此对bean来说Spring容器就是无感知的&#xff08;无侵入编程&#xff09;。但是还是存在需求需要应用bea…