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

### 文章目录

  • [@[toc]](#文章目录 @[toc] 1. ARM定时器简介 2. FPGA配置 3. 常用函数 4. MCU程序设计 5. 工程下载)
  • [1. ARM定时器简介](#文章目录 @[toc] 1. ARM定时器简介 2. FPGA配置 3. 常用函数 4. MCU程序设计 5. 工程下载)
  • [2. FPGA配置](#文章目录 @[toc] 1. ARM定时器简介 2. FPGA配置 3. 常用函数 4. MCU程序设计 5. 工程下载)
  • [3. 常用函数](#文章目录 @[toc] 1. ARM定时器简介 2. FPGA配置 3. 常用函数 4. MCU程序设计 5. 工程下载)
  • [4. MCU程序设计](#文章目录 @[toc] 1. ARM定时器简介 2. FPGA配置 3. 常用函数 4. MCU程序设计 5. 工程下载)
  • [5. 工程下载](#文章目录 @[toc] 1. ARM定时器简介 2. FPGA配置 3. 常用函数 4. MCU程序设计 5. 工程下载)

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

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

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

1. ARM定时器简介

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

2. FPGA配置

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

3. 常用函数

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

c 复制代码
//定时器外设初始化,指定溢出值
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定时器一般配置步骤如下:

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

4. MCU程序设计

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

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

c 复制代码
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;
}

中断服务函数实现:

c 复制代码
//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中断服务函数注释掉,否则编译会报错

主函数调用:

c 复制代码
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文件查看:

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篇文章

相关推荐
张一西5 天前
ARM学习(42)CortexM3/M4 MPU配置
stm32·arm·mpu·nxp·arm架构·cortexm3·cortexm4
迎风打盹儿8 天前
VIVADO FIFO (同步和异步) IP 核详细使用配置步骤
ip·verilog·fpga·vivado·fifo
Ruoyo1769 天前
关于编写测试用例的细枝末节
测试用例·fpga
北城笑笑9 天前
FPGA 21 ,深入理解 Verilog 中的基数,以及二进制数与十进制数之间的关系( Verilog中的基数 )
fpga开发·fpga
CV金科9 天前
freertos的基础(二)内存管理:堆和栈
stm32·开源·arm·freertos·risc-v
代码改变世界ctw10 天前
Armv8/Armv9架构从入门到精通-介绍
arm·trustzone·atf·tee·armv8·armv9·周贺贺
Hi2024021713 天前
RK3588上CPU和GPU算力以及opencv resize的性能对比测试
linux·opencv·arm·gpu·opencl·算力测试·mali-gpu
贝塔实验室14 天前
宇航用VIRTEX5系列FPGA的动态刷新方法及实现
考研·fpga开发·硬件架构·硬件工程·学习方法·业界资讯·fpga
贝塔实验室14 天前
FPGA的 基本结构(Xilinx 公司Virtex-II 系列FPGA )
fpga开发·重构·硬件架构·硬件工程·创业创新·fpga·程序员创富
阿隆ALong16 天前
亚矩阵云手机:跨境出海直播的全方位利器
大数据·服务器·网络安全·矩阵·云计算·arm·信息与通信