#include "stm32f10x.h"
// 硬件定義
#define LED_PORT GPIOA
#define LED_PINS (GPIO_Pin_0 | GPIO_Pin_1 | GPIO_Pin_2 | GPIO_Pin_3 | \
GPIO_Pin_4 | GPIO_Pin_5 | GPIO_Pin_6 | GPIO_Pin_7)
#define KEY_PORT GPIOB
#define KEY_PIN GPIO_Pin_0
#define BEEP_PORT GPIOB
#define BEEP_PIN GPIO_Pin_1
// 系統(tǒng)狀態(tài)
typedef enum {
SYSTEM_OFF,
SYSTEM_RUNNING
} SystemState;
// 燈光模式
typedef enum {
MODE_1_RIGHT_LEFT,
MODE_2_LEFT_RIGHT,
MODE_3_INSIDE_OUT,
MODE_4_BLINK_ALL,
MODE_COUNT
} LightMode;
// 全局變量
volatile SystemState sysState = SYSTEM_OFF;
volatile LightMode currentMode = MODE_1_RIGHT_LEFT;
uint8_t ledPosition = 0;
uint16_t delayCounter = 0;
uint8_t blinkState = 0;
// 函數(shù)原型
void RCC_Configure(void);
void GPIO_Configure(void);
void TIM_Configure(void);
void SysTick_Handler(void);
void UpdateLEDs(void);
void Beep(uint16_t duration, uint8_t times);
void ProcessKey(void);
int main(void) {
// 初始化
RCC_Configure();
GPIO_Configure();
TIM_Configure();
// 系統(tǒng)啟動提示
Beep(100, 2);
while(1) {
ProcessKey();
__WFI(); // 進入低功耗模式等待中斷
}
}
// 時鐘配置
void RCC_Configure(void) {
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_GPIOB |
RCC_APB2Periph_AFIO, ENABLE);
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);
}
// GPIO配置
void GPIO_Configure(void) {
GPIO_InitTypeDef GPIO_InitStructure;
// LED配置 - PA0~PA7
GPIO_InitStructure.GPIO_Pin = LED_PINS;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(LED_PORT, &GPIO_InitStructure);
LED_PORT->ODR = 0x00; // 初始關閉所有LED
// 按鍵配置 - PB0 (外部上拉)
GPIO_InitStructure.GPIO_Pin = KEY_PIN;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
GPIO_Init(KEY_PORT, &GPIO_InitStructure);
// 蜂鳴器配置 - PB1
GPIO_InitStructure.GPIO_Pin = BEEP_PIN;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_Init(BEEP_PORT, &GPIO_InitStructure);
GPIO_ResetBits(BEEP_PORT, BEEP_PIN);
}
// 定時器配置 - 10ms中斷一次
void TIM_Configure(void) {
TIM_TimeBaseInitTypeDef TIM_InitStructure;
NVIC_InitTypeDef NVIC_InitStructure;
TIM_InitStructure.TIM_Period = 1000 - 1; // 自動重裝載值
TIM_InitStructure.TIM_Prescaler = 720 - 1; // 72MHz/720 = 100kHz
TIM_InitStructure.TIM_ClockDivision = 0;
TIM_InitStructure.TIM_CounterMode = TIM_CounterMode_Up;
TIM_TimeBaseInit(TIM2, &TIM_InitStructure);
TIM_ITConfig(TIM2, TIM_IT_Update, ENABLE);
TIM_Cmd(TIM2, ENABLE);
// 配置中斷
NVIC_InitStructure.NVIC_IRQChannel = TIM2_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
}
// 蜂鳴器控制
void Beep(uint16_t duration, uint8_t times) {
for(uint8_t i = 0; i < times; i++) {
GPIO_SetBits(BEEP_PORT, BEEP_PIN);
for(volatile uint32_t j = 0; j < duration * 1000; j++);
GPIO_ResetBits(BEEP_PORT, BEEP_PIN);
for(volatile uint32_t j = 0; j < 10000; j++); // 短暫間隔
}
}
// 處理按鍵
void ProcessKey(void) {
static uint8_t keyLastState = 1; // 假設初始高電平
static uint32_t pressTime = 0;
uint8_t currentState = GPIO_ReadInputDataBit(KEY_PORT, KEY_PIN);
// 檢測按鍵按下 (下降沿)
if((keyLastState == 1) && (currentState == 0)) {
pressTime = 0;
}
// 檢測按鍵釋放 (上升沿)
if((keyLastState == 0) && (currentState == 1)) {
if(pressTime < 50) { // 短按 (<0.5s)
if(sysState == SYSTEM_OFF) {
sysState = SYSTEM_RUNNING; // 啟動系統(tǒng)
Beep(100, 1);
} else {
// 切換燈光模式
currentMode = (currentMode + 1) % MODE_COUNT;
Beep(150, currentMode + 1);
ledPosition = 0; // 重置燈光位置
}
} else { // 長按 (>0.5s)
sysState = (sysState == SYSTEM_OFF) ? SYSTEM_RUNNING : SYSTEM_OFF;
Beep(100, (sysState == SYSTEM_ON) ? 1 : 2);
LED_PORT->ODR = 0x00; // 關閉所有LED
}
}
keyLastState = currentState;
pressTime++;
}
// 更新LED顯示
void UpdateLEDs(void) {
if(sysState != SYSTEM_RUNNING) return;
if(delayCounter++ < 10) return; // 100ms延遲
delayCounter = 0;
switch(currentMode) {
case MODE_1_RIGHT_LEFT: // 從左向右流水燈
LED_PORT->ODR = (1 << ledPosition);
ledPosition = (ledPosition + 1) % 8;
break;
case MODE_2_LEFT_RIGHT: // 從右向左流水燈
LED_PORT->ODR = (0x80 >> ledPosition);
ledPosition = (ledPosition + 1) % 8;
break;
case MODE_3_INSIDE_OUT: // 從中間向兩邊擴展
if(ledPosition < 4) {
LED_PORT->ODR = (1 << (3 - ledPosition)) | (1 << (4 + ledPosition));
} else {
LED_PORT->ODR = 0;
}
ledPosition = (ledPosition + 1) % 5;
break;
case MODE_4_BLINK_ALL: // 所有LED同步閃爍
LED_PORT->ODR = blinkState ? 0xFF : 0x00;
blinkState = !blinkState;
break;
}
}
// 定時器中斷 (10ms)
void TIM2_IRQHandler(void) {
if(TIM_GetITStatus(TIM2, TIM_IT_Update) != RESET) {
TIM_ClearITPendingBit(TIM2, TIM_IT_Update);
UpdateLEDs();
ProcessKey();
}
} |