add delay ms safe & add led heart beat

This commit is contained in:
yelvlab 2025-08-13 00:56:55 +08:00
parent 1dde17d211
commit e9a96aec6a
6 changed files with 68 additions and 2 deletions

View File

@ -8,5 +8,6 @@ void led_init(void);
void led_on(void); void led_on(void);
void led_off(void); void led_off(void);
void led_toggle(void); void led_toggle(void);
void led_heart_beat(void);
#endif // LED_H #endif // LED_H

View File

@ -24,4 +24,7 @@ void delay_ms(uint32_t count);
/* delay a time in microseconds */ /* delay a time in microseconds */
void delay_us(uint32_t count); void delay_us(uint32_t count);
/* delay function that doesn't interfere with SysTick interrupt */
void delay_ms_safe(uint32_t count);
#endif /* SYS_TICK_H */ #endif /* SYS_TICK_H */

View File

@ -36,6 +36,7 @@ OF SUCH DAMAGE.
#include "systick.h" #include "systick.h"
#include "uart.h" #include "uart.h"
#include "uart_ring_buffer.h" #include "uart_ring_buffer.h"
#include "led.h"
/*! /*!
\brief this function handles NMI exception \brief this function handles NMI exception
@ -96,6 +97,7 @@ void PendSV_Handler(void)
\retval none \retval none
*/ */
void SysTick_Handler(void) { void SysTick_Handler(void) {
led_heart_beat(); // LED心跳指示灯
} }
void USART0_IRQHandler(void) { void USART0_IRQHandler(void) {

View File

@ -1,5 +1,42 @@
#include "led.h" #include "led.h"
/**
* @brief LED心跳指示灯功能
* @details LED闪烁模式
* SysTick中断中调用
* @note SysTick中断频率为1ms2
* 200ms->200ms->200ms->1400ms
*/
void led_heart_beat(void)
{
static uint16_t heart_beat_counter = 0;
// 心跳周期2000ms (假设SysTick为1ms中断)
// 模式亮200ms -> 灭200ms -> 亮200ms -> 灭1400ms
heart_beat_counter++;
if (heart_beat_counter <= 200) {
// 第一次亮0-200ms
led_on();
}
else if (heart_beat_counter <= 400) {
// 第一次灭200-400ms
led_off();
}
else if (heart_beat_counter <= 600) {
// 第二次亮400-600ms
led_on();
}
else if (heart_beat_counter <= 2000) {
// 长时间灭600-2000ms
led_off();
}
else {
// 重置计数器,开始新的心跳周期
heart_beat_counter = 0;
}
}
void led_init(void) { void led_init(void) {
rcu_periph_clock_enable(LED_RCU); rcu_periph_clock_enable(LED_RCU);
gpio_mode_set(LED_PORT, GPIO_MODE_OUTPUT, GPIO_PUPD_NONE, LED_PIN); gpio_mode_set(LED_PORT, GPIO_MODE_OUTPUT, GPIO_PUPD_NONE, LED_PIN);

View File

@ -57,9 +57,10 @@ int main(void)
led_init(); led_init();
printf("Hello USART0!"); printf("Hello USART0!");
led_off(); // 移除led_off()调用让心跳函数控制LED
while(1){ while(1){
delay_ms(100); // 使用不会干扰SysTick中断的安全延时函数
delay_ms_safe(100);
command_process(); command_process();
} }
} }

View File

@ -30,6 +30,10 @@ void systick_config(void)
count_1us = (float)SystemCoreClock/8000000; count_1us = (float)SystemCoreClock/8000000;
//计算了每毫秒所需的 SysTick 计数值 //计算了每毫秒所需的 SysTick 计数值
count_1ms = (float)count_1us * 1000; count_1ms = (float)count_1us * 1000;
// 配置SysTick为1ms周期中断
// 注意SysTick_Config会自动设置时钟源为HCLK所以需要使用SystemCoreClock/1000
SysTick_Config(SystemCoreClock / 1000); // 1ms中断
} }
/** /**
@ -88,4 +92,22 @@ void delay_ms(uint32_t count)
SysTick->CTRL &= ~SysTick_CTRL_ENABLE_Msk; SysTick->CTRL &= ~SysTick_CTRL_ENABLE_Msk;
//将 SysTick 计数器的当前值清零,以便下次使用 //将 SysTick 计数器的当前值清零,以便下次使用
SysTick->VAL = 0x0000U; 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++);
}
} }