void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef *hadc){
if(hadc->Instance == ADC1){
//adc_value在/* USER CODE BEGIN Variables */处声明
adc_value = HAL_ADC_GetValue(hadc);
//printf("ADC Conversion Completed!\r\n");
BaseType_t highter_priority_task_woken = pdFALSE;
if(BinarySem_DataReadyHandle != NULL){// 确保信号量已创建
// 释放信号量,通知显示任务数据已准备好
xSemaphoreGiveFromISR(BinarySem_DataReadyHandle, &highter_priority_task_woken);
portYIELD_FROM_ISR(highter_priority_task_woken);
}
}
}void App_Task_showADC(void *argument)
{
/* USER CODE BEGIN App_Task_showADC */
/* Infinite loop */
for(;;)
{
// 等待数据准备就绪
if(xSemaphoreTake(BinarySem_DataReadyHandle, portMAX_DELAY) == pdTRUE){
// 数据已准备好,继续执行
// 显示ADC值
char adc_str[16];
// 格式化输出,保留4位
snprintf(adc_str, sizeof(adc_str), "%04lu", adc_value);
lcd_dma2d_show_eubf_str(0, 64,(char*)"ADC Value:", "ZCOOL QingKe HuangYou", 32, WHITE);
lcd_dma2d_fill(0, 64, 320, 98, BLACK);
lcd_dma2d_show_eubf_str(0, 96,(char*)adc_str, "ZCOOL QingKe HuangYou", 32, WHITE);
lcd_dma2d_update_screen();
osDelay(1);
}
else{
// 数据未准备好,等待
}
osDelay(250);
}
/* USER CODE END App_Task_showADC */
}void HAL_RTCEx_WakeUpTimerEventCallback(RTC_HandleTypeDef *hrtc){
// 这里添加RTC唤醒事件处理代码
//释放计数信号量
if(CountingSem_TableHandle != NULL){ // 确保信号量已创建
BaseType_t highter_priority_task_woken = pdFALSE;
xSemaphoreGiveFromISR(CountingSem_TableHandle, &highter_priority_task_woken);
portYIELD_FROM_ISR(highter_priority_task_woken);
}
}void App_Task_CheckIn(void *argument)
{
/* USER CODE BEGIN App_Task_CheckIn */
char temp_str[30];
UBaseType_t last_count = 0xFFFFFFFF;
UBaseType_t current_count = 0;
osDelay(1500); //必须要有这个等待,否则会因为文件系统未挂载导致字体文件无法读取
sprintf(temp_str, "%lu", uxSemaphoreGetCount(CountingSem_TableHandle));
// 第一行:Y=32 (0~32)
lcd_dma2d_show_eubf_str(160, 32, (char*)"TOTAL_TABLE:", "ZCOOL QingKe HuangYou", 25, WHITE);
// 第二行:Y=64 (32~64)
lcd_dma2d_show_eubf_str(160, 64, temp_str, "ZCOOL QingKe HuangYou", 32, WHITE);
// 第三行:Y=96 (64~96)
lcd_dma2d_show_eubf_str(160, 96, (char*)"AVAILABLE:", "ZCOOL QingKe HuangYou", 32, WHITE);
// 第一次推送到屏幕
lcd_dma2d_update_screen();
/* Infinite loop */
for(;;)
{
// 按键处理
if(myGetKeyPressStateByID(KEY_UP)){
// 清除第五行 (占据 128~160)
lcd_dma2d_fill(160, 128, 320, 160+1, BLACK);
if(xSemaphoreTake(CountingSem_TableHandle, 100) == pdTRUE){
lcd_dma2d_show_eubf_str(160, 160, (char*)"CheckIn OK", "ZCOOL QingKe HuangYou", 25, GREEN);
} else {
lcd_dma2d_show_eubf_str(160, 160, (char*)"CheckIn Failed", "ZCOOL QingKe HuangYou", 25, RED);
}
lcd_dma2d_update_screen();
}
// 按需刷新
current_count = uxSemaphoreGetCount(CountingSem_TableHandle);
if(current_count != last_count)
{
sprintf(temp_str, "%lu", (unsigned long)current_count);
// 清除第四行 (占据 96~128)
lcd_dma2d_fill(160, 96, 320, 128+1, BLACK);
// 绘制第四行数字
lcd_dma2d_show_eubf_str(160, 128, temp_str, "ZCOOL QingKe HuangYou", 32, WHITE);
lcd_dma2d_update_screen();
last_count = current_count;
}
osDelay(100);
}
/* USER CODE END App_Task_CheckIn */
}有点好笑的是,RTC 唤醒属于拓展功能, 因此,所有相关的函数和回调都会带有 Ex 的后缀,而不是 x。然后我一开始就给拼错了,死活找不到 BUG。
创建一个二值信号量token,初始可用。
void App_Task_High(void *argument)
{
/* USER CODE BEGIN App_Task_High */
/* Infinite loop */
for(;;)
{
if(xSemaphoreTake(tokenHandle,portMAX_DELAY) == pdTRUE){
printf("HIGH TAKE IT!\r\n");
HAL_Delay(10);
xSemaphoreGive(tokenHandle);
}
osDelay(1);
}
/* USER CODE END App_Task_High */
}void App_Task_Middle(void *argument)
{
/* USER CODE BEGIN App_Task_Middle */
/* Infinite loop */
for(;;)
{
printf("MIDDLE IS RUNING...\r\n");
HAL_Delay(10);
osDelay(500);
}
/* USER CODE END App_Task_Middle */
}void App_Task_Low(void *argument)
{
/* USER CODE BEGIN App_Task_Low */
/* Infinite loop */
for(;;)
{
if(xSemaphoreTake(tokenHandle,pdMS_TO_TICKS(300)) == pdTRUE){
// 成功获取到 token,执行临界区代码
printf("LOW TAKE IT!\r\n");
HAL_Delay(1000);
printf("LOW GIVE IT!\r\n");
HAL_Delay(10);
xSemaphoreGive(tokenHandle); // 释放 token
} else {
// 获取 token 失败,可能被 Task_High 占用
}
osDelay(20);
}
/* USER CODE END App_Task_Low */
}把信号量删掉,创建一个同名的互斥量,代码不变。