【裸机开发】GPT 定时器(三) —— 使用GPT实现高精度延时

news2024/11/16 18:07:42

延时最简单粗暴的方式就是使用空循环来延时,依赖的是时钟主频(默认是396M)来计数,一旦修改了 6ull 的时钟主频,延时效果就会存在偏差。

因此我们可以使用 EPIT 或者 GPT 的计数功能实现高精度延时,EPIT 是向下计数(自减),GPT 是向上计数(自增)。


目录

一、GPT 初始化

二、延时函数delayus(us 级)

1、原理解析

2、具体实现

三、延时函数delayms(ms级)


一、GPT 初始化

和前面定时中断不一样,如果只是要实现延时功能的话,无需初始化中断,因为延时只用到了 GPT 的计数功能。

  • GPT 复位,并等待复位完成
  • 配置GPT定时器(设置计数器初始值、选择时钟源、选择工作模式)
  • 设置分频数(66 分频)
  • 启动定时器
/*
 * @description	: gpt 定时初始化(不会产生中断,只是单纯的计数)
 * @param 		: 定时器时间间隔
 * @return 		: 无
 */
void delay_init()
{
	// 禁用GPT定时器
    GPT1_CR = 0;
	GPT1_CR |= (1 << 15);
	while((GPT1_CR >> 15) & 0x01);		// 等待复位完成

	/* 
     * 配置GPT定时器
     * bit 1: 1 设置计数器初始值为0
     * bit 8-6: 001 选择时钟源ipg_clk
     * bit 9: 1 选择工作模式free-run
     */
    GPT1_CR |= ((1 << 1) | (1 << 6) | (1 << 9));

	// 分频
	GPT1_PR &= ~(0xFFF << 0);    // 低 12 bit 清零
	GPT1_PR |= (65 << 0);        // 66 分频

	// 启动定时器
    GPT1_CR |= (1 << 0);
}

二、延时函数delayus(us 级)

比如我们要延时 500ms,66MHz时钟源,66分频的条件下,500ms 转换成计数值就是 500000,因此当 delta >= 500000 时,说明延时完毕,所以问题的关键就是求从开始到现在经过了多少计数值。

1、原理解析

Free-Run 模式下,当计数器到达 0xFFFF FFFF 时就会溢出,重新从 0 开始计数。如果计数器没有溢出,从开始到现在,计数的差值如下。(计数的差值是和时间关联的)

delta = newcount - oldcount;

如果计数器溢出了,从开始到现在,计数的差值如下

delta = delta1 + delta2 = 0xFFFFFFFF - oldcount + newcount;

注意:这里的 period 与时钟周期无关

2、具体实现

判断是否移除,需要用到 GPT1_SR 的 ROV 位(bit 5)。

/*
 * @description	: 延时函数(us级)
 * @param - n	: 要延时的us数
 * @return 		: 无
 */
void delayus(unsigned int val)
{
	// 获取到当前计数器的值
	unsigned int oldcount = GPT1_CNT;
	unsigned int delta = 0;
	while (1)
	{
		unsigned int newcount = GPT1_CNT;
		// 判断是否溢出
		if ((GPT1_SR >> 5) & 0x01)			// 说明溢出了
		{
			delta = 0xFFFFFFFF - oldcount + newcount;
		}
		else
		{
			delta = newcount - oldcount;
		}

		if (delta >= val)	break;    // 延时完毕,跳出循环
	}
	GPT1_SR &= ~(1 << 5);			// 清除溢出标志位
}

解析:if (delta >= val)

66 MHz 的时钟源,66分频 =》一个时钟周期的间隔就是 1/1M = 1/10^6

val 的单位是 us:

  • 转换成 s,结果 = val / 10^6
  • 转换成对应的计数值 = 10^6 * val / 10^6  = val

因此,val (us)经过转换以后,最终的计数值就是 val

三、延时函数delayms(ms级)

/*
 * @description	: 延时函数(ms级)
 * @param - n	: 要延时的ms数
 * @return 		: 无
 */
void delayms(unsigned int val)
{
	delayus(val * 1000);
}

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

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

相关文章

电气设备无线测温技术的优势有哪些?安科瑞 许敏

摘 要&#xff1a; 无线测温技术以其安装方便灵活、测温精度高、安全可靠、环境适应性好、便于集中管理等优点&#xff0c; 解决了电气设备长期带电运行状态下的温度在线监测问题&#xff0c; 提高了电气设备的运行可靠性&#xff0c; 在电力行业得到了广泛的应用。本文主要介…

将当前conda环境导出为yaml文件

conda环境的转移和复制 conda导出已有环境&#xff0c;环境会被保存在environment.yaml文件中。 conda env export > environment.yaml 当我们想再次创建该环境&#xff0c;或根据别人提供的.yaml文件复现环境时&#xff0c;就可以通过下面的命令来复现安装环境了。 conda …

【深度学习】Stable Diffusion

Stable Diffusion原理&#xff1a; https://zhuanlan.zhihu.com/p/632866251 训练过程&#xff1a; 文生图方法&#xff1a; 图生图方法&#xff1a;

CSS实现多头像叠加ui效果

第一种实现方式 简单粗暴直接使用margin-right实现&#xff0c;缺点是第一行右侧最右边头像溢出容器&#xff0c;代码中的三行注释的代码放开后可解决这个问题。 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8">&…

SQLyog登录错误解决

sqlyog登录错误号码2058解决 登录本地MySQL数据库 Microsoft Windows [版本 6.1.7601] 版权所有 (c) 2009 Microsoft Corporation。保留所有权利。C:\Users\Administrator>mysql -u root -p Enter password: **** Welcome to the MySQL monitor. Commands end with ; or \…

windows10 Linux子系统 Ubuntu 文件互相访问

ubuntu 访问Windows windows的磁盘被挂载到了/mnt下&#xff0c;可以看到我的电脑的c,d,e,f盘&#xff0c; windows 访问 ubuntu 在文件夹输入\wsl$ 再点击Ubuntu-22.04,进入文件夹

CSS 弹性布局

提示&#xff1a;这章比较重要&#xff0c;做复杂页面时经常会用到&#xff01;会不断更新❗ 文章目录 前言主轴和侧轴flex-direction 主轴方向flex-wrap 折行justify-content 主轴排列方式flex-start&#xff1a;默认左对齐flex-end&#xff1a;右对齐center&#xff1a;居中s…

如何在Maven中发布项目到Nexus私有服务器

本篇环境 nexus-3.55.0-01&#xff0c; Nexus安装在本地服务器 http://localhost:8081/maven-3.9.2 发布步骤 在项目机器的Maven的 settings.xml 配置Nexus的账号/密码 在settings.xml 的 <servers>节点增加 <server> 节点&#xff0c; 配置 Nexus 的登陆账号和…

Java使用pdf模板生成pdf文件

文章目录 前言如何生成pdf文件1. 制作pdf模板2. 填充pdf模板生成文件 前言 有时候&#xff0c;业务中我们需要使用pdf模板生成一份pdf文件。如何生成pdf文件&#xff1f; 如下&#xff0c;我们把左侧的模板生成为右侧的填充文件。 如何生成pdf文件 1. 制作pdf模板 &#xff…

【Linux】C++项目实战-UDP服务器

目录 UDP通信函数解析代码举例 广播函数解析代码举例 橙色 UDP通信 函数解析 #include <sys/types.h> #include <sys/socket.h> ssize_t sendto(int sockfd, const void *buf, size_t len, int flags, const struct sockaddr *dest_addr, socklen_t addrlen);- 参…

避雷器在线测试仪

一、产品概述 KDYZ-306氧化锌避雷器带电测试仪是用于检测氧化锌避雷器电气性能的专用仪器&#xff0c;该仪器适用于各种电压等级的氧化锌避雷器的带电或停电检测&#xff0c;从而及时发现设备内部绝缘受潮及阀片老化等危险缺陷。 仪器操作简单、使用方便&#xff0c;测量全过…

创建固定大小的文件(window 和 UBUNTU)

1、Windows Windows提供了一个强大的文件系统管理工具&#xff1a;fsutil.exe 例&#xff0c;在D盘上创建一个空文件file.txt&#xff0c;文件大小10k字节 fsutil file createnew D:\file.txt 1000 2、Ubuntu Ubuntu创建一个指定大小的文件用全零填充这个文件&#xff0c;例…

vue3 elementplus table合并

table表格下方合并写法&#xff1a; 1&#xff1a;单行合并 &#xff08;1&#xff09;在标签中加入属性 :summary-method"getSummaries":show-summary"true"<el-table:data"data"id"tableRef"ref"tableRef"row-key"…

CentOS Stream 10 计划已启动,即将进入初始化阶段

导读 但初始化的 CentOS Stream 10 暂时不会对外开放&#xff0c;也不会有太多活跃信息。从 Fedora 周期的规律来看&#xff0c;至少还有六个月的时间&#xff0c;CentOS Stream 10 才会正式启动开发流程&#xff0c;接受来自外部的贡献。周五的公告指出&#xff1a;你会看到 C…

智能优化算法改进策略之局部搜索算子(二)—模式搜索(以正余弦算法和灰狼算法为研究对象)

一、改进点基本介绍&#xff1a; 在目前多数的改进智能优化算法文献中&#xff0c;局部搜索算子的形式多种多样。它们主要被用来增强算法的局部开发能力&#xff0c;进而提升它们在优化问题特别在单峰问题上的收敛性能。作为一种高效的直接搜索法&#xff0c;模式搜索目前已被…

freemarker 使用word模板赋值

1. 引包<dependency><groupId>org.freemarker</groupId><artifactId>freemarker</artifactId><version>2.3.28</version></dependency>word文档工具类import freemarker.template.Configuration; import freemarker.template.…

将List转化为String 以逗号隔开

一.前言 在我们日常开发中, 在前后端交互的时候 , 会遇到多个id或其他字段存放到一个字段中, 这时我们会遇到一个List(集合)---->String(单个字段), 这时我们要进行操作数据, 使得我们的数据可以保存到数据库中 . 二.解决方法 2.1 利用StringBurilder或StringBuffer pub…

【git】idea怎么去替换git的地址

git 打开git地址添加或者修改git地址 打开git地址 右击->git->repository->remotes 添加或者修改git地址

​BCC Art Looks:BCC+Color Infrared

BCCColor Infrared 彩色红外 Effect Presets & Docs 效果预设和文档 Mocha Mask and Track Mocha 蒙版和跟踪 Mocha Mask... Mocha 蒙版... Pixel Chooser / Mocha 像素选择器 / Mocha PixelChooser - 像素选择器 View Mask / Matte - 查看蒙版/遮罩 Intensity - 强度 Ma…

java基础(并发编程)-线程状态转换

一、线程的状态 情况1 情况2 情况3 情况4 情况5 情况6 情况7 情况8 情况9 RUNNABLE <-->BLOCKED t 线程用synchronized(obj)获取了对象锁时如果竞争CPU时间片失败&#xff0c;线程的状态从RUNNABLE -->BLOCKED持obj锁线程的同步代码块执行完毕&#xff0c;会…