全志T113-S3裸机定时器驱动(timer0,timer1操作)

        虽然只有2个定时器,但是好在是32bit的,日常使用刚好够,1个定时器当做StopWatch定时器,1us精度,用于时间测量,1个定时器给OS作为滴答时钟使用。

        直接上代码:

/************************************************************************************************************** 文件名:		t113_timer.c* 功能:		t113定时器支持* 作者:		cp1300@139.com* 邮箱:		cp1300@139.com* 创建时间:	2023-09-30* 最后修改时间:2023-09-30* 详细:		支持timer0 timer1 2个32bit定时器
*************************************************************************************************************/
#include "t113_system.h"
#include "t113_map.h"
#include "typedef.h"
#include "t113_timer.h"
#include "t113_const.h"/*
writel(0x2EE0, TMR_0_INTV); //Set the interval value
writel(0x94, TMR_0_CTRL); //Select Single mode, 24 MHz clock source, 2 pre-scale
writel(readl(TMR_0_CTRL)|(1<<1), TMR_0_CTRL); //Set the Reload bit
while((readl(TMR_0_CTRL)>>1)&1); //Waiting the Reload bit turns to 0
writel(readl(TMR_0_CTRL)|(1<<0), TMR_0_CTRL); //Enable Timer0
*/static void (*sg_pTimer0_Callback)(void) = NULL;	//定时器0中断回调,外部初始化
static void (*sg_pTimer1_Callback)(void) = NULL;	//定时器0中断回调,外部初始化void TIMER0_IRQHandler(void);	//中断处理函数
void TIMER1_IRQHandler(void);	//中断处理函数/*************************************************************************************************************************
* 函数			:	void T113_TimerSet(TIMER_CH ch, bool isPeriodicMode,TIMER_PRES_TYPE Pers, u32 Cycle, bool isEnableInt, void (*pCallback)())
* 功能			:	定时器设置
* 参数			:	ch:定时器通道选择;isPeriodicMode:是否为周期模式(否则为单次模式);Pers:分频设置;Cycle:计数周期;isEnableInt:是否使能中断;pCallback:中断回调
* 返回			:	无
* 依赖			:	底层宏定义
* 作者			:	cp1300@139.com
* 时间			:	2023-09-30
* 最后修改时间 	: 	2023-09-30
* 说明			:	会关闭定时器,不会启动定时器
*************************************************************************************************************************/
void T113_TimerSet(TIMER_CH ch, bool isPeriodicMode, TIMER_PRES_TYPE Pers, u32 Cycle, bool isEnableInt, void (*pCallback)())
{switch (ch){case TIMER_CH0:{r_TMR_IRQ_EN &= ~BIT0;	//关闭定时器0 中断r_TMR0_CTRL = 0;									//关闭定时器0if (FALSE == isPeriodicMode) r_TMR0_CTRL |= BIT7;	//单次模式r_TMR0_CTRL |= (Pers & 0x07) << 4;					//设置分频if (Pers & 0x0100) r_TMR0_CTRL |= 1 << 2;			//使用24MHz时钟r_TMR0_INTV_VALUE = Cycle;							//设置初值r_TMR0_CUR_VALUE = Cycle;							//计数器值r_TMR0_CTRL |= BIT1;								//使能自动重载,会自动清除if (TRUE == isEnableInt)	//使能中断了{r_TMR_IRQ_STA |= BIT0;	//清除中断0状态r_TMR_IRQ_EN |= BIT0;	//使能中断sg_pTimer0_Callback = pCallback;				//设置中断回调GIC_SetIrqPriority(GIC_IRQ_TIMER0, 1);	                    		//GIC设置一个中断的优先级GIC_SetIrqEdgeTriggered(GIC_IRQ_TIMER0, TRUE);              		//GIC设置一个中断为边沿触发GIC_RegisterIRQHandler(GIC_IRQ_TIMER0, TIMER0_IRQHandler);   		//注册中断服务程序GIC_IrqEnable(GIC_IRQ_TIMER0, TRUE);	                    		//GIC中断使能-中断使能}else{sg_pTimer0_Callback = NULL;GIC_IrqEnable(GIC_IRQ_TIMER0, FALSE);	                    		//GIC中断使能-中断关闭}}break;case TIMER_CH1:{r_TMR_IRQ_EN &= ~BIT1;	//关闭定时器1中断r_TMR1_CTRL = 0;									//关闭定时器1if (FALSE == isPeriodicMode) r_TMR1_CTRL |= BIT7;	//单次模式r_TMR1_CTRL |= (Pers & 0x07) << 4;					//设置分频if (Pers & 0x0100) r_TMR1_CTRL |= 1 << 2;			//使用24MHz时钟r_TMR1_INTV_VALUE = Cycle;							//设置初值r_TMR1_CUR_VALUE = Cycle;							//计数器值r_TMR1_CTRL |= BIT1;								//使能自动重载,会自动清除if (TRUE == isEnableInt)	//使能中断了{r_TMR_IRQ_STA |= BIT1;	//清除中断1状态r_TMR_IRQ_EN |= BIT1;	//使能中断sg_pTimer1_Callback = pCallback;				//设置中断回调GIC_SetIrqPriority(GIC_IRQ_TIMER1, 3);	                    		//GIC设置一个中断的优先级GIC_SetIrqEdgeTriggered(GIC_IRQ_TIMER1, TRUE);              		//GIC设置一个中断为边沿触发GIC_RegisterIRQHandler(GIC_IRQ_TIMER1, TIMER1_IRQHandler);   		//注册中断服务程序GIC_IrqEnable(GIC_IRQ_TIMER1, TRUE);	                    		//GIC中断使能-中断使能}else{sg_pTimer1_Callback = NULL;GIC_IrqEnable(GIC_IRQ_TIMER1, FALSE);	                    		//GIC中断使能-中断关闭}}break;default: return;}
}/*************************************************************************************************************************
* 函数			:	void T113_TimerEnable(TIMER_CH ch, bool isEnable)
* 功能			:	使能定时器(开启或关闭定时器)
* 参数			:	ch:定时器通道选择;isEnable:TRUE:开启定时器;FALSE:关闭定时器
* 返回			:	无
* 依赖			:	底层宏定义
* 作者			:	cp1300@139.com
* 时间			:	2023-09-30
* 最后修改时间 	: 	2023-09-30
* 说明			:	需要提前初始化定时器
*************************************************************************************************************************/
void T113_TimerEnable(TIMER_CH ch, bool isEnable)
{switch (ch){case TIMER_CH0:{if (TRUE == isEnable){r_TMR0_CTRL |= BIT0;	//使能定时器}else{r_TMR0_CTRL &= ~BIT0;	//关闭定时器}}break;case TIMER_CH1:{if (TRUE == isEnable){r_TMR1_CTRL |= BIT0;	//使能定时器}else{r_TMR1_CTRL &= ~BIT0;	//关闭定时器}}break;default:return;}
}/*************************************************************************************************************************
* 函数			:	u32 T113_GetTimerCount(TIMER_CH ch)
* 功能			:	获取计数器当前值
* 参数			:	ch:定时器通道选择
* 返回			:	无
* 依赖			:	底层宏定义
* 作者			:	cp1300@139.com
* 时间			:	2023-10-02
* 最后修改时间 	: 	2023-10-02
* 说明			:	自减计数器
*************************************************************************************************************************/
u32 T113_GetTimerCount(TIMER_CH ch)
{switch (ch){case TIMER_CH0: return r_TMR0_CUR_VALUE;case TIMER_CH1: return r_TMR1_CUR_VALUE;default:return 0;}
}/*************************************************************************************************************************
* 函数			:	void T113_ClearTimerInt(TIMER_CH ch)
* 功能			:	清除定时器中断
* 参数			:	ch:定时器通道选择
* 返回			:	无
* 依赖			:	底层宏定义
* 作者			:	cp1300@139.com
* 时间			:	2024-07-19
* 最后修改时间 	: 	2024-07-19
* 说明			:	
*************************************************************************************************************************/
void T113_ClearTimerInt(TIMER_CH ch)
{switch (ch){case TIMER_CH0: r_TMR_IRQ_STA |= BIT0; break;	//清除中断0状态case TIMER_CH1: r_TMR_IRQ_STA |= BIT1; break;	//清除中断1状态default:break;}
}//中断处理函数 timer0
void TIMER0_IRQHandler(void)
{r_TMR_IRQ_STA |= BIT0;	//清除中断0状态if (sg_pTimer0_Callback != NULL) sg_pTimer0_Callback();
}//中断处理函数 timer1
void TIMER1_IRQHandler(void)
{r_TMR_IRQ_STA |= BIT1;	//清除中断1状态if (sg_pTimer1_Callback != NULL) sg_pTimer1_Callback();
}
/************************************************************************************************************** 文件名:		t113_timer.h* 功能:		t113定时器支持* 作者:		cp1300@139.com* 邮箱:		cp1300@139.com* 创建时间:	2023-09-30* 最后修改时间:2023-09-30* 详细:		支持timer0 timer1 2个32bit定时器
*************************************************************************************************************/
#ifndef _T113_TIMER_H_  
#define _T113_TIMER_H_
#include "typedef.h"
#include "t113_map.h"
#include "t113_const.h"//普通定时器通道选择
typedef enum
{TIMER_CH0 = 0,TIMER_CH1 = 1,
}TIMER_CH;//分频选择
typedef enum
{TIMER_PRES_LOSC_1_1 = 0x0100,	//LOSC 1分频TIMER_PRES_LOSC_1_2 = 0x0101,	//LOSC 2分频TIMER_PRES_LOSC_1_4 = 0x0102,	//LOSC 4分频TIMER_PRES_LOSC_1_8 = 0x0103,	//LOSC 8分频TIMER_PRES_LOSC_1_16 = 0x0104,	//LOSC 16分频TIMER_PRES_LOSC_1_32 = 0x0105,	//LOSC 32分频TIMER_PRES_LOSC_1_64 = 0x0106,	//LOSC 64分频TIMER_PRES_LOSC_1_128 = 0x0107,	//LOSC 128分频TIMER_PRES_24M_1_1 = 0x0100,	//24MHz 1分频TIMER_PRES_24M_1_2 = 0x0101,	//24MHz 2分频TIMER_PRES_24M_1_4 = 0x0102,	//24MHz 4分频TIMER_PRES_24M_1_8 = 0x0103,	//24MHz 8分频TIMER_PRES_24M_1_16 = 0x0104,	//24MHz 16分频TIMER_PRES_24M_1_32 = 0x0105,	//24MHz 32分频TIMER_PRES_24M_1_64 = 0x0106,	//24MHz 64分频TIMER_PRES_24M_1_128 = 0x0107,	//24MHz 128分频
}TIMER_PRES_TYPE;void T113_TimerSet(TIMER_CH ch, bool isPeriodicMode, TIMER_PRES_TYPE Pers, u32 Cycle, bool isEnableInt, void (*pCallback)());//定时器设置
void T113_TimerEnable(TIMER_CH ch, bool isEnable);	//使能定时器(开启或关闭定时器)
u32 T113_GetTimerCount(TIMER_CH ch);				//获取计数器当前值
void T113_ClearTimerInt(TIMER_CH ch);				//清除定时器中断#endif //_T113_TIMER_H_

注意:定时器需要使用中断,中断需要依赖GIC。

测试代码:

//中断回调0-闪烁LED
static void time0_callback(void)
{GPIOD->DATA ^= BIT16;
}//中断回调1-打印数据
static void time1_callback(void)
{static u32 count = 0;uart_printf("tim1:%u\r\n", count++);
}//定时器测试
void timer_test(void)
{//timer0 500毫秒中断T113_TimerSet(TIMER_CH0, TRUE, TIMER_PRES_24M_1_1, 24 * 1000000 * 0.5, TRUE, time0_callback);//定时器设置T113_TimerEnable(TIMER_CH0, TRUE);	//使能定时器(开启或关闭定时器)//timer1 1中断T113_TimerSet(TIMER_CH1, TRUE, TIMER_PRES_24M_1_1, 24 * 1000000 * 1, TRUE, time1_callback);	//定时器设置T113_TimerEnable(TIMER_CH1, TRUE);	//使能定时器(开启或关闭定时器)
}

例子:

给FreeOS作为滴答时钟


//RTOS滴答时钟中断初始化
void vConfigureTickInterrupt( void )
{T113_TimerSet(FREE_RTOS_TIME_CH, TRUE, TIMER_PRES_24M_1_8, RTOS_TIME_CYCLE, TRUE, FreeRTOS_Tick_Handler);T113_TimerEnable(FREE_RTOS_TIME_CH, TRUE);				//启动定时器      
}
/*-----------------------------------------------------------*/void vClearTickInterrupt( void )
{T113_ClearTimerInt(FREE_RTOS_TIME_CH);//清除定时器中断
}void vApplicationIRQHandler(uint32_t ulICCIAR)
{if (ulICCIAR == GIC_IRQ_TIMER0)	//如果是定时器0中断,则直接调用 FreeRTOS_Tick_Handler() ,因为定时器0是滴答时钟中断{g_OS_RunTime ++;									//操作系统运行时间-单位msFreeRTOS_Tick_Handler();		//由于直接调用了 FreeRTOS_Tick_Handler 导致定时器的中断没有被清除,所以必须实现 vClearTickInterrupt()}else{SystemIrqHandler(ulICCIAR);}
}

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

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

相关文章

无线领夹麦克风哪个牌子好?几十块和几百块的领夹麦克风推荐

现如今视频自媒体行业还在蓬勃发展&#xff0c;麦克风对于自媒体行业可以说是必不可少的装备了&#xff0c;在互联网“内卷”的时代&#xff0c;各大视频博主、Up主、主播大多都会使用无线麦克风来辅助视频和直播内容输出。无线领夹麦克风作为视频行业中的麦克风新宠&#xff0…

深入理解TCP:互联网通信的基石

深入理解TCP&#xff1a;互联网通信的基石 引言TCP的普遍应用TCP连接的建立与维护三次握手&#xff08;Three-Way Handshake&#xff09;连接的可靠性与超时重传数据传输与流量控制连接的终止状态转换 TCP与UDP的对比TCP协议栈的层级结构应用层&#xff08;Application Layer&a…

DevExpress WPF中文教程:如何完成GridControl的列和编辑器配置?

DevExpress WPF拥有120个控件和库&#xff0c;将帮助您交付满足甚至超出企业需求的高性能业务应用程序。通过DevExpress WPF能创建有着强大互动功能的XAML基础应用程序&#xff0c;这些应用程序专注于当代客户的需求和构建未来新一代支持触摸的解决方案。 无论是Office办公软件…

【C++BFS算法】2192. 有向无环图中一个节点的所有祖先

本文涉及知识点 CBFS算法 LeetCode2192. 有向无环图中一个节点的所有祖先 给你一个正整数 n &#xff0c;它表示一个 有向无环图 中节点的数目&#xff0c;节点编号为 0 到 n - 1 &#xff08;包括两者&#xff09;。 给你一个二维整数数组 edges &#xff0c;其中 edges[i]…

springcloud rocketmq 新增的消费者组从哪里开始消费

如果新建一个新的消费者组&#xff0c;是否会消费历史消息&#xff0c;导致重复消费&#xff1f; 直接在 console 界面新增消费者组&#xff0c;但是没有办法绑定订阅关系&#xff0c;没有找到入口&#xff0c;在 控制台项目源码 rocketmq-externals 也没有找到可以确定订阅关系…

Android 常用调试工具/方法解析

一、内存相关 参考Android内存分析命令_dumpsys meminfo 算出rss-CSDN博客 1、基本概念 1&#xff09;PSS & RSS & USS & VSS a、PSS 概念&#xff1a;全称Proportional Set Size&#xff0c;根据进程实际使用的内存量按照共享比例分配给进程的一种内存度量方…

SpringBoot 项目配置文件注释乱码的问题解决方案

一、问题描述 在项目的配置文件中&#xff0c;我们写了一些注释&#xff0c;如下所示&#xff1a; 但是再次打开注释会变成乱码&#xff0c;如下所示&#xff1a; 那么如何解决呢&#xff1f; 二、解决方案 1. 点击” File→Setting" 2. 搜索“File Encodings”, 将框…

华为OD机试 - 小明找位置 (Java 2024年C卷D卷)

华为OD机试&#xff08;C卷D卷&#xff09;2024真题目录(Java & c & python) 题目描述 小朋友出操&#xff0c;按学号从小到大排成一列;小明来迟了&#xff0c;请你给小明出个主意&#xff0c;让他尽快找到他应该排的位置。 算法复杂度要求不高于nLog(n);学号为整数…

Wonder3D 论文学习

论文链接&#xff1a;https://arxiv.org/abs/2310.15008 代码链接&#xff1a;https://github.com/xxlong0/Wonder3D 解决了什么问题&#xff1f; 随着扩散模型的提出&#xff0c;3D 生成领域取得了长足进步。从单张图片重建出 3D 几何是计算机图形学和 3D 视觉的基础任务&am…

World of Warcraft [CLASSIC] Timebadge

游戏币【每个服务器实时金价不一样&#xff0c;本例子是5000-6000金】 1枚【魔兽世界时光徽章】 30天游戏时间。 5760金币游戏币&#xff0c;策划如何消耗游戏里面的金币总量&#xff0c;以及如何留住那些非人民币玩家呢 30天加上去了 World of Warcraft [CLASSIC] [魔兽世界…

c# TcP 开发

在C#中进行TCP开发&#xff0c;通常使用System.Net.Sockets命名空间下的TcpListener和TcpClient类。以下是一个简单的TCP服务器和客户端示例。 TCP服务器端: using System; using System.Net; using System.Net.Sockets; using System.Text;class TcpServer {private TcpList…

搜索与下载Stable Diffusion 模型

我只是一个刚开始学习SD没多久小白&#xff0c;拿到别人的工作流想要运行时&#xff0c;很多时候还要下载对应的模型才能正常运行&#xff0c;虽然也可以通过comfyui-manager下载&#xff0c;不过有时候好像会下载失败&#xff0c;而单独下载所需模型&#xff0c;我自己试过&am…

WebKit的屏幕唤醒:保持设备活力的API

WebKit的屏幕唤醒&#xff1a;保持设备活力的API 在现代Web应用中&#xff0c;保持用户的持续参与和提供流畅的体验至关重要。WebKit的屏幕唤醒&#xff08;Wake Lock API&#xff09;为此提供了一个强大的解决方案。这个API允许Web应用在特定条件下阻止设备的屏幕进入休眠状态…

英语科技写作 希拉里·格拉斯曼-蒂(英文版)pdf下载

下载链接&#xff1a; 链接1&#xff1a;https://pan.baidu.com 链接2&#xff1a;/s/1fxRUGnlJrKEzQVF6k1GmBA 提取码&#xff1a;b69t 由于是英文版&#xff0c;可能有些看着不太方便&#xff0c;可以在网页版使用以下软件中英文对照着看&#xff0c;看着更舒服&#xff0c;…

Centos常用运维命令及使用示例

命令 功能说明 使用示例 man 查看命令帮助 man ls help 查看Linux内置命令的帮助 help cd ls 功能是列出目录的内容 ls cd 从当前工作目录切换到指定的工作目录 cd /root/home cp 其功能为复制文件或目录 cp file1 /root/home/file2 find 用于查找目录及目录下的文件 find /hom…

图书管理系统设计

设计一个图书管理系统时&#xff0c;我们需要考虑系统的基本功能、用户需求、技术选型以及数据的安全性和完整性。下面是一个基本的图书管理系统的设计概览&#xff1a; 1. 系统目标 管理图书信息&#xff1a;添加、删除、修改图书信息。借阅管理&#xff1a;处理借书、还书流…

Express 框架基本用法以及相关知识点

Express框架基本用法包括安装、创建应用、监听请求和响应客户端 Express 框架基本用法 1.安装&#xff1a; 使用npm或cnpm将Express安装到项目中&#xff0c;命令为$ npm install express4.17.1。安装后&#xff0c;还需安装一些额外的中间件&#xff0c;如body-parser、coo…

Python 教程(二):语法与数据结构

目录 前言专栏列表语法特点实例代码基本数据类型变量命名规则赋值动态类型作用域示例代码 运算符list、set和dict 数据结构 区别1. list&#xff08;列表&#xff09;2. set&#xff08;集合&#xff09;3. dict&#xff08;字典&#xff09; 总结 前言 Python 是一种计算机编…

Linux调试器gdb

1.debug版本的文件才能调试 gcc默认编译生成的是release版本&#xff0c;在输入gcc编译指令时&#xff0c;要加-g&#xff0c;才会生成debug版本的可执行文件。 可以看到&#xff0c;code_dbug比code大&#xff0c;因为debug版本含有调试信息&#xff0c;往往比release版本的…

【BUG】已解决:SyntaxError:positional argument follows keyword argument

SyntaxError:positional argument follows keyword argument 目录 SyntaxError:positional argument follows keyword argument 【常见模块错误】 【解决方案】 欢迎来到英杰社区https://bbs.csdn.net/topics/617804998 欢迎来到我的主页&#xff0c;我是博主英杰&#xff0c…