// 定义不同的闪烁模式
#define LED_OFF 0
#define LED_ON 1
#define LED_BLINK_FAST 2
#define LED_BLINK_SLOW 3
#define LED_ALTERNATE_BLINK 4
// 定义错误码对应的闪烁模式
#define ERROR_MOUNT_SD_CARD LED_BLINK_FAST
#define ERROR_OPEN_FILE LED_BLINK_FAST
#define ERROR_ADC_DMA_INIT LED_BLINK_FAST
#define RECORDING_ON LED_ON
#define RECORDING_OFF LED_OFF
#define ERROR_LONG_PRESS LED_BLINK_FAST
// 错误处理函数,通过LED闪烁显示错误
void handleError(uint8_t errorMode) {
switch (errorMode) {
case ERROR_MOUNT_SD_CARD:
case ERROR_OPEN_FILE:
case ERROR_ADC_DMA_INIT:
case ERROR_LONG_PRESS:
// 设置LED闪烁模式来表示错误
setLEDMode(errorMode);
break;
default:
break;
}
}
// 设置LED的闪烁模式
void setLEDMode(uint8_t mode) {
switch (mode) {
case LED_OFF:
HAL_GPIO_WritePin(GPIO_PIN_1, GPIO_PIN_RESET); // LD1(绿色)关闭
HAL_GPIO_WritePin(GPIO_PIN_5, GPIO_PIN_RESET); // LD2(橙色)关闭
HAL_GPIO_WritePin(GPIO_PIN_2, GPIO_PIN_SET); // LD3(红色)关闭
break;
case LED_ON:
if (mode == RECORDING_ON) {
HAL_GPIO_WritePin(GPIO_PIN_1, GPIO_PIN_SET); // LD1(绿色)打开,表示录音中
HAL_GPIO_WritePin(GPIO_PIN_5, GPIO_PIN_RESET); // LD2(橙色)关闭
HAL_GPIO_WritePin(GPIO_PIN_2, GPIO_PIN_SET); // LD3(红色)关闭
}
break;
case LED_BLINK_FAST:
// 实现快速闪烁逻辑(使用LD2橙色LED)
for (int i = 0; i < 10; i++) {
HAL_GPIO_TogglePin(GPIO_PIN_5, GPIO_PIN_SET);
HAL_Delay(100);
}
break;
case LED_BLINK_SLOW:
// 实现慢速闪烁逻辑(使用LD2橙色LED)
for (int i = 0; i < 5; i++) {
HAL_GPIO_TogglePin(GPIO_PIN_5, GPIO_PIN_SET);
HAL_Delay(500);
}
break;
case LED_ALTERNATE_BLINK:
// 实现交替闪烁逻辑
for (int i = 0; i < 5; i++) {
HAL_GPIO_TogglePin(GPIO_PIN_1, GPIO_PIN_SET);
HAL_GPIO_TogglePin(GPIO_PIN_5, GPIO_PIN_SET);
HAL_Delay(300);
}
break;
}
}
// 初始化音频采集
void InitAudioCapture() {
if (HAL_ADC_Start(&hadc1)!= HAL_OK) {
handleError(ERROR_ADC_START);
}
}
// 生成WAV文件头
void generateWavHeader(FIL *file) {
uint32_t dataSize = 0;
uint32_t byteRate = SAMPLE_RATE * NUM_CHANNELS * (BITS_PER_SAMPLE / 8);
uint32_t blockAlign = NUM_CHANNELS * (BITS_PER_SAMPLE / 8);
// RIFF 块
const char riffHeader[] = {'R', 'I', 'F', 'F'};
f_write(file, riffHeader, sizeof(riffHeader), NULL);
f_write(file, &dataSize, sizeof(dataSize), NULL);
const char waveFormat[] = {'W', 'A', 'V', 'E'};
f_write(file, waveFormat, sizeof(waveFormat), NULL);
// fmt 子块
const char fmtHeader[] = {'f', 'm', 't', ' '};
f_write(file, fmtHeader, sizeof(fmtHeader), NULL);
const uint32_t fmtChunkSize = 16;
f_write(file, &fmtChunkSize, sizeof(fmtChunkSize), NULL);
const uint16_t audioFormat = 1;
f_write(file, &audioFormat, sizeof(audioFormat), NULL);
f_write(file, &NUM_CHANNELS, sizeof(NUM_CHANNELS), NULL);
f_write(file, &SAMPLE_RATE, sizeof(SAMPLE_RATE), NULL);
f_write(file, &byteRate, sizeof(byteRate), NULL);
f_write(file, &blockAlign, sizeof(blockAlign), NULL);
f_write(file, &BITS_PER_SAMPLE, sizeof(BITS_PER_SAMPLE), NULL);
// data 子块
const char dataHeader[] = {'d', 'a', 't', 'a'};
f_write(file, dataHeader, sizeof(dataHeader), NULL);
f_write(file, &dataSize, sizeof(dataSize), NULL);
}
// 更完善的按键防抖和长按检测
#define DEBOUNCE_COUNT 5
#define LONG_PRESS_TIME 1000 // 长按时间阈值(单位:毫秒)
uint8_t buttonDebounceCounter = 0;
uint32_t buttonPressStartTime = 0;
// 假设这里的 BUTTON_Pin 就是控制 B2 按键的引脚(PC13)
#define BUTTON_Pin GPIO_PIN_13
#define BUTTON_PORT GPIOC
uint8_t debounceButton(uint16_t GPIO_Pin) {
uint8_t currentState = HAL_GPIO_ReadPin(BUTTON_PORT, BUTTON_Pin); // 读取B2按键引脚状态
if (currentState == button.previousState) {
if (currentState == GPIO_PIN_SET) { // 按下为高电平
buttonDebounceCounter++;
if (buttonDebounceCounter >= DEBOUNCE_COUNT) {
if (HAL_GetTick() - buttonPressStartTime > LONG_PRESS_TIME) {
handleError(ERROR_LONG_PRESS);
return GPIO_PIN_SET; // 返回高电平表示长按
}
}
} else {
buttonDebounceCounter = 0;
buttonPressStartTime = HAL_GetTick();
}
} else {
buttonDebounceCounter = 0;
button.previousState = currentState;
}
return 0;
}
// 按键中断处理
void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin) {
if (GPIO_Pin == BUTTON_Pin && debounceButton(GPIO_Pin) == GPIO_PIN_SET) { // 检测到B2按下
switch (buttonAction) {
case BUTTON_PRESS_SHORT:
recording =!recording;
setLEDMode(recording? RECORDING_ON : RECORDING_OFF);
if (recording) {
SaveAudioToSDCard();
}
break;
default:
break;
}
}
}