好的,针对立创·梁山派开发板(基于GD32F450ZGT6)的嵌入式系统开发,我将详细阐述一个可靠、高效、可扩展的系统平台架构,并提供相应的C代码实现。这个过程将涵盖从需求分析到系统维护升级的整个流程。
关注微信公众号,提前获取相关推文
1. 需求分析
首先,我们假设一个较为通用的嵌入式系统需求,包括:
- 基础功能:
- LED 控制 (至少 3 个 LED,可独立控制亮度)
- 按键输入 (至少 2 个按键)
- 串口通信 (用于调试和数据传输)
- 定时器 (用于周期性任务和延时)
- 进阶功能:
- ADC 采集 (用于模拟信号读取)
- DAC 输出 (用于模拟信号输出)
- SPI 通信 (用于扩展外设)
- I2C 通信 (用于传感器)
- RTC (实时时钟)
- USB 通信 (虚拟串口或 HID)
- 系统特性:
- 可靠性:防止死机,具备错误处理机制
- 高效性:资源占用小,响应速度快
- 可扩展性:易于添加新功能和外设
- 可维护性:代码结构清晰,易于调试和升级
- 可移植性:尽量采用标准C,易于移植到其他平台
2. 代码架构设计
为了满足上述需求,我们采用分层模块化的架构,这种架构具有良好的可读性、可维护性和可扩展性。
- 硬件抽象层 (HAL):
- 封装 GD32F450ZGT6 的硬件操作,包括 GPIO、定时器、ADC、DAC、SPI、I2C、USART、RTC 和 USB 等。
- 提供统一的 API 接口,方便上层模块调用。
- 降低上层模块对硬件细节的依赖,提高代码可移植性。
- 驱动层 (Drivers):
- 在 HAL 层基础上,封装具体外设的驱动,如 LED 驱动、按键驱动、传感器驱动等。
- 提供更高级别的接口,如控制 LED 亮灭、读取按键状态、读取传感器数据等。
- 中间件层 (Middleware):
- 实现一些通用的功能,如任务调度器、软件定时器、数据缓冲队列、日志记录、错误处理等。
- 为应用层提供基础服务,简化应用层的开发。
- 应用层 (Applications):
- 实现具体的应用逻辑,如 LED 闪烁、按键控制、数据采集、数据处理等。
- 调用中间件层和驱动层提供的 API。
3. 具体代码实现 (C)
以下为代码实现示例,由于篇幅限制,会省略部分细节,但会给出核心框架和关键代码:
// *********************************
// 文件:main.c
// 描述:主应用程序入口
// *********************************
#include "gd32f4xx.h"
#include "hal.h"
#include "drivers.h"
#include "middleware.h"
#include "application.h"
int main(void) {
// 初始化 HAL 层
hal_init();
// 初始化驱动层
drivers_init();
// 初始化中间件层
middleware_init();
// 初始化应用层
application_init();
// 进入主循环
while (1) {
// 执行应用逻辑
application_run();
}
}
// *********************************
// 文件:hal.h
// 描述:硬件抽象层头文件
// *********************************
#ifndef HAL_H
#define HAL_H
#include "gd32f4xx.h"
// GPIO 定义
#define LED_RED_PIN GPIO_PIN_6
#define LED_GREEN_PIN GPIO_PIN_7
#define LED_BLUE_PIN GPIO_PIN_8
#define LED_PORT GPIOC
#define BUTTON_1_PIN GPIO_PIN_0
#define BUTTON_2_PIN GPIO_PIN_1
#define BUTTON_PORT GPIOA
// 函数声明
void hal_init(void);
void hal_gpio_set_output(uint32_t pin, uint32_t port);
void hal_gpio_set_input(uint32_t pin, uint32_t port);
void hal_gpio_write_pin(uint32_t pin, uint32_t port, uint8_t value);
uint8_t hal_gpio_read_pin(uint32_t pin, uint32_t port);
void hal_timer_init(uint32_t freq_hz);
void hal_timer_start(void);
void hal_timer_stop(void);
void hal_timer_delay_ms(uint32_t ms);
void hal_usart_init(uint32_t baudrate);
void hal_usart_send_byte(uint8_t byte);
uint8_t hal_usart_receive_byte(void);
void hal_adc_init(void);
uint16_t hal_adc_read(uint8_t channel);
void hal_dac_init(void);
void hal_dac_write(uint16_t value);
void hal_spi_init(void);
void hal_spi_transfer(uint8_t *tx_data, uint8_t *rx_data, uint32_t len);
void hal_i2c_init(void);
uint8_t hal_i2c_read(uint8_t slave_addr, uint8_t reg_addr, uint8_t *data, uint32_t len);
uint8_t hal_i2c_write(uint8_t slave_addr, uint8_t reg_addr, uint8_t *data, uint32_t len);
void hal_rtc_init(void);
void hal_rtc_get_time(rtc_time_struct_type* time);
void hal_rtc_set_time(rtc_time_struct_type* time);
void hal_usb_init(void);
void hal_usb_send_data(uint8_t *data, uint32_t len);
uint32_t hal_usb_receive_data(uint8_t *data, uint32_t max_len);
#endif
// *********************************
// 文件:hal.c
// 描述:硬件抽象层实现
// *********************************
#include "hal.h"
#include "gd32f4xx_gpio.h"
#include "gd32f4xx_timer.h"
#include "gd32f4xx_usart.h"
#include "gd32f4xx_adc.h"
#include "gd32f4xx_dac.h"
#include "gd32f4xx_spi.h"
#include "gd32f4xx_i2c.h"
#include "gd32f4xx_rtc.h"
#include "usb_core.h"
#include "usb_user.h"
// 静态全局变量,用于 USB 缓冲区
static uint8_t usb_rx_buffer[64];
static uint32_t usb_rx_len = 0;
// 硬件初始化
void hal_init(void) {
// 使能时钟
rcu_periph_clock_enable(RCU_GPIOA);
rcu_periph_clock_enable(RCU_GPIOC);
rcu_periph_clock_enable(RCU_TIMER2);
rcu_periph_clock_enable(RCU_USART0);
rcu_periph_clock_enable(RCU_ADC0);
rcu_periph_clock_enable(RCU_DAC);
rcu_periph_clock_enable(RCU_SPI0);
rcu_periph_clock_enable(RCU_I2C0);
rcu_periph_clock_enable(RCU_RTC);
rcu_periph_clock_enable(RCU_USB_FS);
usb_clock_config();
// 配置 NVIC 中断优先级
nvic_irq_enable(TIMER2_IRQn, 0, 0);
nvic_irq_enable(USART0_IRQn, 1, 0);
nvic_irq_enable(USB_IRQn, 0, 0);
}
// 配置 GPIO 输出
void hal_gpio_set_output(uint32_t pin, uint32_t port) {
gpio_mode_set(port, GPIO_MODE_OUTPUT, GPIO_PUPD_NONE, pin);
gpio_output_options_set(port, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, pin);
}
// 配置 GPIO 输入
void hal_gpio_set_input(uint32_t pin, uint32_t port) {
gpio_mode_set(port, GPIO_MODE_INPUT, GPIO_PUPD_PULLUP, pin);
}
// 写 GPIO 输出
void hal_gpio_write_pin(uint32_t pin, uint32_t port, uint8_t value) {
if (value) {
gpio_bit_set(port, pin);
} else {
gpio_bit_reset(port, pin);
}
}
// 读取 GPIO 输入
uint8_t hal_gpio_read_pin(uint32_t pin, uint32_t port) {
return gpio_input_bit_get(port, pin);
}
// 初始化定时器
void hal_timer_init(uint32_t freq_hz) {
timer_parameter_struct timer_initpara;
timer_initpara.prescaler = (uint32_t)(SystemCoreClock / freq_hz) - 1;
timer_initpara.alignedmode = TIMER_COUNTER_EDGE;
timer_initpara.counterdirection = TIMER_COUNTER_UP;
timer_initpara.period = 0xFFFF;
timer_initpara.clockdivision = TIMER_CKDIV_DIV1;
timer_init(TIMER2, &timer_initpara);
timer_interrupt_enable(TIMER2, TIMER_INT_UP);
}
// 启动定时器
void hal_timer_start(void) {
timer_enable(TIMER2);
}
// 停止定时器
void hal_timer_stop(void) {
timer_disable(TIMER2);
}
// 定时器延时
void hal_timer_delay_ms(uint32_t ms) {
// 实现延时函数
uint32_t start_time = timer_counter_read(TIMER2);
uint32_t end_time = (uint32_t)((uint64_t)SystemCoreClock * ms / 1000000);
while(timer_counter_read(TIMER2) - start_time < end_time);
}
// 初始化串口
void hal_usart_init(uint32_t baudrate) {
usart_deinit(USART0);
usart_parameter_struct usart_initpara;
usart_initpara.baudrate = baudrate;
usart_initpara.word_length = USART_WL_8BIT;
usart_initpara.stop_bit = USART_STB_1BIT;
usart_initpara.parity = USART_PARITY_NONE;
usart_initpara.mode = USART_MODE_TX | USART_MODE_RX;
usart_initpara.hardware_flow_control = USART_HARDWARE_FLOW_NONE;
usart_init(USART0, &usart_initpara);
// 使能接收中断
usart_interrupt_enable(USART0, USART_INT_RBNE);
usart_enable(USART0);
}
// 发送一个字节
void hal_usart_send_byte(uint8_t byte) {
usart_data_transmit(USART0, byte);
while(usart_flag_get(USART0, USART_FLAG_TC) == RESET);
}
// 接收一个字节
uint8_t hal_usart_receive_byte(void) {
return usart_data_receive(USART0);
}
// ADC 初始化
void hal_adc_init(void) {
adc_mode_config(ADC_MODE_FREE);
adc_special_function_config(ADC0, ADC_SCAN_MODE, DISABLE);
adc_data_alignment_config(ADC0, ADC_DATAALIGN_RIGHT);
adc_resolution_config(ADC0, ADC_RESOLUTION_12B);
adc_channel_length_config(ADC0, ADC_REGULAR_CHANNEL, 1);
adc_enable(ADC0);
adc_calibration_enable(ADC0);
}
// ADC 读取
uint16_t hal_adc_read(uint8_t channel) {
adc_regular_channel_config(ADC0, 0, channel, ADC_SAMPLETIME_55POINT5);
adc_software_trigger_enable(ADC0, ADC_REGULAR_CHANNEL);
while(adc_flag_get(ADC0, ADC_FLAG_EOC) == RESET);
return adc_regular_data_read(ADC0);
}
// DAC 初始化
void hal_dac_init(void) {
dac_trigger_source_config(DAC_TRIGGER_SOFTWARE);
dac_output_buffer_disable(DAC_CHANNEL_0);
dac_enable(DAC_CHANNEL_0);
}
// DAC 输出
void hal_dac_write(uint16_t value) {
dac_data_set(DAC_ALIGN_R_12B, value, DAC_CHANNEL_0);
dac_software_trigger_enable(DAC_CHANNEL_0);
}
// SPI 初始化
void hal_spi_init(void) {
spi_parameter_struct spi_initpara;
spi_initpara.trans_mode = SPI_TRANSMODE_FULLDUPLEX;
spi_initpara.device_mode = SPI_MASTER;
spi_initpara.frame_size = SPI_FRAMESIZE_8BIT;
spi_initpara.clock_polarity_phase = SPI_CK_PL_LOW_PH_1EDGE;
spi_initpara.nss = SPI_NSS_SOFT;
spi_initpara.first_bit = SPI_FIRSTBIT_MSB;
spi_initpara.prescale = SPI_PSC_2;
spi_init(SPI0, &spi_initpara);
spi_enable(SPI0);
}
// SPI 数据传输
void hal_spi_transfer(uint8_t *tx_data, uint8_t *rx_data, uint32_t len) {
uint32_t i;
for(i = 0; i < len; i++) {
while(RESET == spi_i2s_flag_get(SPI0, SPI_FLAG_TBE));
spi_i2s_data_transmit(SPI0, tx_data[i]);
while(RESET == spi_i2s_flag_get(SPI0, SPI_FLAG_RBNE));
rx_data[i] = spi_i2s_data_receive(SPI0);
}
}
// I2C 初始化
void hal_i2c_init(void) {
i2c_parameter_struct i2c_initpara;
i2c_initpara.speed = 400000;
i2c_initpara.addr_mode = I2C_ADDR_MODE_7BIT;
i2c_initpara.duty_cycle = I2C_DTCY_2;
i2c_initpara.device_address = 0x00;
i2c_init(I2C0, &i2c_initpara);
i2c_enable(I2C0);
i2c_ack_config(I2C0, I2C_ACK_ENABLE);
}
// I2C 读取
uint8_t hal_i2c_read(uint8_t slave_addr, uint8_t reg_addr, uint8_t *data, uint32_t len) {
i2c_start_on_bus(I2C0);
if (i2c_wait_event(I2C0, I2C_EVENT_MASTER_MODE_FLAG) != ERROR) {
i2c_master_address_set(I2C0, slave_addr, I2C_TRANSMITTER);
if (i2c_wait_event(I2C0, I2C_EVENT_MASTER_TRANSMITTER_MODE_FLAG) != ERROR) {
i2c_data_transmit(I2C0, reg_addr);
if (i2c_wait_event(I2C0, I2C_EVENT_MASTER_TRANSMITTED) != ERROR) {
i2c_start_on_bus(I2C0);
if (i2c_wait_event(I2C0, I2C_EVENT_MASTER_MODE_FLAG) != ERROR) {
i2c_master_address_set(I2C0, slave_addr, I2C_RECEIVER);
if (i2c_wait_event(I2C0, I2C_EVENT_MASTER_RECEIVER_MODE_FLAG) != ERROR) {
for (int i = 0; i < len -1; i++) {
while(!i2c_flag_get(I2C0, I2C_FLAG_RBNE));
data[i] = i2c_data_receive(I2C0);
}
i2c_ack_config(I2C0, I2C_ACK_DISABLE);
while(!i2c_flag_get(I2C0, I2C_FLAG_RBNE));
data[len-1] = i2c_data_receive(I2C0);
i2c_ack_config(I2C0, I2C_ACK_ENABLE);
} else {
i2c_stop_on_bus(I2C0);
return 1;
}
} else {
i2c_stop_on_bus(I2C0);
return 1;
}
} else {
i2c_stop_on_bus(I2C0);
return 1;
}
} else {
i2c_stop_on_bus(I2C0);
return 1;
}
} else {
i2c_stop_on_bus(I2C0);
return 1;
}
i2c_stop_on_bus(I2C0);
return 0;
}
// I2C 写
uint8_t hal_i2c_write(uint8_t slave_addr, uint8_t reg_addr, uint8_t *data, uint32_t len) {
i2c_start_on_bus(I2C0);
if (i2c_wait_event(I2C0, I2C_EVENT_MASTER_MODE_FLAG) != ERROR) {
i2c_master_address_set(I2C0, slave_addr, I2C_TRANSMITTER);
if (i2c_wait_event(I2C0, I2C_EVENT_MASTER_TRANSMITTER_MODE_FLAG) != ERROR) {
i2c_data_transmit(I2C0, reg_addr);
if (i2c_wait_event(I2C0, I2C_EVENT_MASTER_TRANSMITTED) != ERROR) {
for(int i = 0; i<len; i++) {
i2c_data_transmit(I2C0, data[i]);
if(i2c_wait_event(I2C0, I2C_EVENT_MASTER_TRANSMITTED) == ERROR)
return 1;
}
} else {
i2c_stop_on_bus(I2C0);
return 1;
}
} else {
i2c_stop_on_bus(I2C0);
return 1;
}
} else {
i2c_stop_on_bus(I2C0);
return 1;
}
i2c_stop_on_bus(I2C0);
return 0;
}
// RTC 初始化
void hal_rtc_init(void) {
rcu_periph_clock_enable(RCU_BKPI);
pmu_backup_write_enable();
rtc_prescaler_set(32767);
rtc_to_calendar_time(RTC_CALENDAR_2024, RTC_MONTH_1, RTC_DATE_1, RTC_WEEK_MONDAY, 0, 0, 0);
rtc_init();
pmu_backup_write_disable();
}
// 获取 RTC 时间
void hal_rtc_get_time(rtc_time_struct_type* time) {
rtc_calendar_get(time);
}
// 设置 RTC 时间
void hal_rtc_set_time(rtc_time_struct_type* time) {
pmu_backup_write_enable();
rtc_to_calendar_time(time->year,time->month,time->date,time->week,time->hour,time->minute,time->second);
pmu_backup_write_disable();
}
// USB 初始化
void hal_usb_init(void) {
usb_init();
}
// USB 发送数据
void hal_usb_send_data(uint8_t *data, uint32_t len) {
usb_data_send(data, len);
}
// USB 接收数据
uint32_t hal_usb_receive_data(uint8_t *data, uint32_t max_len) {
if(usb_rx_len > 0){
uint32_t len = usb_rx_len;
if (len > max_len) len = max_len;
memcpy(data, usb_rx_buffer,len);
usb_rx_len = 0;
return len;
}
return 0;
}
// USB 中断处理函数
void USB_LP_CAN1_RX0_IRQHandler(void)
{
usb_irp_handler();
}
// USB 数据接收完成回调
void usb_rx_callback(uint8_t *data, uint32_t len) {
memcpy(usb_rx_buffer,data,len);
usb_rx_len = len;
}
//定时器中断处理函数
void TIMER2_IRQHandler(void)
{
if (RESET != timer_interrupt_flag_get(TIMER2, TIMER_INT_FLAG_UP)){
timer_interrupt_flag_clear(TIMER2, TIMER_INT_FLAG_UP);
//在此处添加中断处理程序
}
}
//串口中断处理函数
void USART0_IRQHandler(void){
if(RESET != usart_interrupt_flag_get(USART0, USART_INT_FLAG_RBNE)){
usart_interrupt_flag_clear(USART0,USART_INT_FLAG_RBNE);
// //接收到数据
uint8_t data = usart_data_receive(USART0);
hal_usart_send_byte(data); // echo
}
}
// *********************************
// 文件:drivers.h
// 描述:驱动层头文件
// *********************************
#ifndef DRIVERS_H
#define DRIVERS_H
#include "hal.h"
// LED 驱动
typedef struct {
uint32_t pin;
uint32_t port;
uint8_t level; // LED亮度级别
} led_t;
void led_init(led_t *led);
void led_set_level(led_t *led, uint8_t level); // 设置亮度级别 0-255
void led_toggle(led_t *led);
// 按键驱动
typedef struct {
uint32_t pin;
uint32_t port;
uint8_t state; // 按键状态 0: 未按下, 1: 按下
} button_t;
void button_init(button_t *button);
uint8_t button_get_state(button_t *button);
uint8_t button_is_press(button_t *button);
// 传感器驱动
// 定义一个通用的传感器结构体
typedef struct {
uint8_t slave_addr;
uint8_t (*read)(uint8_t reg_addr, uint8_t *data, uint32_t len);
uint8_t (*write)(uint8_t reg_addr, uint8_t *data, uint32_t len);
} sensor_t;
// 示例:温度传感器
typedef struct {
sensor_t sensor;
float temperature;
} temperature_sensor_t;
void temperature_sensor_init(temperature_sensor_t *sensor);
float temperature_sensor_read(temperature_sensor_t *sensor);
// 通用传感器读取数据
uint8_t sensor_read_data(sensor_t *sensor, uint8_t reg_addr, uint8_t *data, uint32_t len);
// 通用传感器写入数据
uint8_t sensor_write_data(sensor_t *sensor, uint8_t reg_addr, uint8_t *data, uint32_t len);
void drivers_init(void);
#endif
// *********************************
// 文件:drivers.c
// 描述:驱动层实现
// *********************************
#include "drivers.h"
#include "hal.h"
// LED 初始化
void led_init(led_t *led) {
hal_gpio_set_output(led->pin, led->port);
led->level = 0; // 初始化为0级亮度
hal_gpio_write_pin(led->pin, led->port, 0); // 默认关闭
}
// 设置 LED 亮度级别 (PWM方式)
void led_set_level(led_t *led, uint8_t level) {
//简单起见,这里采用软件PWM,实际应用建议使用硬件PWM
led->level = level;
}
// 切换 LED 状态
void led_toggle(led_t *led) {
uint8_t current_state = hal_gpio_read_pin(led->pin, led->port);
hal_gpio_write_pin(led->pin, led->port, !current_state);
}
// 按键初始化
void button_init(button_t *button) {
hal_gpio_set_input(button->pin, button->port);
button->state = 0; // 初始化为未按下状态
}
// 获取按键状态
uint8_t button_get_state(button_t *button) {
return hal_gpio_read_pin(button->pin, button->port) == 0;
}
// 判断按键是否按下
uint8_t button_is_press(button_t *button) {
if(button_get_state(button))
return 1;
return 0;
}
// 通用传感器读取数据
uint8_t sensor_read_data(sensor_t *sensor, uint8_t reg_addr, uint8_t *data, uint32_t len) {
return sensor->read(sensor->slave_addr, reg_addr, data, len);
}
// 通用传感器写入数据
uint8_t sensor_write_data(sensor_t *sensor, uint8_t reg_addr, uint8_t *data, uint32_t len) {
return sensor->write(sensor->slave_addr, reg_addr, data, len);
}
// 初始化温度传感器
void temperature_sensor_init(temperature_sensor_t *sensor) {
//假设传感器为 SHT30,I2C地址为 0x44
sensor->sensor.slave_addr = 0x44;
sensor->sensor.read = hal_i2c_read;
sensor->sensor.write = hal_i2c_write;
}
// 读取温度传感器数据
float temperature_sensor_read(temperature_sensor_t *sensor) {
uint8_t data[6];
sensor_write_data(&sensor->sensor, 0x23, NULL, 0); // 发送读取命令(SHT30)
hal_timer_delay_ms(10);
if (0 == sensor_read_data(&sensor->sensor, 0x00, data, 6)) {
uint32_t temp = (uint32_t)data[0] << 8 | data[1];
temp = (temp * 1750) / 65535 - 450;
float temperature = (float)temp/10.0f;
sensor->temperature = temperature;
return temperature;
} else {
return -1000.0f;
}
}
void drivers_init(void) {
// 初始化 LED
static led_t led_red, led_green, led_blue;
led_red.pin = LED_RED_PIN;
led_red.port = LED_PORT;
led_green.pin = LED_GREEN_PIN;
led_green.port = LED_PORT;
led_blue.pin = LED_BLUE_PIN;
led_blue.port = LED_PORT;
led_init(&led_red);
led_init(&led_green);
led_init(&led_blue);
// 初始化按键
static button_t button_1, button_2;
button_1.pin = BUTTON_1_PIN;
button_1.port = BUTTON_PORT;
button_2.pin = BUTTON_2_PIN;
button_2.port = BUTTON_PORT;
button_init(&button_1);
button_init(&button_2);
//初始化温度传感器
static temperature_sensor_t temp_sensor;
temperature_sensor_init(&temp_sensor);
// 驱动层初始化完成
}
// *********************************
// 文件:middleware.h
// 描述:中间件层头文件
// *********************************
#ifndef MIDDLEWARE_H
#define MIDDLEWARE_H
#include "hal.h"
#include "drivers.h"
// 任务调度器
typedef void (*task_function_t)(void);
typedef struct {
task_function_t task;
uint32_t delay_ms;
uint32_t last_run;
} task_t;
void task_scheduler_add(task_t *task);
void task_scheduler_run(void);
// 软件定时器
typedef struct {
uint32_t interval_ms;
uint32_t last_tick;
uint8_t is_timeout;
} software_timer_t;
void software_timer_init(software_timer_t *timer, uint32_t interval_ms);
void software_timer_update(software_timer_t *timer);
uint8_t software_timer_is_timeout(software_timer_t *timer);
void software_timer_reset(software_timer_t *timer);
// 日志系统
void log_info(char* format, ...);
void log_error(char* format, ...);
void middleware_init(void);
#endif
// *********************************
// 文件:middleware.c
// 描述:中间件层实现
// *********************************
#include "middleware.h"
#include "stdio.h"
#include "stdarg.h"
// 任务队列
#define MAX_TASKS 10
static task_t task_queue[MAX_TASKS];
static uint8_t task_count = 0;
// 添加任务到调度器
void task_scheduler_add(task_t *task) {
if (task_count < MAX_TASKS) {
task_queue[task_count] = *task;
task_count++;
}
}
// 运行任务调度器
void task_scheduler_run(void) {
for (int i = 0; i < task_count; i++) {
uint32_t current_time = timer_counter_read(TIMER2) / (SystemCoreClock/1000);
if (current_time - task_queue[i].last_run >= task_queue[i].delay_ms) {
task_queue[i].task();
task_queue[i].last_run = current_time;
}
}
}
// 初始化软件定时器
void software_timer_init(software_timer_t *timer, uint32_t interval_ms) {
timer->interval_ms = interval_ms;
timer->last_tick = timer_counter_read(TIMER2) / (SystemCoreClock/1000);
timer->is_timeout = 0;
}
// 更新软件定时器
void software_timer_update(software_timer_t *timer) {
uint32_t current_time = timer_counter_read(TIMER2) / (SystemCoreClock/1000);
if (current_time - timer->last_tick >= timer->interval_ms) {
timer->is_timeout = 1;
}
}
// 判断软件定时器是否超时
uint8_t software_timer_is_timeout(software_timer_t *timer) {
return timer->is_timeout;
}
// 重置软件定时器
void software_timer_reset(software_timer_t *timer) {
timer->is_timeout = 0;
timer->last_tick = timer_counter_read(TIMER2) / (SystemCoreClock/1000);
}
// 日志信息
void log_info(char* format, ...) {
char buffer[256];