新手上路
- 积分
- 38
- 金钱
- 38
- 注册时间
- 2018-8-19
- 在线时间
- 3 小时
|
5金钱
笔者正在学习STM32F407开发板,使用FreeRTOS并开启低功耗模式,代码与原子哥提供的大同小异,唯一的就是没有开启时间统计功能。
开发板下载完程序后,程序可以运行,而且运行正常,但一旦按下按键触发外部中断,LED要么一直亮,要么一直灭。
最终确认为开发板或操作系统死机,而且并未输出错误信息,不知是否有人碰到此问题。
主函数文件如下:
#include "Led.h"
#include "Key.h"
#include "FreeRTOS.h"
#include "task.h"
#include "io.h"
#include "ticks.h"
#include "queue.h"
#include "semphr.h"
#include "string.h"
/************************************************
FreeRTOS低功耗Tickless模式
************************************************/
/************************************************
需要设置configUSE_TICKLESS_IDLE为1,同时实现函PreSleepProcessing和PostSleepProcessing
可以频繁进出低功耗模式,但是在触发外部中断时死机,原因不明,慎用!!!
慎用!!!慎用!!!慎用!!!慎用!!!慎用!!!慎用!!!慎用!!!慎用!!!
************************************************/
//任务优先级
#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
int main(void)
{
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_4);//设置系统中断优先级分组4
OS_Ticks_Init(); //初始化延时函数
OS_IO_Init(9600,1,1); //初始化串口
Led_Init(); //初始化LED端口
Key_Init(1,2,0); //初始化按键1,中断优先级2
Key_Init(2,2,0); //初始化按键
Clean_Key(1);
Clean_Key(2);
//创建开始任务
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);
//创建TASK2任务
xTaskCreate((TaskFunction_t )DataProcess_task,
(const char* )"keyprocess_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)
{
static u8 sta1=0;
while(1)
{
if(sta1)
Led_Off(1);
else
Led_On(1);
sta1=!sta1;
if(Read_Key(1))
{
if(BinarySemaphore!=NULL)
xSemaphoreGive(BinarySemaphore); //释放二值信号量
Clean_Key(1);
}
vTaskDelay(20); //延时10,10个时钟节拍
}
}
//DataProcess_task函数
void DataProcess_task(void *pvParameters)
{
BaseType_t err=pdFALSE;
static u8 sta2=0;
while(1)
{
if(BinarySemaphore!=NULL)
{
err=xSemaphoreTake(BinarySemaphore,portMAX_DELAY); //获取信号量
if(err==pdTRUE) //获取信号量成功
{
sta2=!sta2;
}
}
else if(err==pdFALSE)
{
vTaskDelay(10); //延时10ms,也就是10个时钟节拍
}
if(sta2)
Led_On(2);
else
Led_Off(2);
}
}
//进入低功耗模式前需要处理的事情
//ulExpectedIdleTime:低功耗模式运行时间
void PreSleepProcessing(uint32_t ulExpectedIdleTime)
{
printf("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)
{
printf("b");
//退出低功耗模式以后打开那些被关闭的外设时钟
// 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);
}
|
最佳答案
查看完整内容[请看2#楼]
问题已经解决了,就是在按键中断里为了消除抖动使用了延时函数,延时函数使用的是滴答计时器完成的。。。。。。
该问题已经解决,原因不在于外部中断,而是在按键中断中使用了滴答计时器做延时来消抖,但滴答计时器已关闭,所以直接死机
目前解决此问题的方式是条件编译,即不使用低功耗模式下才编译那部分延时,这部分功能需在后期进行完善。
|