SmartFusion从FPGA到ARM(四)——MSS_TIMER定时器的使用

文章目录

        • 1.定时器资源简介
        • 2.MSS_TIMER库函数简介
        • 3.简单的周期性中断
        • 4.自定义产生波形
        • 5.64位定时器的使用
        • 6.单次中断模式

系列教程: SmartFusion从FPGA到ARM系列教程

1.定时器资源简介

SmartFusion片上MUC有两个32位的定时器,可以分别独立使用,也可以两个合并成一个64位定时器来使用。

驱动库只有一个mss_timer.h文件,库函数也比较简单。之前几篇文章,我们介绍了MSS_GPIO的使用和SysTick定时器的使用,使用SysTick内核定时器可以精确控制延时,使用外设定时器也能实现定时。

本篇文章介绍MSS_TIMER定时器的使用和配置,演示定时器周期溢出中断,单次溢出中断,自定义波形功能。

固件库下载地址:Firmware_MSS_Timer_Driver_v2.3.102

官方使用文档路径:X:\Microsemi\common\vault\Components\Actel\Firmware\MSS_Timer_Driver\2.3.102\fs\p2f0\docs

示例代码可以参考:
SmartFusion从FPGA到ARM(四)——MSS_TIMER定时器的使用_第1张图片

2.MSS_TIMER库函数简介

MSS_TIMER库函数整体可分为三种:初始化,定时器配置和中断控制

其中TIMx可为TIM1、TIM2或TIM64,其中TIM64是把TIM1和TIM2合成一个64位的定时来使用。

初始化函数,初始化完成之后,定时器将会停止,禁止中断,并设置工作模式。

/* 配置定时器的工作方式,单次中断还是周期性中断 */
void MSS_TIMx_init( mss_timer_mode_t mode )

mode支持的取值:

/* 周期性溢出中断模式 */
MSS_TIMER_PERIODIC_MODE
/* 单次溢出中断模式 */
MSS_TIMER_ONE_SHOT_MODE 

配置函数:

/* 设置溢出值,立即生效 */
void MSS_TIMx_load_immediate(uint32_t load_value);
/* 指定下次计时的溢出值 */
void MSS_TIMx_load_background(uint32_t load_value);
/* 获取当前计数值 */
uint32_t MSS_TIMx_get_current_value();
/* 获取64位定时器的当前值,高32位和低32位 */
void MSS_TIM64_get_current_value(uint32_t * load_value_u, uint32_t * load_value_l)
/* 启动定时器 */
void MSS_TIMx_start(void);
/* 停止计数器 */ 
void MSS_TIMx_stop(void);

中断控制函数

/* 使能中断 */
void MSS_TIMx_enable_irq(void);
/* 禁止中断 */
void MSS_TIMx_disable_irq(void);
/* 清除中断 */
void MSS_TIMx_clear_irq(void);

了解了定时器操作的相关函数,下面来演示几个定时器的使用方法。

3.简单的周期性中断

GPIO每隔250ms翻转一次。

/* TIM1配置成周期中断,中断时间250ms */
MSS_TIM1_init(MSS_TIMER_PERIODIC_MODE);
MSS_TIM1_load_immediate(SystemCoreClock/4);
MSS_TIM1_start();
MSS_TIM1_enable_irq();

/* 定时器中断服务函数 */
void Timer1_IRQHandler(void)
{
    static uint8_t status = 0;
    status = !status;
    
    MSS_IO_OUT(1) = status;
    
    MSS_TIM1_clear_irq();
}

4.自定义产生波形

产生20ms、40ms、60ms、80ms、100ms高低电平相间的波形。

#define SEQUENCE_LENGTH 5

static const uint32_t g_delays_list[SEQUENCE_LENGTH] =
{
    20, 40, 60, 80, 100
};

int main()
{
	。。。。。。。。。。。。。。
    /* TIM1配置成周期中断,中断时间250ms */
    MSS_TIM1_init(MSS_TIMER_PERIODIC_MODE);
    MSS_TIM1_load_immediate(g_delays_list[0]);
    MSS_TIM1_start();
    MSS_TIM1_enable_irq();
    
    while(1)
    {
		。。。。。。
    }
}

void Timer1_IRQHandler(void)
{
    static uint8_t idx = 0;
    static uint8_t status = 0;
    
    status = !status;
    MSS_IO_OUT(1) = status;

    /* 指定下次计时溢出值 */
    MSS_TIM1_load_background( g_delays_list[idx] * (SystemCoreClock/1000));
    
    if(idx < SEQUENCE_LENGTH)
        idx++;
    else 
        idx = 0;

    MSS_TIM1_clear_irq();
}

最终生成的波形:

SmartFusion从FPGA到ARM(四)——MSS_TIMER定时器的使用_第2张图片

5.64位定时器的使用

两个32位的定时器可以组成1个64位的定时器,64位定时器和TIM1共用一个中断服务函数。按键按下时,LED停止闪烁,松开继续闪烁。

#include "main.h"

int main()
{
    uint8_t key;
    
    delay_init();       /* 更新系统时钟 */
    MSS_WD_disable();
    
    MSS_GPIO_init();
    
    /* GPIO_0 & GPIO_1 配置成输出模式 */
    MSS_GPIO_config(MSS_GPIO_0, MSS_GPIO_OUTPUT_MODE);
    MSS_GPIO_config(MSS_GPIO_1, MSS_GPIO_OUTPUT_MODE);
    
    /* GPIO_2配置成输入模式 */
    MSS_GPIO_config(MSS_GPIO_2, MSS_GPIO_INPUT_MODE);
    
    /* TIM64配置成周期中断,中断时间250ms */
    MSS_TIM64_init(MSS_TIMER_PERIODIC_MODE);
    MSS_TIM64_load_immediate(0, SystemCoreClock/4);
    MSS_TIM64_start();
    MSS_TIM64_enable_irq();
    
    while(1)
    {
        key = MSS_IO_IN(2);
        
        if(key == 1)    /* 按键按下暂停 */
        {
            MSS_TIM64_stop();
            while(MSS_IO_IN(2) == 1);     /* 等待释放 */
            MSS_TIM64_start();  /* 释放继续计时 */
        }
    }
}

/* TIM64与TIM1共用一个中断服务函数 */
void Timer1_IRQHandler(void)
{
    static uint8_t status = 0;
    
    status = !status;
    MSS_IO_OUT(1) = status;

    MSS_TIM64_clear_irq();
}

6.单次中断模式

使用ONE_SHOT模式,可以配置只产生一次溢出中断。按键每按下启动一次定时器,产生一次中断,4s之后LED状态翻转,即按键控制LED时,延时4s。

#include "main.h"

int main()
{
    uint8_t key;
    
    delay_init();       /* 更新系统时钟 */
    MSS_WD_disable();
    
    MSS_GPIO_init();
    /* GPIO_0 & GPIO_1 配置成输出模式 */
    MSS_GPIO_config(MSS_GPIO_0, MSS_GPIO_OUTPUT_MODE);
    MSS_GPIO_config(MSS_GPIO_1, MSS_GPIO_OUTPUT_MODE);
    
    /* GPIO_2配置成输入模式 */
    MSS_GPIO_config(MSS_GPIO_2, MSS_GPIO_INPUT_MODE);
    
    /* TIM1配置成单次中断模式 */
    MSS_TIM1_init(MSS_TIMER_ONE_SHOT_MODE);

    while(1)
    {
        key = MSS_IO_IN(2);
        
        if(key == 1)    /* 按键按下中断一次 */
        {
            MSS_TIM1_load_immediate(SystemCoreClock*4);
            MSS_TIM1_enable_irq();
            MSS_TIM1_start();
            while(MSS_IO_IN(2) == 1);   /* 等待释放 */
        }
    }
}

/* TIM1中断服务函数 */
void Timer1_IRQHandler(void)
{
    static uint8_t status = 0;
    
    status = !status;
    MSS_IO_OUT(1) = status;

    MSS_TIM1_clear_irq();
}

你可能感兴趣的:(Microsemi,Microsemi,Libero,FPGA,SmartFusion,ARM)