您尚未登录。

楼主 # 2026-04-03 18:40:36

435788A
会员
注册时间: 2021-10-27
已发帖子: 38
积分: 48

F1C200S纯裸机的定时器中断问题求解

F1C200S纯裸机的定时器中断调不出来。
定时器0作延时delay_us()、delay_ms()正常,但定时器1、定时器2中断无反映。
上传失败了,只好粘贴:

#ifndef __F1C100S_TIMER_H__
#define __F1C100S_TIMER_H__

#include <stdint.h>

#ifdef __cplusplus
extern "C" {
#endif

//=============================================================================
// 定时器编号定义
//=============================================================================
#define TIMER0 0
#define TIMER1 1
#define TIMER2 2

//=============================================================================
// 延时函数接口(使用TIMER0)
//=============================================================================

/**

  • @brief 初始化延时定时器(TIMER0)

  • @note 需要在系统初始化时调用一次
    */
    void delay_init(void);

/**

  • @brief 微秒级延时

  • @param us 延时的微秒数(0~178956970)
    */
    void delay_us(uint32_t us);

/**

  • @brief 毫秒级延时

  • @param ms 延时的毫秒数
    */
    void delay_ms(uint32_t ms);

/**

  • @brief 高精度微秒级延时(循环延时)

  • @param us 延时的微秒数(建议小于100)
    */
    void delay_us_precise(uint32_t us);

/**

  • @brief 低功耗毫秒级延时(使用32KHz时钟)

  • @param ms 延时的毫秒数
    */
    void delay_ms_lowpower(uint32_t ms);

/**

  • @brief 获取定时器当前值

  • @return 当前递减计数值
    */
    uint32_t delay_get_current_value(void);

/**

  • @brief 检查定时器状态

  • @return 1-运行中,0-已停止
    */
    int delay_is_running(void);

/**

  • @brief 停止延时定时器
    */
    void delay_stop(void);

//=============================================================================
// 定时器1接口(中断模式,1秒中断)
//=============================================================================

/**

  • @brief 初始化定时器1,配置为1秒中断

  • @param callback 可选的中断回调函数(为NULL则使用内部计数器)

  • @note 中断号:F1C100S_IRQ_TIMER1 (14)
    */
    void timer1_init(void (*callback)(void));

/**

  • @brief 启动定时器1
    */
    void timer1_start(void);

/**

  • @brief 停止定时器1
    */
    void timer1_stop(void);

/**

  • @brief 获取定时器1中断计数(每秒加1)

  • @return 中断触发次数
    */
    uint32_t timer1_get_count(void);

/**

  • @brief 清除定时器1计数
    */
    void timer1_clear_count(void);

/**

  • @brief 检查定时器1是否正在运行

  • @return 1-运行中,0-已停止
    */
    int timer1_is_running(void);

//=============================================================================
// 定时器2接口(中断模式,1秒中断)
//=============================================================================

/**

  • @brief 初始化定时器2,配置为1秒中断

  • @param callback 可选的中断回调函数(为NULL则使用内部计数器)

  • @note 中断号:F1C100S_IRQ_TIMER2 (15)
    */
    void timer2_init(void (*callback)(void));

/**

  • @brief 启动定时器2
    */
    void timer2_start(void);

/**

  • @brief 停止定时器2
    */
    void timer2_stop(void);

/**

  • @brief 获取定时器2中断计数(每秒加1)

  • @return 中断触发次数
    */
    uint32_t timer2_get_count(void);

/**

  • @brief 清除定时器2计数
    */
    void timer2_clear_count(void);

/**

  • @brief 检查定时器2是否正在运行

  • @return 1-运行中,0-已停止
    */
    int timer2_is_running(void);

//=============================================================================
// AVS计数器接口
//=============================================================================

/**

  • @brief 初始化AVS计数器

  • @param counter_id 计数器ID (0 或 1)

  • @param divisor 分频系数(1~2047),计数时钟 = 24MHz / divisor

  • @param initial_value 初始计数值(33位,低1位必须为0)

  • @return 0-成功,-1-失败
    */
    int avs_counter_init(uint32_t counter_id, uint16_t divisor, uint64_t initial_value);

/**

  • @brief 启动AVS计数器

  • @param counter_id 计数器ID (0 或 1)
    */
    void avs_counter_start(uint32_t counter_id);

/**

  • @brief 暂停AVS计数器

  • @param counter_id 计数器ID (0 或 1)
    */
    void avs_counter_pause(uint32_t counter_id);

/**

  • @brief 停止AVS计数器

  • @param counter_id 计数器ID (0 或 1)
    */
    void avs_counter_stop(uint32_t counter_id);

/**

  • @brief 读取AVS计数器当前值

  • @param counter_id 计数器ID (0 或 1)

  • @return 33位计数值
    */
    uint64_t avs_counter_read(uint32_t counter_id);

/**

  • @brief 设置AVS计数器值

  • @param counter_id 计数器ID (0 或 1)

  • @param value 33位计数值(必须为偶数)

  • @return 0-成功,-1-失败
    */
    int avs_counter_set(uint32_t counter_id, uint64_t value);

/**

  • @brief 配置AVS计数器分频

  • @param counter_id 计数器ID (0 或 1)

  • @param divisor 分频系数(1~2047)
    */
    void avs_counter_set_divisor(uint32_t counter_id, uint16_t divisor);

/**

  • @brief 获取AVS计数器当前分频值

  • @param counter_id 计数器ID (0 或 1)

  • @return 分频系数
    */
    uint16_t avs_counter_get_divisor(uint32_t counter_id);

/**

  • @brief 复位AVS计数器

  • @param counter_id 计数器ID (0 或 1)
    */
    void avs_counter_reset(uint32_t counter_id);

/**

  • @brief 初始化两个AVS计数器为默认配置

  • @note 默认配置:1MHz计数频率(1us步进),从0开始计数
    */
    void avs_counters_init_default(void);

/**

  • @brief 获取AVS计数器计时的微秒数

  • @param counter_id 计数器ID (0 或 1)

  • @return 微秒数(基于当前分频设置)
    */
    uint64_t avs_counter_get_us(uint32_t counter_id);

/**

  • @brief 等待AVS计数器达到指定值

  • @param counter_id 计数器ID (0 或 1)

  • @param target 目标计数值

  • @param timeout_us 超时微秒数(0表示无限等待)

  • @return 0-达到目标,-1-超时
    */
    int avs_counter_wait(uint32_t counter_id, uint64_t target, uint32_t timeout_us);

#ifdef __cplusplus
}
#endif

#endif // __F1C100S_TIMER_H__

====================================================================================================================================================================================================================================================================================================================================================================================================================================

C文件:

// F1C100S/F1C200s裸机定时器驱动
#include <stdint.h>
#include "io.h"
#include "f1c100s_timer.h"
#include "f1c100s-irq.h"
#include "f1c100s_timer.h"
#include "ftypes.h"

//=============================================================================
// 寄存器定义
//=============================================================================

// F1C100S/F1C200s Timer寄存器基地址
#define TIMER0_REG_BASE (0x01C20C00UL)
#define TIMER1_REG_BASE (0x01C20C20UL)
#define TIMER2_REG_BASE (0x01C20C40UL)

// Timer寄存器偏移地址
#define TIMER_IRQ_EN_REG 0x00 // 定时器中断使能寄存器
#define TIMER_IRQ_STA_REG 0x04 // 定时器中断状态寄存器
#define TIMER_CTRL_REG 0x10 // 定时器控制寄存器
#define TIMER_INTV_VALUE_REG 0x14 // 定时器间隔值寄存器,32位
#define TIMER_CUR_VALUE_REG 0x18 // 定时器当前值寄存器
#define TIMER_AVS_CNT_CTRL 0x80 // AVS计数器控制寄存器
#define TIMER_AVS_CNT0 0x84 // AVS计数器0寄存器
#define TIMER_AVS_CNT1 0x88 // AVS计数器1寄存器
#define TIMER_AVS_CNT_DIV 0x8C // AVS计数器分频寄存器

// 定时器控制位定义
#define TIMER_EN (1 << 0) // 定时器使能
#define TIMER_RELOAD (1 << 1) // 重新加载计数值
#define TIMER_SRC_CLK_32K (0 << 2) // 时钟源选择:32.768KHz (LOSC)
#define TIMER_SRC_CLK_24M (1 << 2) // 时钟源选择:24MHz
#define TIMER_SRC_CLK_1K (2 << 2) // 时钟源选择:1KHz (保留)
#define TIMER_SRC_CLK_PCLK (3 << 2) // 时钟源选择:PCLK (保留)
#define TIMER_MODE_CONTINUE (0 << 7) // 连续模式
#define TIMER_MODE_SINGLE (1 << 7) // 单次模式
#define TIMER_PRESCALE_1 (0 << 4) // 预分频:1
#define TIMER_PRESCALE_2 (1 << 4) // 预分频:2
#define TIMER_PRESCALE_4 (2 << 4) // 预分频:4
#define TIMER_PRESCALE_8 (3 << 4) // 预分频:8
#define TIMER_PRESCALE_16 (4 << 4) // 预分频:16
#define TIMER_PRESCALE_32 (5 << 4) // 预分频:32
#define TIMER_PRESCALE_64 (6 << 4) // 预分频:64
#define TIMER_PRESCALE_128 (7 << 4) // 预分频:128

// AVS计数器控制位定义
#define AVS_CNT0_EN (1 << 0) // 计数器0使能
#define AVS_CNT1_EN (1 << 1) // 计数器1使能
#define AVS_CNT0_PAUSE (1 << 8) // 计数器0暂停
#define AVS_CNT1_PAUSE (1 << 9) // 计数器1暂停

// 系统时钟频率
#define SYSTEM_CLOCK_24M 24000000UL // 24MHz
#define SYSTEM_CLOCK_32K 32768UL // 32.768KHz

// 定时器最大值(32位)
#define TIMER_MAX_VALUE 0xFFFFFFFFUL

// AVS默认分频值(24MHz/24 = 1MHz,即1us计数一次)
#define AVS_DEFAULT_DIVISOR 24

// 1秒所需的计数值(24MHz时钟,预分频1)
#define TICK_PER_SECOND 24000000UL

//=============================================================================
// 调用外部
//=============================================================================
extern int32_t N1,H;

extern void f1c100s_intc_set_isr(uint8_t nIRQ, void (*handle)(void));
extern void f1c100s_intc_enable_irq(uint8_t nIRQ);

//=============================================================================
// 静态变量
//=============================================================================

// TIMER1 中断计数和回调
static volatile uint32_t timer1_counter = 0;
static void (*timer1_callback)(void) = NULL;

// TIMER2 中断计数和回调
static volatile uint32_t timer2_counter = 0;
static void (*timer2_callback)(void) = NULL;

//=============================================================================
// 内部函数声明
//=============================================================================

static void timer_set_interval(uint32_t base, uint32_t us, uint32_t clk_src, uint32_t prescale);
static void timer_enable_interrupt(uint32_t base, uint32_t timer_id);
static void timer_disable_interrupt(uint32_t base, uint32_t timer_id);
static void timer_clear_interrupt(uint32_t base, uint32_t timer_id);

//=============================================================================
// 定时器中断服务函数
//=============================================================================

/**

  • @brief 定时器1中断服务函数

  • @note 中断号:F1C100S_IRQ_TIMER1 (14)
    */
    static void timer1_irq_handler(void)
    {
    // 清除中断状态
    timer_clear_interrupt(TIMER1_REG_BASE, 1);

// 增加计数
timer1_counter++;
N1++;
// 调用回调函数(如果存在)
if (timer1_callback) {
timer1_callback();
}
}

/**

  • @brief 定时器2中断服务函数

  • @note 中断号:F1C100S_IRQ_TIMER2 (15)
    */
    static void timer2_irq_handler(void)
    {
    // 清除中断状态
    timer_clear_interrupt(TIMER2_REG_BASE, 2);

// 增加计数
timer2_counter++;
H++;
// 调用回调函数(如果存在)
if (timer2_callback) {
timer2_callback();
}
}

//=============================================================================
// 内部辅助函数
//=============================================================================

/**

  • @brief 设置定时器间隔(微秒)
    */
    static void timer_set_interval(uint32_t base, uint32_t us, uint32_t clk_src, uint32_t prescale)
    {
    uint32_t timeout;

// 计算需要的计数值
// 实际时钟频率 = 24MHz / (prescale + 1)
uint32_t freq = SYSTEM_CLOCK_24M / (1 << prescale);
timeout = (us * freq) / 1000000UL;

if (timeout > TIMER_MAX_VALUE) {
timeout = TIMER_MAX_VALUE;
}

// 设置间隔值
write32(base + TIMER_INTV_VALUE_REG, timeout);
}

/**

  • @brief 使能定时器中断
    */
    static void timer_enable_interrupt(uint32_t base, uint32_t timer_id)
    {
    uint32_t reg = read32(base + TIMER_IRQ_EN_REG);
    reg |= (1 << timer_id);
    write32(base + TIMER_IRQ_EN_REG, reg);
    }

/**

  • @brief 禁用定时器中断
    */
    static void timer_disable_interrupt(uint32_t base, uint32_t timer_id)
    {
    uint32_t reg = read32(base + TIMER_IRQ_EN_REG);
    reg &= ~(1 << timer_id);
    write32(base + TIMER_IRQ_EN_REG, reg);
    }

/**

  • @brief 清除定时器中断状态
    */
    static void timer_clear_interrupt(uint32_t base, uint32_t timer_id)
    {
    write32(base + TIMER_IRQ_STA_REG, (1 << timer_id));
    }

//=============================================================================
// 延时函数 (TIMER0)
//=============================================================================

/**

  • @brief 初始化延时函数使用的定时器
    */
    void delay_init(void)
    {
    // 1. 禁用定时器
    write32(TIMER0_REG_BASE + TIMER_CTRL_REG, 0);

// 2. 清除中断状态
write32(TIMER0_REG_BASE + TIMER_IRQ_STA_REG, 0x07);

// 3. 禁用中断
timer_disable_interrupt(TIMER0_REG_BASE, 0);

// 4. 配置定时器:24MHz时钟源,预分频1,连续模式
uint32_t ctrl_value = TIMER_SRC_CLK_24M | TIMER_MODE_CONTINUE | TIMER_PRESCALE_1;
write32(TIMER0_REG_BASE + TIMER_CTRL_REG, ctrl_value);
}

/**

  • @brief 微秒级延时
    */
    void delay_us(uint32_t us)
    {
    uint32_t timeout;
    uint32_t ctrl_val;

if (us == 0) return;

// 计算需要的计数值(24MHz时钟,1us = 24个时钟周期)
timeout = us * 24;

if (timeout > TIMER_MAX_VALUE) {
timeout = TIMER_MAX_VALUE;
}

// 设置定时器间隔值
write32(TIMER0_REG_BASE + TIMER_INTV_VALUE_REG, timeout);

// 读取当前控制值
ctrl_val = read32(TIMER0_REG_BASE + TIMER_CTRL_REG);

// 启动定时器
write32(TIMER0_REG_BASE + TIMER_CTRL_REG, ctrl_val | TIMER_RELOAD | TIMER_EN);

// 等待RELOAD位自动清零
while (read32(TIMER0_REG_BASE + TIMER_CTRL_REG) & TIMER_RELOAD);

// 等待定时器计数到0
while (read32(TIMER0_REG_BASE + TIMER_CUR_VALUE_REG) != 0);

// 停止定时器
write32(TIMER0_REG_BASE + TIMER_CTRL_REG, read32(TIMER0_REG_BASE + TIMER_CTRL_REG) & ~TIMER_EN);
}

/**

  • @brief 毫秒级延时
    */
    void delay_ms(uint32_t ms)
    {
    const uint32_t MAX_MS_PER_CALL = 1000;

while (ms > MAX_MS_PER_CALL) {
delay_us(MAX_MS_PER_CALL * 1000);
ms -= MAX_MS_PER_CALL;
}

if (ms > 0) {
delay_us(ms * 1000);
}
}

/**

  • @brief 高精度微秒级延时(使用循环)
    */
    void delay_us_precise(uint32_t us)
    {
    volatile uint32_t count = us * 12;
    while (count--) {
    __asm__ volatile ("nop");
    }
    }

/**

  • @brief 使用32KHz时钟源的延时(低功耗)
    */
    void delay_ms_lowpower(uint32_t ms)
    {
    uint32_t timeout;
    uint32_t ctrl_val;

if (ms == 0) return;

uint32_t ctrl_backup = read32(TIMER0_REG_BASE + TIMER_CTRL_REG);

uint32_t ctrl_value = (ctrl_backup & ~(0xFC)) | TIMER_SRC_CLK_32K | TIMER_PRESCALE_1;
write32(TIMER0_REG_BASE + TIMER_CTRL_REG, ctrl_value);

timeout = (ms * SYSTEM_CLOCK_32K) / 1000;
if (timeout > TIMER_MAX_VALUE) {
timeout = TIMER_MAX_VALUE;
}

write32(TIMER0_REG_BASE + TIMER_INTV_VALUE_REG, timeout);
ctrl_val = read32(TIMER0_REG_BASE + TIMER_CTRL_REG);
write32(TIMER0_REG_BASE + TIMER_CTRL_REG, ctrl_val | TIMER_RELOAD | TIMER_EN);

while (read32(TIMER0_REG_BASE + TIMER_CTRL_REG) & TIMER_RELOAD);
while (read32(TIMER0_REG_BASE + TIMER_CUR_VALUE_REG) != 0);

write32(TIMER0_REG_BASE + TIMER_CTRL_REG, read32(TIMER0_REG_BASE + TIMER_CTRL_REG) & ~TIMER_EN);
write32(TIMER0_REG_BASE + TIMER_CTRL_REG, ctrl_backup);
}

/**

  • @brief 获取定时器当前计数值
    */
    uint32_t delay_get_current_value(void)
    {
    return read32(TIMER0_REG_BASE + TIMER_CUR_VALUE_REG);
    }

/**

  • @brief 检查定时器是否正在运行
    */
    int delay_is_running(void)
    {
    return (read32(TIMER0_REG_BASE + TIMER_CTRL_REG) & TIMER_EN) ? 1 : 0;
    }

/**

  • @brief 停止延时定时器
    */
    void delay_stop(void)
    {
    write32(TIMER0_REG_BASE + TIMER_CTRL_REG, read32(TIMER0_REG_BASE + TIMER_CTRL_REG) & ~TIMER_EN);
    }

//=============================================================================
// 定时器1接口(中断模式,1秒中断)
//=============================================================================

/**

  • @brief 初始化定时器1,配置为1秒中断
    */
    void timer1_init(void (*callback)(void))
    {
    // 保存回调函数
    timer1_callback = callback;
    timer1_counter = 0;

// 禁用定时器
write32(TIMER1_REG_BASE + TIMER_CTRL_REG, 0);

// 清除中断状态
timer_clear_interrupt(TIMER1_REG_BASE, 1);

// 禁用中断
timer_disable_interrupt(TIMER1_REG_BASE, 1);

// 设置1秒间隔(24MHz时钟,预分频1)
// write32(TIMER1_REG_BASE + TIMER_INTV_VALUE_REG, TICK_PER_SECOND);
write32(TIMER1_REG_BASE + TIMER_INTV_VALUE_REG, 750000);//预分频32,24MHz/32=750000
// 配置定时器:24MHz时钟源,预分频1,连续模式
uint32_t ctrl_value = TIMER_SRC_CLK_24M | TIMER_MODE_CONTINUE | TIMER_PRESCALE_32;
write32(TIMER1_REG_BASE + TIMER_CTRL_REG, ctrl_value);

// 注册中断处理函数
f1c100s_intc_set_isr(F1C100S_IRQ_TIMER1, timer1_irq_handler);

// 使能中断控制器中的定时器1中断
f1c100s_intc_enable_irq(F1C100S_IRQ_TIMER1);

// 使能中断
timer_enable_interrupt(TIMER1_REG_BASE, 1);
}

/**

  • @brief 启动定时器1
    */
    void timer1_start(void)
    {
    uint32_t ctrl_val = read32(TIMER1_REG_BASE + TIMER_CTRL_REG);
    write32(TIMER1_REG_BASE + TIMER_CTRL_REG, ctrl_val | TIMER_RELOAD | TIMER_EN);
    }

/**

  • @brief 停止定时器1
    */
    void timer1_stop(void)
    {
    uint32_t ctrl_val = read32(TIMER1_REG_BASE + TIMER_CTRL_REG);
    write32(TIMER1_REG_BASE + TIMER_CTRL_REG, ctrl_val & ~TIMER_EN);
    }

/**

  • @brief 获取定时器1中断计数
    */
    uint32_t timer1_get_count(void)
    {
    return timer1_counter;
    }

/**

  • @brief 清除定时器1计数
    */
    void timer1_clear_count(void)
    {
    timer1_counter = 0;
    }

/**

  • @brief 检查定时器1是否正在运行
    */
    int timer1_is_running(void)
    {
    return (read32(TIMER1_REG_BASE + TIMER_CTRL_REG) & TIMER_EN) ? 1 : 0;
    }

//=============================================================================
// 定时器2接口(中断模式,1秒中断)
//=============================================================================

/**

  • @brief 初始化定时器2,配置为1秒中断
    */
    void timer2_init(void (*callback)(void))
    {
    // 保存回调函数
    timer2_callback = callback;
    timer2_counter = 0;

// 禁用定时器
write32(TIMER2_REG_BASE + TIMER_CTRL_REG, 0);

// 清除中断状态
timer_clear_interrupt(TIMER2_REG_BASE, 2);

// 禁用中断
timer_disable_interrupt(TIMER2_REG_BASE, 2);

// 设置1秒间隔(24MHz时钟,预分频1)
write32(TIMER2_REG_BASE + TIMER_INTV_VALUE_REG, TICK_PER_SECOND);

// 配置定时器:24MHz时钟源,预分频1,连续模式
uint32_t ctrl_value = TIMER_SRC_CLK_24M | TIMER_MODE_CONTINUE | TIMER_PRESCALE_1;
write32(TIMER2_REG_BASE + TIMER_CTRL_REG, ctrl_value);

// 使能中断
timer_enable_interrupt(TIMER2_REG_BASE, 2);

// 注册中断处理函数
f1c100s_intc_set_isr(F1C100S_IRQ_TIMER2, timer2_irq_handler);

// 使能中断控制器中的定时器2中断
f1c100s_intc_enable_irq(F1C100S_IRQ_TIMER2);
}

/**

  • @brief 启动定时器2
    */
    void timer2_start(void)
    {
    uint32_t ctrl_val = read32(TIMER2_REG_BASE + TIMER_CTRL_REG);
    write32(TIMER2_REG_BASE + TIMER_CTRL_REG, ctrl_val | TIMER_RELOAD | TIMER_EN);
    }

/**

  • @brief 停止定时器2
    */
    void timer2_stop(void)
    {
    uint32_t ctrl_val = read32(TIMER2_REG_BASE + TIMER_CTRL_REG);
    write32(TIMER2_REG_BASE + TIMER_CTRL_REG, ctrl_val & ~TIMER_EN);
    }

/**

  • @brief 获取定时器2中断计数
    */
    uint32_t timer2_get_count(void)
    {
    return timer2_counter;
    }

/**

  • @brief 清除定时器2计数
    */
    void timer2_clear_count(void)
    {
    timer2_counter = 0;
    }

/**

  • @brief 检查定时器2是否正在运行
    */
    int timer2_is_running(void)
    {
    return (read32(TIMER2_REG_BASE + TIMER_CTRL_REG) & TIMER_EN) ? 1 : 0;
    }

//=============================================================================
// AVS计数器函数
//=============================================================================

/**

  • @brief 初始化AVS计数器
    */
    int avs_counter_init(uint32_t counter_id, uint16_t divisor, uint64_t initial_value)
    {
    uint32_t reg_val;
    uint32_t ctrl_reg;

if (counter_id > 1) return -1;
if (divisor == 0 || divisor > 2047) return -1;

if (initial_value & 0x1) {
initial_value &= ~0x1ULL;
}

ctrl_reg = TIMER0_REG_BASE + TIMER_AVS_CNT_CTRL;

reg_val = read32(ctrl_reg);
if (counter_id == 0) {
reg_val |= AVS_CNT0_PAUSE;
} else {
reg_val |= AVS_CNT1_PAUSE;
}
write32(ctrl_reg, reg_val);

uint32_t div_reg = read32(TIMER0_REG_BASE + TIMER_AVS_CNT_DIV);

if (counter_id == 0) {
div_reg &= 0xFFFFF000;
div_reg |= (divisor - 1) & 0xFFF;
} else {
div_reg &= ~(0xFFF << 16);
div_reg |= ((divisor - 1) & 0xFFF) << 16;
}
write32(TIMER0_REG_BASE + TIMER_AVS_CNT_DIV, div_reg);

if (counter_id == 0) {
write32(TIMER0_REG_BASE + TIMER_AVS_CNT0, (uint32_t)(initial_value >> 1));
} else {
write32(TIMER0_REG_BASE + TIMER_AVS_CNT1, (uint32_t)(initial_value >> 1));
}

return 0;
}

/**

  • @brief 启动AVS计数器
    */
    void avs_counter_start(uint32_t counter_id)
    {
    uint32_t reg_val;
    uint32_t ctrl_reg = TIMER0_REG_BASE + TIMER_AVS_CNT_CTRL;

reg_val = read32(ctrl_reg);

if (counter_id == 0) {
reg_val &= ~AVS_CNT0_PAUSE;
reg_val |= AVS_CNT0_EN;
} else {
reg_val &= ~AVS_CNT1_PAUSE;
reg_val |= AVS_CNT1_EN;
}

write32(ctrl_reg, reg_val);
}

/**

  • @brief 暂停AVS计数器
    */
    void avs_counter_pause(uint32_t counter_id)
    {
    uint32_t reg_val;
    uint32_t ctrl_reg = TIMER0_REG_BASE + TIMER_AVS_CNT_CTRL;

reg_val = read32(ctrl_reg);

if (counter_id == 0) {
reg_val |= AVS_CNT0_PAUSE;
} else {
reg_val |= AVS_CNT1_PAUSE;
}

write32(ctrl_reg, reg_val);
}

/**

  • @brief 停止AVS计数器
    */
    void avs_counter_stop(uint32_t counter_id)
    {
    uint32_t reg_val;
    uint32_t ctrl_reg = TIMER0_REG_BASE + TIMER_AVS_CNT_CTRL;

reg_val = read32(ctrl_reg);

if (counter_id == 0) {
reg_val &= ~AVS_CNT0_EN;
reg_val |= AVS_CNT0_PAUSE;
} else {
reg_val &= ~AVS_CNT1_EN;
reg_val |= AVS_CNT1_PAUSE;
}

write32(ctrl_reg, reg_val);
}

/**

  • @brief 读取AVS计数器当前值
    */
    uint64_t avs_counter_read(uint32_t counter_id)
    {
    uint32_t high;

if (counter_id == 0) {
high = read32(TIMER0_REG_BASE + TIMER_AVS_CNT0);
} else {
high = read32(TIMER0_REG_BASE + TIMER_AVS_CNT1);
}

return ((uint64_t)high) << 1;
}

/**

  • @brief 设置AVS计数器值
    */
    int avs_counter_set(uint32_t counter_id, uint64_t value)
    {
    if (value & 0x1) {
    return -1;
    }

avs_counter_pause(counter_id);

if (counter_id == 0) {
write32(TIMER0_REG_BASE + TIMER_AVS_CNT0, (uint32_t)(value >> 1));
} else {
write32(TIMER0_REG_BASE + TIMER_AVS_CNT1, (uint32_t)(value >> 1));
}

return 0;
}

/**

  • @brief 配置AVS计数器分频
    */
    void avs_counter_set_divisor(uint32_t counter_id, uint16_t divisor)
    {
    uint32_t div_reg;

if (divisor == 0) divisor = 1;
if (divisor > 2047) divisor = 2047;

div_reg = read32(TIMER0_REG_BASE + TIMER_AVS_CNT_DIV);

if (counter_id == 0) {
div_reg &= 0xFFFFF000;
div_reg |= (divisor - 1) & 0xFFF;
} else {
div_reg &= ~(0xFFF << 16);
div_reg |= ((divisor - 1) & 0xFFF) << 16;
}

write32(TIMER0_REG_BASE + TIMER_AVS_CNT_DIV, div_reg);
}

/**

  • @brief 获取AVS计数器当前分频值
    */
    uint16_t avs_counter_get_divisor(uint32_t counter_id)
    {
    uint32_t div_reg = read32(TIMER0_REG_BASE + TIMER_AVS_CNT_DIV);

if (counter_id == 0) {
return (div_reg & 0xFFF) + 1;
} else {
return ((div_reg >> 16) & 0xFFF) + 1;
}
}

/**

  • @brief 复位AVS计数器
    */
    void avs_counter_reset(uint32_t counter_id)
    {
    avs_counter_stop(counter_id);

if (counter_id == 0) {
write32(TIMER0_REG_BASE + TIMER_AVS_CNT0, 0);
} else {
write32(TIMER0_REG_BASE + TIMER_AVS_CNT1, 0);
}
}

/**

  • @brief 初始化两个AVS计数器为默认配置
    */
    void avs_counters_init_default(void)
    {
    write32(TIMER0_REG_BASE + TIMER_AVS_CNT_CTRL, AVS_CNT0_PAUSE | AVS_CNT1_PAUSE);

uint32_t div_val = ((AVS_DEFAULT_DIVISOR - 1) & 0xFFF) |
(((AVS_DEFAULT_DIVISOR - 1) & 0xFFF) << 16);
write32(TIMER0_REG_BASE + TIMER_AVS_CNT_DIV, div_val);

write32(TIMER0_REG_BASE + TIMER_AVS_CNT0, 0);
write32(TIMER0_REG_BASE + TIMER_AVS_CNT1, 0);
}

/**

  • @brief 获取AVS计数器计时的微秒数
    */
    uint64_t avs_counter_get_us(uint32_t counter_id)
    {
    uint64_t ticks = avs_counter_read(counter_id);
    uint16_t divisor = avs_counter_get_divisor(counter_id);

return (ticks * divisor) / 24;
}

/**

  • @brief 等待AVS计数器达到指定值
    */
    int avs_counter_wait(uint32_t counter_id, uint64_t target, uint32_t timeout_us)
    {
    uint64_t start, current;
    uint32_t elapsed = 0;

start = avs_counter_read(counter_id);

while (1) {
current = avs_counter_read(counter_id);

if (current >= target) {
return 0;
}

if (timeout_us > 0) {
elapsed = (uint32_t)((current - start) * avs_counter_get_divisor(counter_id) / 24);
if (elapsed >= timeout_us) {
return -1;
}
}
}
}
/-----------------------------------------------------------/
/-----------------------------------------------------------/

/*
使用示例:
#include "f1c100s_timer.h"
#include "f1c100s-intc.h"

// 自定义回调函数示例
void my_timer1_callback(void)
{
// 每秒执行一次
// 注意:中断中不要执行耗时操作
}

void my_timer2_callback(void)
{
// 每秒执行一次
}

void main(void)
{
// 1. 初始化中断控制器
f1c100s_intc_init();

// 2. 初始化延时定时器(TIMER0)
delay_init();

// 3. 初始化定时器1(1秒中断)
timer1_init(my_timer1_callback);
timer1_start();

// 4. 初始化定时器2(1秒中断)
timer2_init(my_timer2_callback);
timer2_start();

// 5. 初始化AVS计数器
avs_counters_init_default();
avs_counter_start(0);

// 6. 主循环
while (1) {
// 获取定时器计数
uint32_t t1 = timer1_get_count();
uint32_t t2 = timer2_get_count();

// 使用延时函数
delay_ms(100);

// 获取AVS计时(微秒)
uint64_t us = avs_counter_get_us(0);
}
}

*/

最近编辑记录 435788A (2026-04-03 18:42:33)

离线

页脚

工信部备案:粤ICP备20025096号 Powered by FluxBB

感谢为中文互联网持续输出优质内容的各位老铁们。 QQ: 516333132, 微信(wechat): whycan_cn (哇酷网/挖坑网/填坑网) service@whycan.cn


东莞哇酷科技有限公司开发