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)
离线