一:理论基础
当任务1执行到第二步时被打断,此时开始执行任务2,最终打印结果为1,1.
二:代码
先说下遇到的bug:
1、main.c文件中最后一个任务打印大数据的代码
官方 :Serial_Printf("big_queue数据:%s\r\n",buf); 不可以正确打印,直接卡死
改正:Serial_Printf("big_queue数据:%s\r\n",&buf); 可以正确打印
2、大数据char buff[100]中的数据
char buff[100]={"1111"} 打印未报错,正确执行,但是1111的结尾有个方块不知道是啥
char buff[100]={"我"} 打印为报错,完美打印,没有方块,也没有乱码
char buff[100]={"我是大数据"} 只能打印前几个字,后面都是黑色方块,原因未知
代码:
key.c
#include "stm32f10x.h" // Device header
#include "Delay.h"
#include "FreeRTOS.h"
#include "task.h"
#include "Serial.h"
void Key_Init(void)
{
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
GPIO_InitTypeDef GPIO_InitStructure;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1 | GPIO_Pin_11;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOB, &GPIO_InitStructure);
}
uint8_t Key_GetNum(void)
{
uint8_t KeyNum = 0;
//当按键按下时,为低电平,进入if,因为是上拉模式,按下为低电平,松手为高电平
if (GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_1) == 0)
{
//按下的过程就像弹簧压缩一样,防止震荡,加个延时函数
vTaskDelay(10);
//松手时为上拉状态,此时为高电平,退出循环,
while (GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_1) == 0);
//防止震荡
vTaskDelay(10);
//给按键赋值
KeyNum = 1;
}
if (GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_11) == 0)
{
//按下的过程就像弹簧压缩一样,防止震荡,加个延时函数
vTaskDelay(10);
//松手时为上拉状态,此时为高电平,退出循环,
while (GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_11) == 0);
//防止震荡
vTaskDelay(10);
//给按键赋值
KeyNum = 2;
}
return KeyNum;
}
key.h
#ifndef __KEY_H
#define __KEY_H
void Key_Init(void);
uint8_t Key_GetNum(void);
#endif
main.c
#include "stm32f10x.h" // Device header
#include "Delay.h"
#include "LED.h"
#include "Key.h"
#include "OLED.h"
#include "Serial.h"
#include "FreeRTOS.h"
#include "task.h"
#include "Timer.h"
#include "queue.h"
QueueHandle_t key_queue;
QueueHandle_t big_queue;
char buff[100]={"我"};
//char buff[100]={"我是大数据"};
//char buff[100]={"11111"};
uint16_t Num=0;
#define START_STK_DEPTH 128
#define START_TASK_PRIO 1
TaskHandle_t start_task_handler;
void start_task(void * pvParameters);
#define LED2_STK_DEPTH 128
#define LED2_TASK_PRIO 2
TaskHandle_t led2_task_handler;
void led2_task(char * pvParameters);
#define LED3_STK_DEPTH 128
#define LED3_TASK_PRIO 3
TaskHandle_t led3_task_handler;
void led3_task(char * pvParameters);
#define LED4_STK_DEPTH 128
#define LED4_TASK_PRIO 4
TaskHandle_t led4_task_handler;
void led4_task(char * pvParameters);
int main(void)
{
Serial_Init();
Key_Init();
//队列创建
key_queue = xQueueCreate( 1, sizeof(uint8_t));
if(key_queue != NULL )
{
Serial_Printf("key_queue创建成功\r\n");
}
else
{
Serial_Printf("key_queue创建失败\r\n");
}
big_queue = xQueueCreate( 1, sizeof(char *));
if(key_queue != NULL )
{
Serial_Printf("big_queue创建成功\r\n");
}
else
{
Serial_Printf("big_queue创建失败\r\n");
}
xTaskCreate( (TaskFunction_t) start_task, //创建开始任务
(const char * ) "start_task",
(uint16_t ) START_STK_DEPTH,
(void * ) NULL,
(UBaseType_t ) START_TASK_PRIO,
(TaskHandle_t *) &start_task_handler);
vTaskStartScheduler(); //开启任务调度器
}
/*******开始任务函数*****/
void start_task(void * pvParameters)
{
taskENTER_CRITICAL();
xTaskCreate((TaskFunction_t) led2_task,
(const char * ) "led2_task",
(uint16_t ) LED2_STK_DEPTH,
(void * ) NULL,
(UBaseType_t ) LED2_TASK_PRIO,
(TaskHandle_t *) &led2_task_handler);
xTaskCreate((TaskFunction_t) led3_task,
(const char * ) "led3_task",
(uint16_t ) LED3_STK_DEPTH,
(void * ) NULL,
(UBaseType_t ) LED3_TASK_PRIO,
(TaskHandle_t *) &led3_task_handler);
xTaskCreate((TaskFunction_t) led4_task,
(const char * ) "led4_task",
(uint16_t ) LED4_STK_DEPTH,
(void * ) NULL,
(UBaseType_t ) LED4_TASK_PRIO,
(TaskHandle_t *) &led4_task_handler);
vTaskDelete(start_task_handler);
taskEXIT_CRITICAL();
}
//入队
void led2_task(char * pvParameters)
{
BaseType_t err=0;
char * buf;
buf=buff;
for(;;)
{
Num=Key_GetNum();
if(Num==1)
{
err = xQueueSend(key_queue,&Num,portMAX_DELAY);
if(err!=pdTRUE)
{
Serial_Printf("key_queue发送失败");
}
} else if(Num==2)
{
err = xQueueSend(big_queue,buf,portMAX_DELAY);
if(err!=pdTRUE)
{
Serial_Printf("big_queue发送失败");
}
}
vTaskDelay(10);
}
}
//如果当队列为空,此时xQueueReceive不执行,会将该任务从就绪态转为阻塞态,
//所以可以加延时函数也可以不加
//可以用我注释掉的那行代表测试queue是否有值
void led3_task(char * pvParameters)
{ uint8_t key_data=0;
BaseType_t err=0;
for(;;)
{
err = xQueueReceive(key_queue,&key_data,portMAX_DELAY);
//Serial_Printf("如果显示,代表未进入阻塞态");
if(err!=pdTRUE)
{
Serial_Printf("key_queue读取失败");
}
else
{
Serial_Printf("key_queue读取成功,数据:%d\r\n",key_data);
}
}
}
void led4_task(char * pvParameters)
{ char * buf;
BaseType_t err=0;
for(;;)
{
err = xQueueReceive(big_queue,&buf,portMAX_DELAY);
//Serial_Printf("如果显示,代表未进入阻塞态");
if(err!=pdTRUE)
{
Serial_Printf("big_queue读取失败");
}
else
{
Serial_Printf("big_queue数据:%s\r\n",&buf);
}
}
}
实验结果:
有知道是啥原因的大老可以留言,感谢