高云FPGA系列教程(6):ARM定时器使用

2023-09-18 21:25:02

本文是高云FPGA系列教程第6篇文章

本篇文章介绍片上ARM Cortex-M3硬核处理器定时器外设的使用,演示定时器溢出中断的配置方法,基于TangNano 4K开发板。

参考文档:Gowin_EMPU(GW1NS-4C)软件编程 参考手册

1. ARM定时器简介

GW1NSR-4C ARM处理器部分共有两个定时器,这两个定时器都是32位的,可以产生中断请求,也可以对外部输入信号进行计数,这两个定时器都挂载在APB1总线上,时钟源是PCLK1。

2. FPGA配置

和串口不同,定时器不用手动开启,直接在MCU程序中使用即可。

3. 常用函数

以下是定时器驱动库常用的一些函数,都比较容易理解,使用也很简单:

//定时器外设初始化,指定溢出值
void TIMER_Init(TIMER_TypeDef* TIMERx,TIMER_InitTypeDef* TIMER_InitStruct)
//启动定时器
void TIMER_StartTimer(TIMER_TypeDef* TIMERx)
//停止定时器
void TIMER_StopTimer(TIMER_TypeDef* TIMERx)
//读取中断状态
ITStatus TIMER_GetIRQStatus(TIMER_TypeDef* TIMERx)
//清除中断状态
void TIMER_ClearIRQ(TIMER_TypeDef* TIMERx)
//读取重载值(溢出值)
uint32_t TIMER_GetReload(TIMER_TypeDef* TIMERx)
//设定重载值
void TIMER_SetReload(TIMER_TypeDef* TIMERx,uint32_t value)
//获取当前计数值
uint32_t TIMER_GetValue(TIMER_TypeDef* TIMERx)
//手动指定计数值
void TIMER_SetValue(TIMER_TypeDef* TIMERx,uint32_t value)
//使能中断
void TIMER_EnableIRQ(TIMER_TypeDef* TIMERx)
//禁止中断
void TIMER_DisableIRQ(TIMER_TypeDef* TIMERx)
//外部输入使能
void TIMER_SelExtEnable(TIMER_TypeDef *TIMER)
//选择外部输入时钟
void TIMER_SelExtClock(TIMER_TypeDef *TIMER)

GW1NSR-4C定时器一般配置步骤如下:

1. 定时器初始化。指定重载值(溢出值)
2. NVIC使能定时器中断源,并指定优先级
3. 开启定时器中断
4. 启动定时器
5. 定时器中断服务函数实现,并清除中断

4. MCU程序设计

MCU程序可以使用Keil或GWD进行设计,参考上一篇文章提供的工程模板

首先是定时器和中断控制器初始化,开启中断并指定优先级:

int timer_init(void)
{
    TIMER_InitTypeDef tmr0;
    NVIC_InitTypeDef InitTypeDef_NVIC;
    
    tmr0.Reload = PCLK1/2;	//APB1 CLK, 500ms定时器
    TIMER_Init(TIMER0, &tmr0);

    //Interrupt priority configuration
    NVIC_PriorityGroupConfig(NVIC_PriorityGroup_3);

    //Enable Timer0 interrupt
    InitTypeDef_NVIC.NVIC_IRQChannel = TIMER0_IRQn;
    InitTypeDef_NVIC.NVIC_IRQChannelPreemptionPriority = 1;
    InitTypeDef_NVIC.NVIC_IRQChannelSubPriority = 1;
    InitTypeDef_NVIC.NVIC_IRQChannelCmd = ENABLE;
    NVIC_Init(&InitTypeDef_NVIC);

    TIMER_EnableIRQ(TIMER0);//enable timer0 interrupt register
    TIMER_StartTimer(TIMER0);//startup timer0

    return 0;
}

中断服务函数实现:

//Timer0 interrupt handler
void TIMER0_Handler(void)
{
    static uint16_t cnt = 0;
    if(TIMER_GetIRQStatus(TIMER0) != RESET)
    {
        cnt++;
        printf("timer0 int...%d\r\n", cnt);        
        TIMER_ClearIRQ(TIMER0);
    }
}

需要把gw1ns4c_it.c文件中的定时器0中断服务函数注释掉,否则编译会报错

主函数调用:

int main(void)
{
	delay_init();
	uart0_init(115200);
    timer_init();
    
	printf("SystemCoreClock = %d\r\n", SystemCoreClock);
	printf("APB1 CLK = %d\r\n", PCLK1);
	printf("APB2 CLK = %d\r\n", PCLK2);
	printf("AHB CLK  = %d\r\n", HCLK);
	printf("Hello GW1NSR-4C SoC(ARM Cortex-M3)\r\n");
    printf("TIMER0 Interrupt Example\r\n");
    
	while(1)
	{

	}
}

查询每个外设挂载在哪个总线上,可以打开gw1ns4c.h文件查看:

或者在EMPU配置界面查看:

各总线的时钟频率,可以打开system_gw1ns4c.c文件查看:

//system_gw1ns4c.c
#define __SYSTEM_CLOCK    (60000000UL)	   /* 60MHz */

uint32_t SystemCoreClock = __SYSTEM_CLOCK;/*!< System Clock Frequency (Core Clock)*/
uint32_t PCLK1 = __SYSTEM_CLOCK;          /*!< APB1 Clock Frequency */
uint32_t PCLK2 = __SYSTEM_CLOCK;          /*!< APB2 Clock Frequency */
uint32_t HCLK = __SYSTEM_CLOCK;           /*!< AHB Clock Frequency */

这里和FPGA工程中配置的保持一致,这里我设置的是60MHz。

编译生成Bin文件,打开下载工具,指定FPGA的fs文件和MCU的bin文件进行下载。

打开串口调试助手,可以看到串口数据输出的时间间隔大概是500ms。

5. 工程下载

基于TangNano 4K的配套工程,包括Keil和GMD开发环境,都可以正常使用。

本文是高云FPGA系列教程第6篇文章

更多推荐

LeetCode 面试题 04.09. 二叉搜索树序列

文章目录一、题目二、C#题解一、题目从左向右遍历一个数组,通过不断将其中的元素插入树中可以逐步地生成一棵二叉搜索树。给定一个由不同节点组成的二叉搜索树root,输出所有可能生成此树的数组。点击此处跳转题目。示例1:输入:root=[2,1,3]输出:[[2,1,3],[2,3,1]]解释:数组[2,1,3]、[2,3,

macOS 12 Monterey:一次全新的跨设备协作体验

macOS12Monterey是苹果公司的一次重大突破,它打破了设备间的壁垒,将不同设备无缝地连接在一起,极大地提升了用户的工作效率和娱乐体验。Monterey带来了通用控制、AirPlay、捷径等新功能,以及一些实用的新小功能。安装:macOS12Montereyv12.6.9正式版功能特点通用控制macOS12Mo

会“穿墙术”的神奇材料 ——超固体

超固体(supersolid)是一种具备超流特性的固体,也就是集“超流体+固体”特性于一身的物质。简单来说就是超固体既有晶体态中原子规则排布的特征,又可以像超流体一样无摩擦流动。在凝聚态物理学中,超固体是具有超流体特性的空间有序材料。超固体是一种晶体材料,其原子排列结构规则且重复,也能够永远流动而不损失任何动能。尽管它

SpringMVC之自定义注解

目录一、Java注解1.1注解简介1.2注解分类1.3JDK基本注解1.4JDK元注解1.5自定义注解1.5.1标记注解1.5.2元数据注解1.6如何自定义注解二、自定义注解的基本案例2.1案例一(获取类、方法以及属性上的注解)2.1.1@Ingerited的使用2.2案例二(获取类属性上的注解属性值)2.3案例三(获

全球变暖问题(floodfill 处理联通块问题)

全球变暖问题文章目录全球变暖问题前言题目描述题目分析边界问题的考虑岛屿是否被淹没判断:如何寻找联通块:代码预告前言之前我们介绍了bfs算法在二维,三维地图中的应用,现在我们接续进行拓展,解锁floodfill算法,准确的来说是用bfs算法解决联通块问题。后续还会更新bfs算法有关内容,喜欢的小伙伴可以点个关注啦。题目描

数据结构和算法之快速排序

快速排序是一种基于分治法的排序算法。它通过不断地将数组分成较小的子数组,并按照递归的方式对每个子数组进行排序,最终将整个数组排序。#mermaid-svg-Za26UnuASULzGzsM{font-family:"trebuchetms",verdana,arial,sans-serif;font-size:16px

Vue路由与nodejs环境搭建

一.路由什么是路由什么是SPA路由的思路及实现实例建立一个HTML来编写路由测试结果​编辑二.nodejs环境什么是node.jsnpm是什么node.js的下载一.路由什么是路由路由(Routing)是指根据不同的URL地址,将用户导航到不同的页面或视图的过程。在前端开发中,特别是在单页面应用(SPA)中,路由起着至

Python实现MYSQL蜜罐

1LOADDATAINFILE介绍首先开启一个Mysql,看一下mysql是如何读取主机文件的。1.1linux搭建mysql1)docker运行mysql2)启动Mysqldockerrun-itd--namemysql-p3306:3306-eMYSQL_ROOT_PASSWORD=123456mysql3)进入容

Rust常见编程概念

变量和可变性rust使用let声明变量,变量默认是不可改变的。通过在let后面加上mut,可以声明可变变量。可以在变量名后加:和类型名,来显式声明变量类型,例如:leta:u32=1;常量常量使用const声明,变量名一般约定使用大写。隐藏不同的作用域如果有重叠,且重叠区域内有同名的变量,那么更小的作用域里变量会隐藏外

CentOS 7系统安装与配置、常用100条操作命令

CentOS7是一个广泛使用的开源Linux操作系统,它是RedHatEnterpriseLinux(RHEL)的一个免费重建版本,以稳定性和安全性而著称。在CentOS7上安装虚拟机通常使用虚拟化技术,如VirtualBox或VMware等。以下是CentOS7的简要介绍以及如何安装CentOS7虚拟机的步骤。Cen

git 的文件目录错误删除 --chatGPT

问:git的文件目录错误删除,需要还原到最后一次提交的位置,如何操作gpt:如果您在Git中删除了文件或目录,想要还原到最后一次提交的位置,可以使用以下步骤:1.**查看Git状态**:首先,可以使用以下命令来查看当前Git仓库的状态,以确保您删除了哪些文件或目录:```gitstatus```这将列出未提交的更改,包

热文推荐