1. 裸机系统下的前后台架构
任务说明
本案例要求在一个裸机(无操作系统)环境下,采用前后台架构实现LED闪烁功能。所谓前后台,即:后台为永不退出的主循环(while(1)),负责轮询事件标志并执行相应处理;前台为中断服务程序(ISR),负责响应硬件事件(如定时器溢出)并置位事件标志。通过该案例,理解前后台架构中“中断产生事件、主循环处理事件”的基本协作模式。
硬件连接与依赖
本案例以STM32F103系列MCU为运行目标,使用标准外设库(StdPeriph_Lib)。硬件连接如下:
- LED正极经220Ω限流电阻接PC13(STM32最小系统板载LED),阴极接地;
- 使用TIM2作为定时中断源,配置为1ms周期中断。
所需文件:main.c、stm32f10x_it.c(中断向量)、stm32f10x_conf.h(外设库配置头文件)。工程需包含标准外设库源码及启动文件。
代码实现
以下代码实现完整的LED闪烁功能:TIM2每1ms触发一次中断,在ISR中累加time_tick;主循环检测到500ms到达时翻转LED状态。核心逻辑如下:
// main.c
#include "stm32f10x.h"
volatile uint32_t time_tick = 0; // 前台ISR写入,后台主循环读取
void TIM2_IRQHandler(void) // 前台:定时器中断服务
{
if (TIM_GetITStatus(TIM2, TIM_IT_Update) != RESET) {
TIM_ClearITPendingBit(TIM2, TIM_IT_Update);
time_tick++; // 每1ms加1
}
}
static void LED_GPIO_Init(void)
{
GPIO_InitTypeDef gpio;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC, ENABLE);
gpio.GPIO_Pin = GPIO_Pin_13;
gpio.GPIO_Mode = GPIO_Mode_Out_PP;
gpio.GPIO_Speed = GPIO_Speed_2MHz;
GPIO_Init(GPIOC, &gpio);
}
static void TIM2_Init(void)
{
TIM_TimeBaseInitTypeDef tim;
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);
tim.TIM_Prescaler = 7200 - 1; // 72MHz/7200 = 10kHz
tim.TIM_CounterMode = TIM_CounterMode_Up;
tim.TIM_Period = 10 - 1; // 10kHz/10 = 1kHz → 1ms
tim.TIM_ClockDivision = TIM_CKD_DIV1;
TIM_TimeBaseInit(TIM2, &tim);
TIM_ITConfig(TIM2, TIM_IT_Update, ENABLE);
NVIC_EnableIRQ(TIM2_IRQn);
TIM_Cmd(TIM2, ENABLE);
}
int main(void)
{
uint32_t last_tick = 0;
LED_GPIO_Init();
TIM2_Init();
while (1) { // 后台:主循环
if (time_tick - last_tick >= 500) { // 500ms到
last_tick = time_tick;
GPIO_WriteBit(GPIOC, GPIO_Pin_13,
(BitAction)(1 - GPIO_ReadOutputDataBit(GPIOC, GPIO_Pin_13)));
}
}
}
编译与烧录
使用Keil MDK或IAR建立工程,添加上述main.c及标准外设库源文件(如stm32f10x_tim.c、stm32f10x_gpio.c、stm32f10x_rcc.c),包含对应头文件路径。编译生成HEX文件后,通过ST-Link或J-Link烧录至STM32F103开发板。
验证方法与判定标准
验证步骤:
- 将程序烧录至开发板,确认PC13引脚连接的LED正常点亮;
- 观察LED是否以约1Hz频率(每500ms翻转一次,即亮500ms、灭500ms)持续闪烁;
- 在调试器中设置断点于
TIM2_IRQHandler,确认每1ms进入一次中断; - 在
while(1)循环中观察time_tick变量持续递增。
判定标准:
- LED以肉眼可见的稳定频率闪烁(周期约1s),无停顿或跳变;
- 中断服务函数被周期性调用,
time_tick值单调递增; - 主循环中LED翻转间隔与
time_tick差值500ms对应,证明前后台协作正确。
若LED不闪烁或频率异常,检查TIM2时钟配置(确认系统主频为72MHz)及GPIO引脚连接是否正确。