Files
Motor_v2/Robot_V2/device/Timer.cpp
T
2025-10-02 02:52:07 +08:00

239 lines
7.1 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#include "Timer.h"
#include "adc.h"
#include "gd32c10x.h"
#include "gd32c10x_gpio.h"
#include "gd32c10x_timer.h"
#include "initial.h"
#include <stdbool.h>
#include <stdint.h>
#include <stdio.h>
constexpr int TIMER1_PRESCALER = 1199;
constexpr int TIMER1_PERIOD = 9;
constexpr int TIMER0_PRESCALER = 5999;
constexpr int TIMER0_PERIOD = 15999;
constexpr int TIMER0_CH0_PULSE = 4000;
constexpr int TIMER0_CH1_PULSE = 6000;
constexpr int TIMER0_CH2_PULSE = 8000;
extern u16 adc_value[7];
/**
* @brief 设置引脚中断优先级
* @return void
*
*设置引脚中断优先级
*/
void nvic_config(void) {
/* 设置NVIC优先级分组,1位抢占优先级,3位响应优先级 */
nvic_priority_group_set(NVIC_PRIGROUP_PRE2_SUB2);
/* 使能TIMER1中断,设置抢占优先级为1,子优先级为1 */
nvic_irq_enable(TIMER1_IRQn, 1, 1);
}
/**
* @brief 配置定时器1
* @return void
*
*配置定时器1
*/
void timer1_config(void) {
/* ----------------------------------------------------------------------------
TIMER1 Configuration:
TIMER1CLK = SystemCoreClock/12000 = 10KHz, the period is 1s(10000/10000 =
1s).
----------------------------------------------------------------------------
*/
timer_parameter_struct timer_struct;
/* 使能TIMER1时钟 */
rcu_periph_clock_enable(RCU_TIMER1);
/* 复位TIMER1外设到默认状态 */
timer_deinit(TIMER1);
/* 初始化TIMER初始化参数结构体 */
timer_struct_para_init(&timer_struct);
/* TIMER1配置参数设置 */
timer_struct.prescaler =
TIMER1_PRESCALER; /* 预分频值:12000分频(从0开始计数) */
timer_struct.alignedmode = TIMER_COUNTER_EDGE; /* 边沿对齐模式 */
timer_struct.counterdirection = TIMER_COUNTER_UP; /* 向上计数模式 */
timer_struct.period =
TIMER1_PERIOD; /* 自动重装载值:10000次计数(从0开始计数) */
timer_struct.clockdivision = TIMER_CKDIV_DIV1; /* 时钟分频值:1分频 */
timer_init(TIMER1, &timer_struct);
/* 清除更新中断标志位 */
timer_interrupt_flag_clear(TIMER1, TIMER_INT_FLAG_UP);
/* 使能更新中断 */
timer_interrupt_enable(TIMER1, TIMER_INT_UP);
/* 使能TIMER1 */
timer_enable(TIMER1);
}
/**
* @brief 配置TIMER1中断
* @return void
*/
void User_timer_init(void) {
/* 配置TIMER1 */
timer1_config();
/* 配置TIMER1中断 */
nvic_config();
}
/**
* @brief TIMER1中断处理函数
* @return void
*/
void TIMER1_IRQHandler(void) {
// 检查更新中断标志并处理
if (timer_interrupt_flag_get(TIMER1, TIMER_INT_UP) != RESET) {
// 清除更新中断标志
timer_interrupt_flag_clear(TIMER1, TIMER_INT_UP);
// 使用静态变量来跟踪定时器事件
static u8 ms_counter = 0;
static u8 tens_counter = 0;
static u8 hundreds_counter = 0;
static u16 seconds_counter = 0;
// 增加计数器
ms_counter++;
if (ms_counter >= 10) {
ms_counter = 0;
tens_counter++;
// 每1ms执行的代码可以放在这里
if (tens_counter >= 10) {
tens_counter = 0;
hundreds_counter++;
// 每10ms执行的代码可以放在这里
if (hundreds_counter >= 10) {
hundreds_counter = 0;
seconds_counter++;
// 每100ms执行的代码可以放在这里
if (seconds_counter >= 10) {
seconds_counter = 0;
// 每1s执行的代码可以放在这里
}
}
}
}
}
}
/**
* @brief TIMER0 GPIO配置函数
*/
void timer0_gpio_config(void) {
// 时钟使能
rcu_periph_clock_enable(RCU_GPIOA);
rcu_periph_clock_enable(RCU_AF);
// TIMER0 GPIO初始化
gpio_init(GPIOA, GPIO_MODE_AF_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_0);
gpio_init(GPIOA, GPIO_MODE_AF_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_1);
gpio_init(GPIOA, GPIO_MODE_AF_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_2);
/* 配置TIMER0完全重映射 */
gpio_pin_remap_config(GPIO_TIMER0_FULL_REMAP, ENABLE);
}
/**
* @brief TIMER0 配置函数
*/
void timer0_config(void) {
/* -----------------------------------------------------------------------
TIMER0配置:
生成3路具有不同占空比的互补PWM信号:
TIMER0CLK固定为systemcoreclock,TIMER0预分频器设置为6000,因此
TIMER0计数器时钟为20KHz。
三个占空比的计算如下:
通道0的占空比设置为25%,因此通道1N设置为75%。
通道1的占空比设置为50%,因此通道2N设置为50%。
通道2的占空比设置为75%,因此通道3N设置为25%。
----------------------------------------------------------------------- */
timer_oc_parameter_struct timer_ocinitpara;
timer_parameter_struct timer_initpara;
rcu_periph_clock_enable(RCU_TIMER0);
timer_deinit(TIMER0);
/* initialize TIMER init parameter struct */
timer_struct_para_init(&timer_initpara);
/* TIMER0 configuration */
timer_initpara.prescaler = TIMER0_PRESCALER;
timer_initpara.alignedmode = TIMER_COUNTER_EDGE;
timer_initpara.counterdirection = TIMER_COUNTER_UP;
timer_initpara.period = TIMER0_PERIOD;
timer_initpara.clockdivision = TIMER_CKDIV_DIV1;
timer_initpara.repetitioncounter = 0;
timer_init(TIMER0, &timer_initpara);
/* initialize TIMER channel output parameter struct */
timer_channel_output_struct_para_init(&timer_ocinitpara);
/* CH0, CH1 and CH2 configuration in PWM mode */
timer_ocinitpara.outputstate = TIMER_CCX_ENABLE;
timer_ocinitpara.outputnstate = TIMER_CCXN_DISABLE;
timer_ocinitpara.ocpolarity = TIMER_OC_POLARITY_HIGH;
timer_ocinitpara.ocnpolarity = TIMER_OCN_POLARITY_HIGH;
timer_ocinitpara.ocidlestate = TIMER_OC_IDLE_STATE_LOW;
timer_ocinitpara.ocnidlestate = TIMER_OCN_IDLE_STATE_LOW;
timer_channel_output_config(TIMER0, TIMER_CH_0, &timer_ocinitpara);
timer_channel_output_config(TIMER0, TIMER_CH_1, &timer_ocinitpara);
timer_channel_output_config(TIMER0, TIMER_CH_2, &timer_ocinitpara);
timer_channel_output_pulse_value_config(TIMER0, TIMER_CH_0,
TIMER0_CH0_PULSE);
timer_channel_output_mode_config(TIMER0, TIMER_CH_0, TIMER_OC_MODE_PWM0);
timer_channel_output_shadow_config(TIMER0, TIMER_CH_0,
TIMER_OC_SHADOW_DISABLE);
timer_channel_output_pulse_value_config(TIMER0, TIMER_CH_1,
TIMER0_CH1_PULSE);
timer_channel_output_mode_config(TIMER0, TIMER_CH_1, TIMER_OC_MODE_PWM0);
timer_channel_output_shadow_config(TIMER0, TIMER_CH_1,
TIMER_OC_SHADOW_DISABLE);
timer_channel_output_pulse_value_config(TIMER0, TIMER_CH_2,
TIMER0_CH2_PULSE);
timer_channel_output_mode_config(TIMER0, TIMER_CH_2, TIMER_OC_MODE_PWM0);
timer_channel_output_shadow_config(TIMER0, TIMER_CH_2,
TIMER_OC_SHADOW_DISABLE);
timer_primary_output_config(TIMER0, ENABLE);
// 自动重载模式使能和启动TIMER0
timer_auto_reload_shadow_enable(TIMER0);
timer_enable(TIMER0);
}
/**
* @brief TIMER0 GPIO config
*/
void Timer0_init(void) {
timer0_gpio_config();
timer0_config();
}
/*!
\brief set PWM
\param[in] channel: TIMER_CH_0/TIMER_CH_1/TIMER_CH_2/TIMER_CH_3 (valid
values: 0, 1, 2, 3)
\param[in] pulse: PWM pulse value
\param[out] none
\retval none
\note The channel parameter must be between 0 and 3 inclusive.
*/
void Set_Pwm(u16 channel, u32 palse) {
if (channel <= 3) {
timer_channel_output_pulse_value_config(TIMER0, channel, palse);
} else {
} // Ensure channel is within valid range
}