天天看點

FreeRTOS tickless低功耗模式

宏配置

 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);
				}
	
			}
			
		}

}


           

繼續閱讀