您尚未登录。

楼主 # 昨天 18:40:36

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

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 (昨天 18:42:33)

离线

页脚

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

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


太原小智科技有限责任公司 - 东莞哇酷科技有限公司联合开发