#include "bsp_flash_log.h"
#include "Reg_RW.h"
#include "LDChip.h"
#include "bsp_beep.h"
#include <stdint.h>
#include <stdbool.h>
#include <stdio.h>
#include <string.h>
#include "bsp_ili9341_lcd.h"
#include "bsp_color_led.h"
#include "usart.h"
#include "delay.h"
#include "bsp_spi_flash.h"
#include "bsp_usart.h" // 包含 USART_Config 声明
#include "remind.h"
#include "bsp_SysTick.h"
#include "stm32f10x_it.h" // 包含 SysTick_Handler 声明
#define MAX_TASKS 10
#define CMD_BUFFER_SIZE 64
// 全局变量声明
u8 nAsrStatus = LD_ASR_NONE; // 语音识别状态
u8 nAsrRes = 0; // 语音识别结果
u8 flag = 0; // 通用标志位
volatile uint32_t ms_count = 0; // 毫秒计数器 - 添加volatile关键字
uint8_t needStartASR = 1;
bool lcdState_changed = true ;
// 外部变量
//extern uint32_t log_count; // 日志条目计数
//extern uint32_t log_bytes_written; // 日志已写字节数
// 天气信息结构体
typedef struct {
char condition[16]; // 天气状况
int8_t temperature; // 温度
} WeatherInfo;
// LCD显示状态枚举
typedef enum {
LCD_SHOW_MENU, // 显示主菜单
LCD_SHOW_TASK, // 显示任务列表
LCD_SHOW_WEATHER // 显示天气信息
} LCD_State;
// 全局数据结构
Task taskList[MAX_TASKS]; // 任务列表
uint8_t taskCount = 0; // 任务计数
WeatherInfo todayWeather; // 当天天气信息
LCD_State lcdState = LCD_SHOW_MENU; // 当前LCD状态
Time global_time = {17, 27}; // 全局时间(初始值)
char cmd_buffer[CMD_BUFFER_SIZE]; // 串口命令缓冲区
uint16_t cmd_index = 0; // 命令缓冲区索引
/*-------------------------- 函数声明 --------------------------*/
// 串口通信
void UART_SendData(uint8_t* data, uint16_t len);
void LOG_ProcessCommand(char* cmd);
void LOG_EnhancedRxHandler(uint8_t* data, uint16_t len);
// 任务管理
bool is_overlap(Time a_start, Time a_end, Time b_start, Time b_end);
bool add_task(Task *newTask);
void check_and_remind(Time now);
// LCD显示
void LCD_ShowTask(Task* pTask, uint8_t y);
void LCD_ShowWeather(WeatherInfo* pWeather, uint8_t y);
// 语音识别
void User_Modification(u8 dat);
/*-------------------------- 函数实现 --------------------------*/
// 串口发送数据
void UART_SendData(uint8_t* data, uint16_t len) {
for(uint16_t i = 0; i < len; i++) {
USART_SendData(USART1, data[i]);
while(USART_GetFlagStatus(USART1, USART_FLAG_TXE) == RESET);
}
}
// 处理串口命令
void LOG_ProcessCommand(char* cmd) {
if(strcmp(cmd, "READLOG") == 0) {
printf("Sending log via UART...\r\n");
LOG_SendToSerial(UART_SendData);
printf("Log transfer complete.\r\n");
}
else if(strcmp(cmd, "CLEARLOG") == 0) {
LOG_Clear();
printf("Log cleared.\r\n");
}
else if(strcmp(cmd, "STATUS") == 0) {
//printf("Log entries: %lu, Size: %lu bytes\r\n", log_count, log_bytes_written);
}
else if(strcmp(cmd, "HELP") == 0) {
printf("Available commands:\r\n");
printf("READLOG - Send log via UART\r\n");
printf("CLEARLOG - Clear log file\r\n");
printf("STATUS - Show log status\r\n");
printf("TASKS - List current tasks\r\n");
printf("WEATHER - Show weather info\r\n");
printf("ADDTASK - Add new task\r\n");
printf("DELTASK - Delete task\r\n");
}
else if(strcmp(cmd, "TASKS") == 0) {
printf("Current tasks:\r\n");
for(uint8_t i = 0; i < taskCount; i++) {
printf("%d. %02d:%02d-%02d:%02d %s (P%d)\r\n",
i+1,
taskList[i].start.hour, taskList[i].start.min,
taskList[i].end.hour, taskList[i].end.min,
taskList[i].name, taskList[i].priority);
}
}
else if (strncmp(cmd, "ADDTASK ", 8) == 0) {
int h1, m1, h2, m2, pri;
char name[16];
if (sscanf(cmd + 8, "%d %d %d %d %d %15s",
&h1, &m1, &h2, &m2, &pri, name) == 6) {
Task newTask = {
.start = {.hour = (uint8_t)h1, .min = (uint8_t)m1},
.end = {.hour = (uint8_t)h2, .min = (uint8_t)m2},
.priority = (uint8_t)pri,
.reminderSet = false
};
strncpy(newTask.name, name, sizeof(newTask.name));
if (add_task(&newTask)) {
printf("Task added: %s\r\n", name);
Remind_SetTaskList(taskList, taskCount); // 更新提醒模块
} else {
printf("Add task failed: overlap or full\r\n");
}
} else {
printf("Invalid ADDTASK format\r\n");
}
}
else if (strncmp(cmd, "DELTASK ", 8) == 0) {
int index;
if (sscanf(cmd + 8, "%d", &index) == 1) {
if (index >= 1 && index <= taskCount) {
printf("Deleting task %d: %s\r\n", index, taskList[index-1].name);
// 移动后续任务
for (uint8_t i = index-1; i < taskCount-1; i++) {
taskList[i] = taskList[i+1];
}
taskCount--;
Remind_SetTaskList(taskList, taskCount); // 更新提醒模块
} else {
printf("Invalid task index\r\n");
}
} else {
printf("Invalid DELTASK format\r\n");
}
}
else if(strcmp(cmd, "WEATHER") == 0) {
printf("Weather: %s, %dC\r\n", todayWeather.condition, todayWeather.temperature);
}
else {
printf("Unknown command: %s\r\n", cmd);
printf("Type 'HELP' for available commands.\r\n");
}
}
// 串口接收处理
void LOG_EnhancedRxHandler(uint8_t* data, uint16_t len) {
for(uint16_t i = 0; i < len; i++) {
// 处理回车/换行(命令结束)
if(data[i] == '\r' || data[i] == '\n') {
if(cmd_index > 0) {
cmd_buffer[cmd_index] = '\0';
LOG_ProcessCommand(cmd_buffer);
cmd_index = 0;
}
continue;
}
// 处理退格/删除
if(data[i] == 0x08 || data[i] == 0x7F) {
if(cmd_index > 0) {
cmd_index--;
}
continue;
}
// 存储有效字符
if(cmd_index < (CMD_BUFFER_SIZE - 1) && data[i] >= 32 && data[i] <= 126) {
cmd_buffer[cmd_index++] = data[i];
}
}
}
// 检查时间重叠
bool is_overlap(Time a_start, Time a_end, Time b_start, Time b_end) {
if ((a_end.hour < b_start.hour) ||
(a_end.hour == b_start.hour && a_end.min <= b_start.min) ||
(a_start.hour > b_end.hour) ||
(a_start.hour == b_end.hour && a_start.min >= b_end.min))
return false;
return true;
}
// 添加任务
bool add_task(Task *newTask) {
// 检查时间重叠
for (uint8_t i = 0; i < taskCount; i++) {
if (is_overlap(newTask->start, newTask->end, taskList[i].start, taskList[i].end)) {
return false;
}
}
// 添加到任务列表
if (taskCount < MAX_TASKS) {
taskList[taskCount++] = *newTask;
return true;
}
return false;
}
// 显示任务信息
void LCD_ShowTask(Task* pTask, uint8_t y) {
char buf[32];
sprintf(buf, "%02d:%02d~%02d:%02d %-10s P%d",
pTask->start.hour, pTask->start.min,
pTask->end.hour, pTask->end.min,
pTask->name, pTask->priority);
ILI9341_DispString_EN(0, y, buf);
}
// 显示天气信息
void LCD_ShowWeather(WeatherInfo* pWeather, uint8_t y) {
char buf[32];
sprintf(buf, "Weather:%-7s %2dC", pWeather->condition, pWeather->temperature);
ILI9341_DispString_EN(0, y, buf);
}
// 语音识别处理
void User_Modification(u8 dat) {
if(dat == CODE_1KL1) { // "任务"命令
lcdState = LCD_SHOW_TASK;
lcdState_changed = true; // 标记状态改变
printf("CMD: Show tasks\r\n");
}
else if(dat == CODE_1KL2) { // "天气"命令
lcdState = LCD_SHOW_WEATHER;
lcdState_changed = true; // 标记状态改变
printf("CMD: Show weather\r\n");
}
else { // 未知命令
lcdState = LCD_SHOW_MENU;
lcdState_changed = true; // 标记状态改变
printf("CMD: Unknown voice command\r\n");
}
}
/*-------------------------- 主函数 --------------------------*/
int main(void) {
// 系统初始化(最先执行)
SystemInit();
// 延时初始化(在其他模块之前)
delay_init();
// 中断优先级分组
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
// SysTick初始化(1ms中断)- 重要!
if (SysTick_Config(SystemCoreClock / 1000)) { // 配置为1ms中断
while (1); // 配置失败时死循环
}
// 硬件初始化
COLOR_TIMx_LED_Init(); // RGB灯初始化
BEEP_GPIO_Config(); // 蜂鸣器初始化
// 串口和日志初始化
USART_Config(); // 串口初始化
LOG_Init(); // 日志系统初始化
// LCD初始化
ILI9341_Init(); // LCD初始化
ILI9341_Clear(0, 0, LCD_X_LENGTH, LCD_Y_LENGTH); // 清屏
// 语音识别初始化
LD3320_Init();
EXTIX_Init();
LD_Reset();
nAsrStatus = LD_ASR_NONE; // 初始状态:没有在作ASR
SCS = 0;
// 启用串口中断
USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);
NVIC_EnableIRQ(USART1_IRQn);
// 初始化天气信息
strcpy(todayWeather.condition, "Sunny");
todayWeather.temperature = 25;
// 创建示例任务
Task task1 = {{17, 38}, {17, 39}, 1, "Meeting", false};
Task task2 = {{17, 39}, {17, 40}, 2, "Study", false};
Task task3 = {{17, 40}, {17, 41}, 3, "Exercise", false};
add_task(&task1);
add_task(&task2);
add_task(&task3);
Remind_SetTaskList(taskList, taskCount);
// 系统启动信息
printf("System started!\r\n");
printf("Type 'HELP' for command list\r\n");
// 非阻塞计时变量
uint32_t last_time_update = ms_count;
uint32_t last_remind_check = ms_count;
uint32_t last_lcd_refresh = ms_count;
uint32_t last_debug = ms_count; // 调试用
// 主循环
while (1) {
// ===== 1. 唯一的ASR流程控制逻辑,放在主循环顶部 ======
switch(nAsrStatus) {
case LD_ASR_NONE:
if (needStartASR) {
nAsrStatus = LD_ASR_RUNING;
if (RunASR() == 0) {
nAsrStatus = LD_ASR_ERROR;
}
needStartASR = 0;
}
break;
case LD_ASR_FOUNDOK:
nAsrRes = LD_GetResult();
printf("Voice recognition result: %d\r\n", nAsrRes); // 调试输出
User_Modification(nAsrRes);
nAsrStatus = LD_ASR_NONE;
needStartASR = 1;
break;
case LD_ASR_ERROR:
LD_Reset();
nAsrStatus = LD_ASR_NONE;
printf("Voice module reset due to error\r\n");
needStartASR = 1;
break;
default:
// 其他状态保持
break;
}
// 获取当前时间
uint32_t current_ms = ms_count;
// 调试输出 - 每秒输出一次ms_count值
if(current_ms - last_debug >= 1000) {
last_debug = current_ms;
printf("Debug - ms_count: %lu, ASR status: %d\r\n", current_ms, nAsrStatus);
}
// 2. 非阻塞时间更新(每分钟更新)
if(current_ms - last_time_update >= 60000) { // 1分钟
last_time_update = current_ms;
global_time.min++;
if(global_time.min >= 60) {
global_time.min = 0;
global_time.hour++;
if(global_time.hour >= 24)
global_time.hour = 0;
}
// 每分钟记录一次时间
printf("Current time: %02d:%02d\r\n", global_time.hour, global_time.min);
}
// 3. 任务提醒检查(每10秒检查)
if(current_ms - last_remind_check >= 10000) { // 10秒
last_remind_check = current_ms;
Remind_CheckAndDo(global_time);
}
// 4. LCD显示更新(每秒刷新或状态变化时刷新)
if(current_ms - last_lcd_refresh >= 1000 || lcdState_changed) {
last_lcd_refresh = current_ms;
if(lcdState_changed) {
lcdState_changed = false;
ILI9341_Clear(0, 0, LCD_X_LENGTH, LCD_Y_LENGTH); // 清屏
}
// 显示当前时间
char time_buf[16];
sprintf(time_buf, "Time: %02d:%02d", global_time.hour, global_time.min);
ILI9341_DispString_EN(0, 0, time_buf);
switch(lcdState) {
case LCD_SHOW_MENU:
ILI9341_DispString_EN(0, 20, "Voice Control Ready");
ILI9341_DispString_EN(0, 40, "Say 'Task' or 'Weather'");
break;
case LCD_SHOW_TASK:
for(uint8_t i = 0; i < taskCount; i++) {
LCD_ShowTask(&taskList[i], 20 + i*20);
}
break;
case LCD_SHOW_WEATHER:
LCD_ShowWeather(&todayWeather, 20);
break;
}
}
// 短延时 - 注意函数名
Delay_ms(10); // 改为10ms,减少CPU占用
}
}
// 添加文件结束符,确保最后一行有换行
为什么输出后是白屏
最新发布