复旦微PSOC PS端开发实战指南:TTC定时器中断控制LED灯

引言

在嵌入式系统开发中,定时器是不可或缺的外设之一。复旦微电子公司的FPGA芯片(如FMQL20S400)提供了丰富的外设资源,其中TTC(Triple Timer Counter)是PS(Processing System)端的重要定时器模块。本文将基于TTC定时器产生中断控制led灯,详细解析复旦微FPGA芯片PS端TTC的工作原理、配置方法和应用场景。

TTC概述

PSOC提供了不同类型的定时器用来满足不同的应用需求,包括通用定时器GTC、系统看门狗定时器WDT和三重定时器TTC。FMQL20S400上有两个TTC定时器,procise新建工程添加ps的IP核后TTC的频率默认未83.333Mhz。

TTC寄存器

基地址:

        0xE000_7000(TTC0)

        0xE002_4000(TTC1)

代码解析

以下是一个基于复旦微JFMQL100TAI芯片的TTC定时器控制PS端LED灯闪烁的例程,我们将逐部分解析其实现原理。

头文件包含和宏定义

#include <stdio.h>
#include "platform.h"
#include "fmsh_common.h"
#include "ps_init.h"
#include "fmsh_print.h"
#include "fmsh_gic.h"
#include "fmsh_gpio_public.h"
#include "fmsh_ps_parameters.h"
#include "fmsh_ttc_public.h"  

这部分代码包含了必要的头文件。这些头文件提供了访问复旦微FPGA芯片各种外设所需的API和数据结构。

全局变量声明

FGpioPs_T GpioOutput;
FGpioPs_Config *gpio_cfgPpr;

FTtcPs_T g_ttc_dev;
FTtcPs_Config* cfg;
volatile u8 g_ttc0_flag = 0;

u8 g_led_flag = 0;

这里声明了多个全局变量,包括看门狗、GPIO和TTC的设备实例和配置结构。g_ttc0_flag是一个易失性变量,用于在中断和主程序之间传递状态信息。

主函数

int main()
{
    init_platform();
    fmsh_print("Hello World\n\r");

    // GPIO初始化
    gpio_cfgPpr = FGpioPs_LookupConfig(FPAR_GPIOPS_0_DEVICE_ID);
    FGpioPs_init(&GpioOutput, gpio_cfgPpr);
    FGpioPs_setDirection(&GpioOutput, 0x0080); //MIO 7
    FGpioPs_writeData(&GpioOutput, 0x0); 
    
    // 中断控制器初始化
    FGicPs_CommonInit(&IntcInstance);
    
    // TTC定时器初始化
    init_timer();
    
    // 主循环
    while(1) {
      if(g_ttc0_flag == 1) {
        FTtcPs_setTimerEnble(&g_ttc_dev, timer1, FMSH_set);
      }
    }
    
    return 0;
}

主函数完成了平台初始化、外设初始化和主循环。特别注意,主循环中检查g_ttc0_flag标志,并在条件满足时重新启用定时器。

TTC初始化函数

int init_timer() 
{
    // 查找并初始化TTC配置
    cfg=FTtcPs_LookupConfig(FPAR_TTCPS_0_DEVICE_ID);
    FTtcPs_init(&g_ttc_dev, cfg);
    cfg=NULL;
    
    // 连接中断处理函数
    FGicPs_Connect(&IntcInstance, TIMER0_1_INT_ID, (FMSH_InterruptHandler)timer1_handler, &g_ttc_dev);
    FGicPs_Enable(&IntcInstance, TIMER0_1_INT_ID);   
    
    // 配置TTC定时器
    FTtcPs_setTimerEnble(&g_ttc_dev, timer1, FMSH_clear);
    FTtcPs_setTimerMode(&g_ttc_dev, timer1, user_DefinedCount_mode);
    FTtcPs_setTimerInterruptMask(&g_ttc_dev, timer1, FMSH_clear); 
    FTtcPs_setTIMERPWM(&g_ttc_dev, timer1, FMSH_clear); 
    
    // 设置定时器计数值(2秒)
    FTtcPs_TimerNLoadCount(&g_ttc_dev, timer1, 83333333*2);
    
    g_ttc0_flag = 0;
    
    // 启用定时器
    FTtcPs_setTimerEnble(&g_ttc_dev, timer1, FMSH_set);
    
    return 0;
}

这是TTC初始化的核心函数,完成了以下关键操作:

  1. 查找和初始化TTC配置:通过设备ID查找TTC配置并初始化设备实例。

  2. 连接中断:将TTC中断连接到中断控制器,并指定中断处理函数。

  3. 配置定时器模式:设置为用户定义计数模式,禁用PWM功能。

  4. 设置计数值:计算并设置2秒定时所需的计数值。

  5. 启用定时器:最后启用定时器开始计数。

中断处理函数

void timer1_handler(FTtcPs_T *DevPtr)
{
    // 控制LED状态
    led_run();
    
    // 清除定时器中断
    FTtcPs_ClearTimerNInterrupt(DevPtr, 1);
    
    // 禁用定时器
    FTtcPs_setTimerEnble(DevPtr, timer1, FMSH_clear);
    
    // 设置标志,通知主循环
    g_ttc0_flag = 1;
}

中断处理函数完成了以下任务:

  1. 调用led_run()函数切换LED状态

  2. 清除定时器中断标志

  3. 禁用定时器(防止重复进入中断)

  4. 设置标志位,通知主循环可以重新启用定时器

LED控制函数

void led_run()
{
    if(g_led_flag) {
        FGpioPs_writeData(&GpioOutput, 0x0);  //按位改变灯的状态
        g_led_flag = 0;
    } else {
        FGpioPs_writeData(&GpioOutput, 0x80);
        g_led_flag = 1;
    }
}

这个函数简单地切换LED的状态,通过写GPIO数据寄存器实现。

TTC工作原理解析

工作模式

TTC支持多种工作模式,本例中使用的是user_DefinedCount_mode(用户定义计数模式)。在这种模式下:

  1. 定时器从加载的计数值开始递减计数

  2. 当计数到0时,产生中断

  3. 定时器可以配置为自动重载或单次模式

中断处理流程

  1. 定时器计数到0,触发中断

  2. CPU跳转到中断处理函数

  3. 在处理函数中执行相关操作(如切换LED)

  4. 清除中断标志,防止重复进入中断

  5. 禁用定时器(本例中),等待主循环重新启用

应用场景

TTC定时器在嵌入式系统中有广泛的应用:

  1. 周期性任务调度:如操作系统的时钟节拍

  2. 外设时序控制:如通信接口的超时检测

  3. PWM生成:控制电机、LED亮度等

  4. 时间测量:测量事件持续时间

注意事项

在使用TTC时,需要注意以下几点:

  1. 中断优先级:合理设置中断优先级,避免高优先级中断阻塞TTC中断

  2. 计数值计算:准确计算计数值,考虑时钟分频和系统时钟频率

  3. 中断清除:必须在中断处理函数中清除中断标志,否则会重复进入中断

  4. 资源冲突:避免多个任务或中断同时访问同一个TTC实例

  5. 低功耗考虑:在低功耗应用中,合理配置TTC以平衡性能和功耗

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值