Stm32 freertos队列串口缓冲区的使用

2023-05-16

main.c

 

#include "Config.h"
#include "Command.h"	
#include "Control.h"
#include "bsp.h"
#include "delay.h"
#include "24C512.h"
#include "FreeRTOS.h"
#include "task.h"
#include "queue.h"
//==================================================
//任务优先级
#define START_TASK_PRIO		1
//任务堆栈大小	
#define START_STK_SIZE 		128  
//任务句柄
TaskHandle_t StartTask_Handler;
//任务函数
void start_task(void *pvParameters);

//任务优先级
#define LED1_TASK_PRIO		1
//任务堆栈大小	
#define LED1_STK_SIZE 		50  
//任务句柄
TaskHandle_t LED1Task_Handler;
//任务函数
void Led1_task(void *pvParameters);

//任务优先级
#define KEY_TASK_PRIO		1
//任务堆栈大小	
#define KEY_STK_SIZE 		50  
//任务句柄
TaskHandle_t KEYTask_Handler;
//任务函数
void Key_task(void *pvParameters);


//任务优先级
#define uart1_process_TASK_PRIO		1
//任务堆栈大小	
#define uart1_process_task_STK_SIZE 		128
//任务句柄
TaskHandle_t uart1_process_Task_Handler;
//任务函数
void uart1_process_task(void const *pvParameters);

QueueHandle_t Rx_Message_Queue; //信息队列句柄,用来传递串口接收到的数据
#define MESSAGE_Q_NUM   1000  //接收数据的消息队列的数量 (本实验这里指的是可存储连续10条串口指令)  改大可以缓解大数据量的吞吐
//==================================================
int main(void)
{  
	BSP_Init();//Board Init,板级初始化
	System_init();
	//init_config();//调取eeprom参数
		//创建任务
   	//创建开始任务
    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();                              //开启任务调度
	while(1);
	

}


//
void start_task(void *pvParameters)
{
    taskENTER_CRITICAL();           //进入临界区
	  //Tx_Message_Queue=xQueueCreate(MESSAGE_Q_NUM,sizeof(u8));
	  Rx_Message_Queue=xQueueCreate(MESSAGE_Q_NUM,sizeof(u8));//MESSAGE_Q_NUM队列的队列长度,这里是队列的项目数,队列中每个项目(消息)的长度,单位为字节
    //
    xTaskCreate((TaskFunction_t )Led1_task,     	
                (const char*    )"led1_task",   	
                (uint16_t       )LED1_STK_SIZE, 
                (void*          )NULL,				
                (UBaseType_t    )LED1_TASK_PRIO,	
                (TaskHandle_t*  )&LED1Task_Handler);   
    
    xTaskCreate((TaskFunction_t )Key_task,     
                (const char*    )"KEY_task",   
                (uint16_t       )KEY_STK_SIZE, 
                (void*          )NULL,
                (UBaseType_t    )KEY_TASK_PRIO,
                (TaskHandle_t*  )&KEYTask_Handler);   							
    //
    xTaskCreate((TaskFunction_t )uart1_process_task,     
                (const char*    )"uart1_process_task",   
                (uint16_t       )uart1_process_task_STK_SIZE, 
                (void*          )NULL,
                (UBaseType_t    )uart1_process_TASK_PRIO,
                (TaskHandle_t*  )&uart1_process_Task_Handler);  
													
    vTaskDelete(StartTask_Handler); //删除开始任务
    taskEXIT_CRITICAL();            //退出临界区
}
//
void Led1_task(void *pvParameters)
{
    while(1)
    {
      //GPIO_WriteBit(GPIOC, GPIO_Pin_13, (BitAction)(1 - GPIO_ReadOutputDataBit(GPIOC, GPIO_Pin_13)));
			LED1_ON();
			vTaskDelay(500);
			LED1_OFF();
			vTaskDelay(500);
    }
}   


void Key_task(void *pvParameters)
{
    while(1){
			Key_Scan();
		}
}

//
#define MY_CMD_SIZE 0x0a
enum input_stat
{
	NULL__=0,
	WATI_NORMAL,
	WATI_FUNCTION,
	
};
struct my_shell
{
	enum input_stat stat;
	char line[MY_CMD_SIZE];
	uint8_t line_position;//队头
	uint8_t line_curpos;//队尾
};

struct my_shell  _shell,*shell;
//
void uart1_process_task(void const *pvParameters)
{
	uint8_t ch;
	shell=&_shell;//结构体指针指向结构体变量
	while(1)
	{
//		 if( USARTStructure2.RX_Flag==1 ){                    /*If receive the command*/
//			  USARTStructure2.RX_Flag=0;									 //清标志位 
//			  USARTStructure2.RX_TMEP_Len=0;
//				USARTStructure2.RX_Len=0;
//			  Command_exec((char*)USARTStructure2.RX_TEMP_BUFF);
//			  //Check2((char *)USARTStructure2.RX_TEMP_BUFF);  /*Run the action*/ 
//		  }
		while(xQueueReceive( Rx_Message_Queue, &ch, 10 ) != pdPASS){//没有收到数据继续读,读到就跳出执行163行后面程序,(读取队列Rx_Message_Queue过程中把读到的数据拷贝到ch缓冲区中,读取成功以后就会将队列中的这条数据删除)
			   if (shell->line_curpos == 0)//一条正确格式的指令后就会清0 看182行
         continue;//继续执行155行
				 shell->line_position--;                   //频繁接收出错(shell->line_curpos!=0) 队头指针回0位置 正常不会执行到这里
         shell->line_curpos--;                     //队尾指针回0位置
         shell->line[shell->line_position]= 0;     //出错清除shell队列里面内容

				 
		}
		if(ch=='\r'){
			char next;
			if(xQueueReceive( Rx_Message_Queue , &next, 10 ) == pdPASS){//如果队列读取成功
				if(next=='\0'){
					ch='\r';
				}
				else {
					ch=next;//正常带\r\n的指令 解析\r的时候执行到这儿	ch=0x0A 接着执行178行
				}					
			}
			else{
				ch='\r';//如果队列读取失败
			}
			
		}
		 /* handle end of line, break  处理命令行结尾*/
		if (ch == '\r' || ch == '\n'){
			Command_exec(shell->line); //解析队列里面的内容
			memset(shell->line, 0, sizeof(shell->line));
			shell->line_curpos = shell->line_position = 0;//初始化为0位置
			continue;//跳转到146行
		}
		 /* it's a large line, discard it 命令行太长*/
		if (shell->line_position>=MY_CMD_SIZE)//判断是否是长指令
		{
				shell->line_position = 0;
				shell->line_curpos = 0;
		}
		shell->line[shell->line_position] = ch;//把指令存到缓冲区里面
		ch=0;//接收数据变量清0
		shell->line_position++; //收到数据队头指针向后移一位
		shell->line_curpos++;   //收到数据队尾指针向后移一位
	}
}

uart2.c

extern QueueHandle_t Rx_Message_Queue;
unsigned char uart2_data;

void USART2_IRQHandler(void)
{  
	BaseType_t xHigherPriorityTaskWoken=pdFALSE;
	BaseType_t err;
	if(USART_GetITStatus(USART2, USART_IT_RXNE) == SET)				// 串口接收数据触发中断
	{
		USART_ClearITPendingBit(USART2, USART_IT_RXNE);					//清空接收中断标志			
		uart2_data=USART_ReceiveData(USART2);
	  err=xQueueSendFromISR(Rx_Message_Queue,&uart2_data,&xHigherPriorityTaskWoken);//发送消息到队尾uart2_data->Rx_Message_Queue
		if(err==errQUEUE_FULL){
			printf("xQueue is full,send message fail to pc\r\n");
		}
		portYIELD_FROM_ISR(xHigherPriorityTaskWoken);       
		
	}	

}

command.c

#include "Config.h"
#include "string.h"
#include "Control.h"
#include "Command.h"
#include "USART1_init.h"
#include "24C512.h"
#include "delay.h"
#include "SysTick.h"
#include "crc16.h"



typedef void (*op_func)();
void Help(void *parameters);

struct _cmd
{
	char *str;
	uint8_t parameters;
	void *f;
};
//===================================================
const struct _cmd Cmd[]=
{
	{"HELP",0,Help},
  {"FWVER",0,Fwver},
	{"SET_OUT",0,Set_OUT},
	{"RESET_OUT",0,Reset_OUT},
	{"GET_ALL_SENSOR_STATUS",0,Get_ALL_Sensor_Status},
	{"RESET",0,Reset},
	{"BEEP",0,Beep},
	
};

#define CMD_LEN sizeof(Cmd)/sizeof(struct _cmd)    //84/12
//===================================================
void Help(void *parameters){
	  int j,i;
	  i=CMD_LEN;
	 	for(j=0;j<i;j++)
		{
				printf("%s\r\n",Cmd[j].str);
		}
    printf("OK\r\n"); 
} 
//===================================================

int uart_strncmp(const char *str,const char *cmd_str)
{

		for(;;)
		{
			    if(*cmd_str=='\0')
					{
						if(((int)*str<48)||(((int)*str>57)&&((int)*str<65))||(((int)*str>90)&&((int)*str<96))||((int)*str>122))
						{
									if((int)*str!=95)
								break;						
						}
					}
					if(*str != *cmd_str)return 1;//
					str++;
					cmd_str++;
		}
		return 0;
}


//===================================================
char pr[32];
void Command_exec(char *cChar){
	int parameterv[8],temp;
  unsigned int parameters,i;
	op_func p;
  for(i=0;i<CMD_LEN;i++)                //CMD_LEN为指令的个数
	{
		if(uart_strncmp(cChar,Cmd[i].str)==0)
	 {			
			parameters=Cmd[i].parameters;     //保存函数参数个数
		  sscanf(cChar,"%*[^(](%[^)]"	,pr);	//cChar为uart2缓冲区中的指令 %*[^(] + ( + %[^)] 3部分组成   pr含有数字和逗号和句号 例如1,2,3,4,5,6   %*[^(]:忽略(之前的非(字符      %[^):取)之前的字符
		  p=(op_func)Cmd[i].f;              //函数指针指向结构体函数指针
      if(p!=NULL){
			switch(parameters)                //解析函数参数个数
			{
				case 0:p(pr);break;
				case 1:
					temp=sscanf(pr,"%d",&parameterv[0]);
          if(temp==1){
						p(parameterv[0]);
					}
					else i=CMD_LEN; //错误的指令,退出for循环
          break;	

       	case 2:
					temp=sscanf(pr,"%d,%d",parameterv,parameterv+1);
          if(temp==2){
						p(parameterv[0],parameterv[1]);
					}
					else i=CMD_LEN;//错误的指令,退出for循环 下达指令函数参数只能多不能少 少则出错 多则不报错
          break;					
				default: break;
      					
			}
			
		 }
			break;//跳出for循环 使得i值不增加 为不识别的指令判断创造判断条件
		}
		
	}
	if(i>=CMD_LEN){
		printf("Command Not Found!\r\n"); //无法匹配命令表时 i=CMD_LEN
	}


}

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Stm32 freertos队列串口缓冲区的使用 的相关文章

  • 140-基于stm32单片机智能晾衣杆控制系统Proteus仿真+源程序

    资料编号 140 一 功能介绍 1 采用stm32单片机 LCD1602显示屏 独立按键 DHT11传感器 ds1302时钟 光敏传感器 蜂鸣器 LED灯 制作一个基于stm32单片机智能晾衣杆控制系统Proteus仿真 2 通过光敏传感器
  • 138-基于stm32单片机汽车多功能仪表盘显示系统Proteus仿真+源程序

    资料编号 138 一 功能介绍 1 采用stm32单片机 LCD1602显示屏 独立按键 DHT11传感器 ds1302时钟 LED灯 蜂鸣器 电位器 制作一个基于stm32单片机汽车多功能仪表盘显示系统Proteus仿真 2 通过DHT1
  • 当一个任务写入变量而其他任务读取该变量时,我们是否需要信号量?

    我正在研究 freeRtos 并且我有一个名为 x 的变量 现在 每秒只有一个任务正在写入该变量 而其他任务正在读取该变量值 我需要用互斥锁来保护变量吗 如果变量为 32 位或更小 并且其值是独立的并且不与任何其他变量一起解释 则不需要互斥
  • 物联网网关

    物联网网关是 连接物联网设备和互联网的重要桥梁 它负责将物联网设备采集到的数据进行处理 存储和转发 使其能够与云端或其它设备进行通信 物联网网关的作用是实现物联网设备与云端的无缝连接和数据交互 物联网网关功能 数据采集 物联网网关可以从物联
  • HAL库学习

    CMSIS简介 CMSIS Cortex Microcontroller Software Interface Standard 微控制器软件接口标准 由ARM和其合作的芯片厂商 ST NXP 软件工具厂商 KEIL IAR 共同制定的标准
  • 毕业设计 江科大STM32的智能温室控制蓝牙声光报警APP系统设计

    基于STM32的智能温室控制蓝牙声光报警APP系统设计 1 项目简介 1 1 系统构成 1 2 系统功能 2 部分电路设计 2 1 stm32f103c8t6单片机最小系统电路设计 2 2 LCD1602液晶显示电路设计 2 2 风
  • 在 Atollic TrueStudio、STM32CubeMX 中导入 C 库

    我目前正在开发 STM32F767ZI Nucleo 板和一个小安全芯片 microchip atecc508a 通过 i2c 连接进行连接 该芯片有一个可用的库加密验证库 https github com MicrochipTech cr
  • 最终启动顺序错误 - STM32L476 的 Eclipse System Workbench 调试

    我正在尝试调试和运行 STM32L476 的简单汇编代码 我已经设置了 Eclipse Oxygen 在 Eclipse 中安装了最新版本的 System Workbench 插件并安装了 ST Link 驱动程序 IDE 成功构建了程序
  • STM32F207 I2C 测试失败

    我正在使用 STM32F207 微控制器在 STM3220G EVAL 板上学习嵌入式开发 我尝试通过连接同一芯片上的两个 I2C2 和 I2C3 模块并发送 接收字符来测试 I2C 接口 这是我当前编写的代码 使用 mdk arm 5 i
  • CMSIS & STM32,如何开始? [关闭]

    Closed 这个问题正在寻求书籍 工具 软件库等的推荐 不满足堆栈溢出指南 help closed questions 目前不接受答案 我想在 STM32 上使用 CMSIS 启动项目 网上一搜 没找到具体的教程 有些使用 SPL 开始项
  • for循环延时时间计算

    提示 文章写完后 目录可以自动生成 如何生成可参考右边的帮助文档 文章目录 前言 一 pandas是什么 二 使用步骤 1 引入库 2 读入数据 总结 前言 之前做led点亮的实验 好像是被delay函数影响了 因为delay参数设置的不对
  • 嵌入式开发--STM32G4系列片上FLASH的读写

    这个玩意吧 说起来很简单 就是几行代码的事 但楞是折腾了我大半天时间才搞定 原因后面说 先看代码吧 读操作 读操作很简单 以32位方式读取的时候是这样的 data IO uint32 t 0x0800F000 需要注意的是 当以32位方式读
  • 核心耦合内存在 STM32F4xx 上可执行吗?

    尝试从 STM32F429s CCM 运行代码 但每当我命中 CCM 中的第一条指令时 我总是会遇到硬故障 并且 IBUSERR 标志被设置 该指令有效且一致 STM32F4xx 是否可能不允许从 CCM 执行 数据访问效果良好 alios
  • 从没有中断引脚并且在测量准备好之前需要一些时间的传感器读取数据的最佳方法

    我正在尝试将压力传感器 MS5803 14BA 与我的板 NUCLEO STM32L073RZ 连接 根据 第 3 页 压力传感器需要几毫秒才能准备好读取测量值 对于我的项目 我对需要大约 10 毫秒来转换原始数据的最高分辨率感兴趣 不幸的
  • PWM DMA 到整个 GPIO

    我有一个 STM32F4 我想对一个已与掩码进行 或 运算的 GPIO 端口进行 PWM 处理 所以 也许我们想要 PWM0b00100010一段时间为 200khz 但随后 10khz 后 我们现在想要 PWM0b00010001 然后
  • HAL_Delay() 陷入无限循环

    我被 HAL Delay 函数困住了 当我调用此函数 HAL Delay 时 控制陷入无限循环 在寻找问题的过程中 我发现了这个 http www openstm32 org forumthread2145 threadId2146 htt
  • 使用 STM32F0 ADC 单独读取不同的输入

    STM32F072CBU 微控制器 我有多个 ADC 输入 并且希望单独读取它们 STMcubeMX 生成样板代码 假设我希望按顺序读取所有输入 但我无法弄清楚如何纠正这个问题 这篇博文 http blog koepi info 2015
  • 当端点和 PMA 地址均更改时,CubeMX 生成的 USB HID 设备发送错误数据

    我正在调试我正在创建的复合设备的问题 并在新生成的仅 CubeMX 代码中重新创建了该问题 以使其更容易解决 我添加了少量代码main 让我发送 USB HID 鼠标点击 并在按下蓝色按钮时使 LED 闪烁 uint8 t click re
  • 移动数组中的元素

    我需要一点帮助 我想将数组中的元素向上移动一个元素 以便新位置 1 包含位置 1 中的旧值 new 2 包含 old 1 依此类推 旧的最后一个值被丢弃 第一个位置的新值是我每秒给出的新值 我使用大小为 10 的数组 uint32 t TE
  • stm32l0: 执行MI命令失败。使用 vFlashErase 数据包擦除闪存时出错

    我正在使用 Nucleo STM32L031 和 AC6 STM32 工作台 eclipse 我编写应用程序并进入调试模式 一切正常 直到我在应用程序中添加另一个功能 我注意到当我删除 评论 新函数 软件可以再次进入调试模式 但是当我添加

随机推荐