宏配置
configUSE_TICKLESS_IDLE 此宏要置為1表示啟用低功耗模式,在FreeRTOS.h檔案的708行
configEXPECTED_IDLE_TIME_BEFORE_SLEEP ,在FreeRTOS.h檔案的700行,此宏要置預設為2,其值不能小于2,否則低功耗時鐘節 拍太短沒有意義
main.c
#include "sys.h"
#include "delay.h"
#include "usart.h"
#include "led.h"
#include "beep.h"
#include "lcd.h"
#include "key.h"
#include <string.h>
#include "FreeRTOS.h"
#include "task.h"
#include "queue.h"
#include "semphr.h"
/************************************************
************************************************/
//LCD刷屏時使用的顔色
int lcd_discolor[14]={ WHITE, BLACK, BLUE, BRED,
GRED, GBLUE, RED, MAGENTA,
GREEN, CYAN, YELLOW,BROWN,
BRRED, GRAY };
#define START_TASK_PRIO 1 //任務優先級
#define START_STK_SIZE 256 //任務堆棧大小
TaskHandle_t StartTask_Handler; //任務句柄
void start_task(void *pvParameters); //任務函數
#define TASK1_TASK_PRIO 2 //任務優先級
#define TASK1_STK_SIZE 256 //任務堆棧大小
TaskHandle_t TASK1Task_Handler; //任務句柄
void task1_task(void *pvParameters); //任務函數
#define DATAPROCESS_TASK_PRIO 3 //任務優先級
#define DATAPROCESS_STK_SIZE 256 //任務堆棧大小
TaskHandle_t dataprocess_Handler; //任務句柄
void dataprocess_task(void *pvParameters); //任務函數
//二值信号量句柄
SemaphoreHandle_t BinarySemaphore;//二值信号量句柄
//用于指令解析用的指令值
#define LED1ON 1
#define LED1OFF 2
#define BEEPON 3
#define BEEPOFF 4
#define COMMANDERR 0xff
//進入低功耗模式前需要處理的事情
//ulExpectedIdleTime:低功耗模式運作時間
void PreSleepProcessing(uint32_t ulExpectedIdleTime)
{
//關閉某些低功耗模式下不使用的外設時鐘,因為A端口上要用序列槽,所能不關閉
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB,DISABLE);
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOC,DISABLE);
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOD,DISABLE);
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOE,DISABLE);
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOF,DISABLE);
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOG,DISABLE);
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOH,DISABLE);
}
//退出低功耗模式以後需要處理的事情
//ulExpectedIdleTime:低功耗模式運作時間
void PostSleepProcessing(uint32_t ulExpectedIdleTime)
{
//退出低功耗模式以後打開被關閉的外設時鐘
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB,ENABLE);
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOC,ENABLE);
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOD,ENABLE);
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOE,ENABLE);
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOF,ENABLE);
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOG,ENABLE);
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOH,ENABLE);
}
//将字元串的小寫字母轉換為大寫
//str:要轉換的字元串
//len:字元串長度
void LowerToCap(u8* str,u8 len)
{
u8 i;
for(i=0;i<len;i++)
{
if((96<str[i])&&(str[i]<123))//小寫字母
str[i]=str[i]-32;
}
}
//指令處理函數,将字元串指令轉換成指令值
//str:指令
//傳回值:0xff ,指令錯誤 ,其他值,指令值
u8 CommandProcess(u8 *str)
{
u8 CommandValue=COMMANDERR;
if(strcmp((char*)str,"LED1ON")==0)CommandValue=LED1ON;
else if(strcmp((char*)str,"LED1OFF")==0)CommandValue=LED1OFF;
else if(strcmp((char*)str,"BEEPON")==0)CommandValue=BEEPON;
else if(strcmp((char*)str,"BEEPOFF")==0)CommandValue=BEEPOFF;
return CommandValue;
}
int main(void)
{
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_4);//設定系統中斷優先級分組4
delay_init(168); //初始化延時函數
uart_init(115200); //初始化序列槽
LED_Init(); //初始化LED端口
//KEY_Init();
BEEP_Init();
//LCD_Init();
/*
POINT_COLOR=RED;
LCD_ShowString(10,10,200,16,16,"STM32F407");
LCD_ShowString(10,30,200,16,16,"FREERTOS 13.1");
LCD_ShowString(10,50,200,16,16,"Binary Semaphore");
LCD_ShowString(10,70,220,16,16,"Command data:");
*/
//my_mem_init(SRAMIN); //初始化内部記憶體池
//建立開始任務
xTaskCreate((TaskFunction_t )start_task, //任務函數
(const char* )"start_task", //任務名稱
(uint16_t )START_STK_SIZE, //任務堆棧大小
(void* )NULL, //傳遞給任務函數的參數
(UBaseType_t )START_TASK_PRIO, //任務優先級
(TaskHandle_t* )&StartTask_Handler); //任務句柄
vTaskStartScheduler(); //開啟任務排程
}
//開始任務任務函數
void start_task(void *pvParameters)
{
taskENTER_CRITICAL(); //進入臨界區
//建立二值信号量
BinarySemaphore=xSemaphoreCreateBinary();
//建立TASK1任務
xTaskCreate((TaskFunction_t )task1_task,
(const char* )"task1_task",
(uint16_t )TASK1_STK_SIZE,
(void* )NULL,
(UBaseType_t )TASK1_TASK_PRIO,
(TaskHandle_t* )&TASK1Task_Handler);
//建立dataprocess任務
xTaskCreate((TaskFunction_t )dataprocess_task,
(const char* )"dataprocess_task",
(uint16_t )DATAPROCESS_STK_SIZE,
(void* )NULL,
(UBaseType_t )DATAPROCESS_TASK_PRIO,
(TaskHandle_t* )&dataprocess_Handler);
vTaskDelete(StartTask_Handler); //删除開始任務
taskEXIT_CRITICAL(); //退出臨界區
}
//TASK1任務函數
void task1_task(void *pvParameters)
{
while(1)
{
LED0=~LED0;
vTaskDelay(500);
}
}
//
//
//
void dataprocess_task(void *pvParameters)
{
u8 len=0;
u8 CommandValue=COMMANDERR;
BaseType_t err=pdFALSE;
u8* CommandStr;
//POINT_COLOR=BLUE;
while(1)
{
if(BinarySemaphore !=NULL)
{
err=xSemaphoreTake(BinarySemaphore,portMAX_DELAY);
if(err==pdTRUE) //擷取信号量成功
{
len=USART_RX_STA&0x3fff; //得到此次連接配接到的資料長度
CommandStr=USART_RX_BUF;
CommandStr[len]='\0';
LowerToCap(CommandStr,len);
CommandValue=CommandProcess(CommandStr);
if(CommandValue != COMMANDERR)//收到正确指令
{
//LCD_Fill(10,90,210,110,WHITE);
//LCD_ShowString(10,90,200,16,16,CommandStr);
printf("指令為:%s \r\n",CommandStr);
switch(CommandValue)
{
case LED1ON: LED1=0;break;
case LED1OFF: LED1=1;break;
case BEEPON: BEEP=1;break;
case BEEPOFF: BEEP=0;break;
default:break;
}
}
else
{
printf("無效指令,請重新輸入\r\n");
}
USART_RX_STA=0;
}
else if(err==pdFALSE)
{
vTaskDelay(10);
}
}
}
}