【求助】003J4M6,定时器的使用

设想:采用定时器,中断触发后通过串口发送一串hex出去。


代码如下:

timer.h

#ifndef TIMER_H
#define TIMER_H

#include "debug.h"

// Timer configuration structure
typedef struct {
    uint16_t period;      // Auto-reload value
    uint16_t prescaler;   // Clock prescaler
    uint8_t priority;     // Interrupt priority
    uint8_t sub_priority; // Interrupt sub-priority
} Timer_Config_t;

// Initialize Timer2 with configuration
void Timer2_Init(Timer_Config_t *config);

// Register callback for Timer2 interrupt
void Timer2_RegisterCallback(void (*callback)(void));

// Start/Stop Timer2
void Timer2_Start(void);
void Timer2_Stop(void);

#endif

timer.c

// timer.c
#include "timer.h"

static void (*timer2_callback)(void) = NULL;

void TIM2_IRQHandler(void) __attribute__((interrupt("WCH-Interrupt-fast")));

void Timer2_Init(Timer_Config_t *config)
{
    TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure = {0};
    NVIC_InitTypeDef NVIC_InitStructure = {0};

    // Enable Timer2 clock
    RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);

    // Configure Timer
    TIM_TimeBaseStructure.TIM_Period = config->period - 1;
    TIM_TimeBaseStructure.TIM_Prescaler = config->prescaler - 1;
    TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1;
    TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
    TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure);

    // Enable Timer2 interrupt
    TIM_ITConfig(TIM2, TIM_IT_Update, ENABLE);

    // Configure NVIC
    NVIC_InitStructure.NVIC_IRQChannel = TIM2_IRQn;
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = config->priority;
    NVIC_InitStructure.NVIC_IRQChannelSubPriority = config->sub_priority;
    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
    NVIC_Init(&NVIC_InitStructure);
}

void Timer2_RegisterCallback(void (*callback)(void))
{
    timer2_callback = callback;
}

void Timer2_Start(void)
{
    TIM_Cmd(TIM2, ENABLE);
}

void Timer2_Stop(void)
{
    TIM_Cmd(TIM2, DISABLE);
}

void TIM2_IRQHandler(void)
{
    if (TIM_GetITStatus(TIM2, TIM_IT_Update) != RESET)
    {
        TIM_ClearITPendingBit(TIM2, TIM_IT_Update);

        // Execute callback if registered
        if (timer2_callback != NULL)
        {
            timer2_callback();
        }
    }
}

main.c片段

//发送hex
void KeepAlive(void)
{
	// 构建返回数据结构
	uint8_t response[10];
	uint8_t address=0;
	response[0] = FRAME_HEAD;
	if (rx_buffer[1]==0x00) {
		address = 0x11;
	} else {
		address = rx_buffer[1];
	}
	response[1] = ((address & 0x70) >> 4) | ((address & 0x07) << 4);
	response[2] = g_tm1650_data[0];
	response[3] = g_tm1650_data[1];
	response[4] = 0x13;				//当前为固定值 g_tm1650_data[2];
	response[5] = 0x14;				//当前为固定值 g_tm1650_data[3];
	response[6] = g_tm1804_data;
	response[7] = 0x17;				//当前为固定值

	// 计算校验码
	uint8_t resp_checksum = 0;
	for (int i = 1; i <= 7; i++)
	{
		resp_checksum ^= response[i];
	}
	response[8] = resp_checksum;
	response[9] = FRAME_TAIL;

	// 发送返回数据
	for (int i = 0; i < 10; i++)
	{
		while(USART_GetFlagStatus(USART1, USART_FLAG_TC) == RESET);
		USART_SendData(USART1, response[i]);
	}
}

int main(void)
{
	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);
	SystemCoreClockUpdate();

	Delay_Init();

	// 配置1秒定时器
    Timer_Config_t timer_config = {
        .period = 1000,          // 1ms周期
        .prescaler = 48,         // 48分频
        .priority = 1,           // 优先级1
        .sub_priority = 0        // 子优先级0
    };
    // 初始化定时器
    Timer2_Init(&timer_config);
    // 注册回调函数
    Timer2_RegisterCallback(KeepAlive);

    // 启动定时器
    Timer2_Start();
	while(1)
	{
	}
}


当前碰到的问题是:无论如何修改.period = 1000值,感觉触发中断的时间都没有变化。

您好,若方便可将工程发我邮箱(lzs@wch.cn)具体看一下


邮件已发送,谢谢~


您好,已邮件回复,经测试,如下图,在中断函数中加了一个GPIO翻转,注释掉其他代码,改变重装载值,翻转频率会发生变化,因此定时器中断是没有问题的,可以检查一下其他函数是否有问题,下次遇到该类问提可按照该方法先测试一下。后续若有问题可继续邮箱沟通。你可以检查一下中断函数中那个if判断以及回调函数是否有问题。

image.png

image.png




只有登录才能回复,可以选择微信账号登录