天天看点

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

}


           

继续阅读