From 17413f4cc21d110227238f5d098d90297da9812f Mon Sep 17 00:00:00 2001 From: yelvlab Date: Wed, 13 Aug 2025 20:15:17 +0800 Subject: [PATCH] fix delay ms & delay 10us --- Inc/systick.h | 15 +++-- Src/gd32e23x_it.c | 1 + Src/main.c | 15 +++-- Src/systick.c | 139 +++++++++++++++++++++------------------------- 4 files changed, 83 insertions(+), 87 deletions(-) diff --git a/Inc/systick.h b/Inc/systick.h index 83285bc..202ecf6 100644 --- a/Inc/systick.h +++ b/Inc/systick.h @@ -18,16 +18,19 @@ /* configure systick */ void systick_config(void); +/* delay a time in 10 microseconds */ +void delay_10us(uint32_t count); + /* delay a time in milliseconds */ void delay_ms(uint32_t count); -/* delay a time in microseconds */ -void delay_us(uint32_t count); +/* decrement delay counters */ +void delay_decrement(void); -/* delay function that doesn't interfere with SysTick interrupt */ -void delay_ms_safe(uint32_t count); +// /* delay function that doesn't interfere with SysTick interrupt */ +// void delay_ms_safe(uint32_t count); -/* delay a time in microseconds (safe version) */ -void delay_us_safe(uint32_t count); +// /* delay a time in microseconds (safe version) */ +// void delay_us_safe(uint32_t count); #endif /* SYS_TICK_H */ \ No newline at end of file diff --git a/Src/gd32e23x_it.c b/Src/gd32e23x_it.c index 3512280..aa19aa8 100644 --- a/Src/gd32e23x_it.c +++ b/Src/gd32e23x_it.c @@ -98,6 +98,7 @@ void PendSV_Handler(void) */ void SysTick_Handler(void) { led_heart_beat(); // LED心跳指示灯 + delay_decrement(); } void USART0_IRQHandler(void) { diff --git a/Src/main.c b/Src/main.c index fced534..9a962e5 100644 --- a/Src/main.c +++ b/Src/main.c @@ -56,11 +56,16 @@ int main(void) led_init(); - printf("Hello USART0!"); - // 移除led_off()调用,让心跳函数控制LED + char hello_world[] = {"Hello World!"}; + + for (uint8_t i = 0; i < sizeof(hello_world); i++) + { + while (usart_flag_get(RS485_PHY, USART_FLAG_TBE) == RESET) {} + usart_data_transmit(RS485_PHY, hello_world[i]); + } + + while (usart_flag_get(RS485_PHY, USART_FLAG_TC) == RESET) {} + while(1){ - // 使用不会干扰SysTick中断的安全延时函数 - delay_ms_safe(100); - command_process(); } } diff --git a/Src/systick.c b/Src/systick.c index 9a385ac..fd3d707 100644 --- a/Src/systick.c +++ b/Src/systick.c @@ -12,8 +12,7 @@ #include "gd32e23x.h" #include "systick.h" -volatile static float count_1us = 0; -volatile static float count_1ms = 0; +volatile static uint32_t delay_count = 0; /** * ************************************************************************ @@ -24,45 +23,32 @@ volatile static float count_1ms = 0; */ void systick_config(void) { - //设置了 SysTick 定时器的时钟源为 HCLK/8 - systick_clksource_set(SYSTICK_CLKSOURCE_HCLK_DIV8); - //计算了每微秒所需的 SysTick 计数值 - count_1us = (float)SystemCoreClock/8000000; - //计算了每毫秒所需的 SysTick 计数值 - count_1ms = (float)count_1us * 1000; + //设置了 SysTick 定时器的时钟源为 HCLK + systick_clksource_set(SYSTICK_CLKSOURCE_HCLK); // 配置SysTick为1ms周期中断 // 注意:SysTick_Config会自动设置时钟源为HCLK,所以需要使用SystemCoreClock/1000 - SysTick_Config(SystemCoreClock / 1000); // 1ms中断 + SysTick_Config(SystemCoreClock / 1000U); // 1ms中断 + NVIC_SetPriority(SysTick_IRQn, 0x00U); } /** * ************************************************************************ - * @brief delay_us 微秒延时函数 + * @brief delay_ms 毫秒延时函数 * - * @param[in] count 微秒值 + * @param[in] count 毫秒值 * * ************************************************************************ */ -void delay_us(uint32_t count) +void delay_10us(uint32_t count) { - uint32_t ctl; + // 基于系统时钟的简单循环延时 + // 这是一个粗略的估计,实际延时可能有偏差 实测10.2us + uint32_t loops_per_10us = SystemCoreClock / 1700000; // 粗略估计,每10微秒的循环次数 - //设置 SysTick 计数器的装载值 - SysTick->LOAD = (uint32_t)(count * count_1us); - //清零 SysTick 计数器,以确保计数器从零开始计数 - SysTick->VAL = 0x0000U; - //使能 SysTick 定时器,开始进行计数 - SysTick->CTRL = SysTick_CTRL_ENABLE_Msk; - //等待 SysTick 计数器的计数值达到装载值时退出 - do - { - ctl = SysTick->CTRL; //读取 CTRL 寄存器的值 - }while((ctl & SysTick_CTRL_ENABLE_Msk)&&!(ctl & SysTick_CTRL_COUNTFLAG_Msk)); - //循环退出,禁用 SysTick 定时器 - SysTick->CTRL &= ~SysTick_CTRL_ENABLE_Msk; - //将 SysTick 计数器的当前值清零,以便下次使用 - SysTick->VAL = 0x0000U; + for(uint32_t i = 0; i < count; i++) { + for(volatile uint32_t j = 0; j < loops_per_10us; j++); + } } /** @@ -75,57 +61,58 @@ void delay_us(uint32_t count) */ void delay_ms(uint32_t count) { - uint32_t ctl; + delay_count = count; // 设置延时计数 + while (delay_count != 0U); +} - //设置 SysTick 计数器的装载值 - SysTick->LOAD = (uint32_t)(count * count_1ms); - //清零 SysTick 计数器,以确保计数器从零开始计数 - SysTick->VAL = 0x0000U; - //使能 SysTick 定时器,开始进行计数 - SysTick->CTRL = SysTick_CTRL_ENABLE_Msk; - //等待 SysTick 计数器的计数值达到装载值时退出 - do +/** + * ************************************************************************ + * @brief 每个 SysTick 中断调用时,减少延时计数 + * + * @param[in] void + * + * ************************************************************************ + */ +void delay_decrement(void) +{ + if (delay_count != 0U) { - ctl = SysTick->CTRL; //读取 CTRL 寄存器的值 - }while((ctl&SysTick_CTRL_ENABLE_Msk)&&!(ctl & SysTick_CTRL_COUNTFLAG_Msk)); - //循环退出,禁用 SysTick 定时器 - SysTick->CTRL &= ~SysTick_CTRL_ENABLE_Msk; - //将 SysTick 计数器的当前值清零,以便下次使用 - SysTick->VAL = 0x0000U; -} - -/** - * ************************************************************************ - * @brief delay_ms_safe 毫秒延时函数(不干扰SysTick中断) - * @details 使用简单循环实现延时,不会重新配置SysTick - * @param[in] count 毫秒值 - * ************************************************************************ - */ -void delay_ms_safe(uint32_t count) -{ - // 基于系统时钟的简单循环延时 - // 这是一个粗略的估计,实际延时可能有偏差 - uint32_t loops_per_ms = SystemCoreClock / 8000; // 粗略估计 - - for(uint32_t i = 0; i < count; i++) { - for(volatile uint32_t j = 0; j < loops_per_ms; j++); + delay_count--; } } -/** - * ************************************************************************ - * @brief delay_us_safe 微秒延时函数(不干扰SysTick中断) - * @details 使用简单循环实现延时,不会重新配置SysTick - * @param[in] count 微秒值 - * ************************************************************************ - */ -void delay_us_safe(uint32_t count) -{ - // 基于系统时钟的简单循环延时 - // 这是一个粗略的估计,实际延时可能有偏差 - uint32_t loops_per_us = SystemCoreClock / 8000000; // 粗略估计,每微秒的循环次数 +// /** +// * ************************************************************************ +// * @brief delay_ms_safe 毫秒延时函数(不干扰SysTick中断) +// * @details 使用简单循环实现延时,不会重新配置SysTick +// * @param[in] count 毫秒值 +// * ************************************************************************ +// */ +// void delay_ms_safe(uint32_t count) +// { +// // 基于系统时钟的简单循环延时 +// // 这是一个粗略的估计,实际延时可能有偏差 +// uint32_t loops_per_ms = SystemCoreClock / 14000; // 粗略估计 - for(uint32_t i = 0; i < count; i++) { - for(volatile uint32_t j = 0; j < loops_per_us; j++); - } -} \ No newline at end of file +// for(uint32_t i = 0; i < count; i++) { +// for(volatile uint32_t j = 0; j < loops_per_ms; j++); +// } +// } + +// /** +// * ************************************************************************ +// * @brief delay_us_safe 微秒延时函数(不干扰SysTick中断) +// * @details 使用简单循环实现延时,不会重新配置SysTick +// * @param[in] count 微秒值 +// * ************************************************************************ +// */ +// void delay_us_safe(uint32_t count) +// { +// // 基于系统时钟的简单循环延时 +// // 这是一个粗略的估计,实际延时可能有偏差 +// uint32_t loops_per_us = SystemCoreClock / 22000000; // 粗略估计,每微秒的循环次数 + +// for(uint32_t i = 0; i < count; i++) { +// for(volatile uint32_t j = 0; j < loops_per_us; j++); +// } +// } \ No newline at end of file