FreeRTOS中断和任务之间的队列,自定义串口通讯协议

2023-05-16

本文提供这样一种方法:FreeRTOS中串口接收数据中断,然后通过队列将数据传递给任务A,在任务A中对数据进行处理,串口使用的通讯协议为自定义。
依次给出了串口的初始化,中断服务函数;任务A,队列创建的代码;由于实际在MDK中采用多文件编程,结合自己的需求对相应代码进行移植和修改.
由于本人能力水平有限,仅供参考,欢迎交流
串口初始化代码:

void usart5_init(u32 bound)
{
	GPIO_InitTypeDef GPIO_InitStructure;
	USART_InitTypeDef USART_InitStructure;
	NVIC_InitTypeDef NVIC_InitStructure;
  RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC|RCC_APB2Periph_GPIOD|RCC_APB2Periph_AFIO, ENABLE);	//使能GPIOA时钟
  RCC_APB1PeriphClockCmd(RCC_APB1Periph_UART5, ENABLE);	//使能USART5时钟
	
	//USART5_TX   GPIOC.12
   GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12; //PC.12
   GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
   GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;	//复用推挽输出
   GPIO_Init(GPIOC, &GPIO_InitStructure);//初始化GPIOC.12
   
  //USART5_RX	  GPIOD.2初始化
   GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2;//PD2
   GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;//浮空输入
   GPIO_Init(GPIOD, &GPIO_InitStructure);//初始化GPIOD.2  
  
   //USART 初始化设置

	USART_InitStructure.USART_BaudRate = bound;//串口波特率
	USART_InitStructure.USART_WordLength = USART_WordLength_8b;//字长为8位数据格式
	USART_InitStructure.USART_StopBits = USART_StopBits_1;//一个停止位
	USART_InitStructure.USART_Parity = USART_Parity_No;//无奇偶校验位
	USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;//无硬件数据流控制
	USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;	//收发模式

   USART_Init(UART5, &USART_InitStructure); //初始化串口5
  //Uart5 NVIC 配置
   NVIC_InitStructure.NVIC_IRQChannel = UART5_IRQn;
  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=7 ;//抢占优先级7
  NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;		//子优先级一定需要为0
  NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;			//IRQ通道使能
  NVIC_Init(&NVIC_InitStructure);	//根据指定的参数初始化VIC寄存器
  
  USART_ITConfig(UART5, USART_IT_RXNE, ENABLE);//开启串口接受中断
   USART_Cmd(UART5, ENABLE);                    //使能串口5 
	
}

中断服务函数

extern QueueHandle_t   S_Queue;//队列句柄,

//串口5中断服务函数,
void UART5_IRQHandler(void)   
{  
	 u16 ch=0;
	 int i=0;
	 BaseType_t xHigherPriorityTaskWoken;
     static  u8 count=0,t=0,data[4]={0x00,0x00,0x00,0x00}; 
  	 if(USART_GetITStatus(UART5, USART_IT_RXNE) != RESET)
	{
		 USART_ClearFlag(UART5, USART_FLAG_RXNE);
		 USART_ClearITPendingBit(UART5,USART_IT_RXNE);
		 ch=USART_ReceiveData(UART5);	//读取接收到的数据
      
		 switch(count){  //自定义的通讯协议为:0x01,0x02数据头,后面有4组数据,每组包含两位十六进制的数.
	       case 0:{if(ch==0x01) count++;else count=0;break;}									         						
		   case 1:{ if(ch==0x02) count++;else count=0;break;}       		 
		   case 2: data[t]=ch;t++;
                  if  (t==4) 
	            {			  
				          if(S_Queue!=NULL) //判断队列是否有效
		                 { 
				         xQueueSendFromISR(S_Queue,data,&xHigherPriorityTaskWoken);//向队列S_Queue中发送数据data,阻塞时间为最大
				         portYIELD_FROM_ISR(xHigherPriorityTaskWoken);//如果需要的话进行一次任务切换	 
				         }
	                     count=0,t=0;//计数清零
	             } 		 
	    }
}


任务A:

#define  A_TASK_PRIO  4      //优先级
#define  A_STK_SIZE   256    //堆栈大小
TaskHandle_t ATask_Handler; //任务句柄
void A_task(void *pvParameters);

extern QueueHandle_t S_Queue;
//start_task中创建A_task
 xTaskCreate(
				(TaskFunction_t    )    A_task,
				(const char *      )    "A_task",	
				(uint16_t          )    A_STK_SIZE,
				(void *            )    NULL,
				(UBaseType_t       )    A_TASK_PRIO,
				(TaskHandle_t *    )    &A_Handler
             );

void A_task(void *pvParameters)    
{
  u8 data[4];
  int j=0;
  BaseType_t xTaskWokenByReceive=pdFALSE;
  BaseType_t err=pdFALSE; 
  
  for( ;; )    
    {    
     err=xQueueReceiveFromISR(S_Queue,data,&xTaskWokenByReceive);
     if(err==pdTRUE) //接收成功
        {
          	for( j=0;j<4;j++)	 //对数据进行处理,这里仅将他们打印出来	
           {
             printf("指令是:%X\n",data[j]);
            }
        }
       vTaskDelay(10);//延时,进入阻塞
    }
}

创建队列

#define S_MSG_Q_NUM      10  //消息队列的数量
#define USART_REC_LEN  	1  //定义最大接收字节数4  1B 字节=8bit 位,0x01:1B(字节)
S_Queue=xQueueCreate(S_MSG_Q_NUM,USART_REC_LEN);

欢迎关注公众号,干货满满。
在这里插入图片描述

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

FreeRTOS中断和任务之间的队列,自定义串口通讯协议 的相关文章

  • FreeRTOS例程4-串口DMA收发不定长数据

    FreeRTOS例程4 串口DMA收发不定长数据 知乎 zhihu com
  • 【FreeRtos学习笔记】STM32 CubeMx——Timers(定时器)

    目录 1 软件定时器 2 示例程序 2 1 例程功能 2 2 步骤 2 3 实验结果 2 4 函数讲解 1 软件定时器 定时器是MCU常用的外设 我们在学习各种单片机时必然会学习它的硬件定时器 但是 MCU自带的硬件定时器资源是有限的 而且
  • FreeRTOS 软件定时器的使用

    FreeRTOS中加入了软件定时器这个功能组件 是一个可选的 不属于freeRTOS内核的功能 由定时器服务任务 其实就是一个定时器任务 来提供 软件定时器是当设定一个定时时间 当达到设定的时间之后就会执行指定的功能函数 而这个功能函数就叫
  • 解决错误“ #error “include FreeRTOS.h“ must appear in source files before “include event_groups.““例子分享

    今天来给大家分享一下 关于之前自己在学习FreeRTOS过程中遇到的一个错误提示 话不多说 我们直接来看 错误分析 首先 我们看一下错误的提示 error 35 error directive include FreeRTOS h must
  • 一文教你学会keil软件仿真

    仿真在我们调试代码中是非常重要的 通过仿真 我们可以快速定位到错误代码 或者错误逻辑的地方 这里我就以上一篇博客为例 教大家如何软件仿真 软件仿真不需要单片机 直接通过keil软件进行代码调试 一 打开工具 二 选择软件仿真 三 开始仿真
  • FreeRTOS学习(八) 延时函数

    声明及感谢 跟随正点原子资料学习 在此作为学习的记录和总结 环境 keil stm32f103 FreeRTOS延时函数有两个 分别是 vTaskDelay vTaskDelayUntil 1 vTaskDelay 任务相对延时 函数原型
  • freertos---软定时器

    一 软件定时器介绍 freeRTOS软件定时器的时基是基于系统时钟节拍实现的 可以创建很多个 在硬件定时器资源不充足的情况下非常有用 软件定时器一般用作周期性地执行函数 在创建软件定时器时指定软件定时器的回调函数 在回调函数中实现相应的功能
  • freeRTOS手册 第六章 . 中断管理

    如果我对本翻译内容享有所有权 允许任何人复制使用本文章 不会收取任何费用 如有平台向你收取费用与本人无任何关系 第六章 中断管理 章节介绍和范围 事件 嵌入式实时系统必需对环境中的事件做出响应 比如 外部网络设备收到一个发送给TCP IP栈
  • FreeRTOS临界段和开关中断

    http blog sina com cn s blog 98ee3a930102wg5u html 本章教程为大家讲解两个重要的概念 FreeRTOS的临界段和开关中断 本章教程配套的例子含Cortex M3内核的STM32F103和Co
  • STM32F103移植FreeRTOS必须搞明白的系列知识---2(FreeRTOS任务优先级)

    STM32F103移植FreeRTOS必须搞明白的系列知识 1 Cortex CM3中断优先级 STM32F103移植FreeRTOS必须搞明白的系列知识 2 FreeRTOS任务优先级 STM32F103移植FreeRTOS必须搞明白的系
  • FreeRTOS之软件定时器

    FreeRTOS之软件定时器 声明 本人按照正点原子的FreeRTOS例程进行学习的 欢迎各位大佬指责和批评 谢谢 include sys h include delay h include usart h include led h in
  • FreeRTOS学习(三)开关中断

    声明及感谢 跟随正点原子资料学习 在此作为学习的记录和总结 环境 keil stm32f103 背景知识 Cotex M3的NVIC最多支持240个IRQ 中断请求 1个不可屏蔽 NMI 1个Systick 滴答定时器 Cortex M处理
  • FreeRTOS笔记(一)简介

    这个笔记主要依据韦东山freertos快速入门系列记录 感谢韦东山老师的总结 什么是实时操作系统 操作系统是一个控制程序 负责协调分配计算资源和内存资源给不同的应用程序使用 并防止系统出现故障 操作系统通过一个调度算法和内存管理算法尽可能把
  • Arduino IDE将FreeRTOS用于STM32

    介绍 适用于STM32F103C8的FreeRTOS STM32F103C是一种能够使用FreeRTOS的ARM Cortex M3处理器 我们直接在Arduino IDE中开始使用STM32F103C8的FreeRTOS 我们也可以使用K
  • FreeRTOS死机原因

    1 中断回调函数中没有使用中断级API xxFromISR 函数 xSemaphoreGiveFromISR uart busy HighterTask 正确 xSemaphoreGive uart busy 错误 2 比configMAX
  • FreeRTOS之系统配置

    1 FreeRTOS的系统配置文件为FreeRTOSConfig h 在此配置文件中可以完成FreeRTOS的裁剪和配置 在官方的demo中 每个工程都有一个该文件 2 先说一下 INCLUDE 开始的宏 使用 INCLUDE 开头的宏用来
  • FreeRTOSConfig.h 配置优化及深入

    本篇目标 基于上一篇的移植freertos stm32f4 freertos 上 修改 FreeRTOSConfig h 文件的相关配置来优化辅助 FreeRtos 的使用 并且建立一些基本功能 信号量 消息地列等 的简单应用位于 stm3
  • 当一个任务写入变量而其他任务读取该变量时,我们是否需要信号量?

    我正在研究 freeRtos 并且我有一个名为 x 的变量 现在 每秒只有一个任务正在写入该变量 而其他任务正在读取该变量值 我需要用互斥锁来保护变量吗 如果变量为 32 位或更小 并且其值是独立的并且不与任何其他变量一起解释 则不需要互斥
  • 哪些变量类型/大小在 STM32 微控制器上是原子的?

    以下是 STM32 微控制器上的数据类型 http www keil com support man docs armcc armcc chr1359125009502 htm http www keil com support man d
  • 有关 CMake 错误的问题:没有为目标提供源

    我正在尝试使用 cmake 和 eclipse 将 FreeRtos 添加到我的项目中 但出现错误 我运行的是 debian 10 我的 cmake 版本是 3 13 4 cmake 的文件可以在以下位置找到这个 git 仓库 https

随机推荐