StmF103C8T6标准库使用FreeRtos----队列

一:理论基础

当任务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);
		}
	}
}

实验结果:

 

 

 

有知道是啥原因的大老可以留言,感谢 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值