基于RS485和循环队列(streambuf)和freertos做一个简单的收发

一、关于Stream Buffer的介绍

Stream Buffer,顾名思义,是一种用于存储和传输流式数据的缓冲区,也就是数据结构中的循环队列。它能够在不同的组件或任务之间高效地传递和处理连续的数据流,如音频、视频、文件传输等。Stream Buffer通过提供一个环形缓冲区(ring buffer)来存储数据,允许数据连续地写入和读取,从而优化了数据的处理效率,同时也可以避免内存浪费。

循环队列数据结构定义: int read;//指向队列头,指向第一个数据节点 int write;//指向队列尾(并不是指向最后一个数据节点,而是最后一个数据节点后面的位置) char data[];//节点数据,根据实际需要可以是不同的数据类型.

二、关于RS485介绍

RS-485是一种串行通信协议,是串口通信的变种之一,设计用于工业环境中的数据通信。它采用平衡发送和差分接收的方式,相较于普通串口通信和RS232通信,RS485通信干扰能力更强,适用于长距离通信,最长可达1200米。RS-485标准允许在一条总线上连接多个设备,支持半双工通信。这种通信方式特别适合于工业控制系统中,需要采集多点数据或传输大量数据的场景。

rs485模块的rs485_dir管脚置高处于数据发送状态,置低处于数据接收状态

三、STM32cubeMX配置

四、代码编写

#include "freertos_demo.h"
#include "FreeRTOS.h"
#include "task.h"
#include "gpio.h"
#include "tim.h"
#include "usart.h"
#include <stdio.h>


#define START_TASK_STACK_SIZE 64
#define START_TASK_PRIO       1
TaskHandle_t       start_task_handler;
void start_task( void * pvParameters );

#define TASK1_STACK_SIZE 128
#define TASK1_PRIO       2
TaskHandle_t       task1_handler;
void task1( void * pvParameters );

circqueue_t  que;
circqueue_t *queue=&que;

void freertos_demo(void)
{
	xTaskCreate(	(TaskFunction_t)         start_task,
							  (char *)                 "start_task",		
							  (configSTACK_DEPTH_TYPE) START_TASK_STACK_SIZE,
							  (void *)                 NULL,
							  (UBaseType_t)            START_TASK_PRIO,
							  (TaskHandle_t *)         &start_task_handler);
	vTaskStartScheduler();
}

void start_task( void * pvParameters )
 {
	 taskENTER_CRITICAL();
	 
	xTaskCreate((TaskFunction_t)         task1,
							  (char *)                 "task1",		
							  (configSTACK_DEPTH_TYPE) TASK1_STACK_SIZE,
							  (void *)                 NULL,
							  (UBaseType_t)            TASK1_PRIO,
							  (TaskHandle_t *)         &task1_handler);				
	vTaskDelete(NULL);
	taskEXIT_CRITICAL();
 }
 
 /*处理数据再发送出去*/
void task1( void * pvParameters )
 {
	 char buf[32];
	 char ch;
		printf("task1\r\n");
		while(1)
		{		
			ch = circQueueRemove(queue);
			printf("%x\n",ch);
			while(ch != NULL)
			{
				HAL_GPIO_WritePin(GPIOC, GPIO_PIN_7, GPIO_PIN_SET);//置高发送数据
				HAL_UART_Transmit(&hlpuart1, (uint8_t *)&ch, 1, 0xffff);
				HAL_GPIO_WritePin(GPIOC, GPIO_PIN_7, GPIO_PIN_RESET);//置低接收数据
				ch = circQueueRemove(queue);
			}
			vTaskDelay(500);
		}
 }
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include "streambuf.h"

void circqueue_init(circqueue_t *queue)//初始化队列
{
        queue->write = 0;
        queue->read = 0;
        memset(queue->data, 0, MAX_NODE_NUM);
}

void circqueue_delete(circqueue_t *queue)//清空队列
{
        if(queue)
        {
					printf("will free queue, write is:%d,read is %d\n",queue->write, queue->read);
					free(queue);
        }
}

int isQueueEmpty(circqueue_t *queue)//判空
{
	return (queue->read==queue->write);
}

int isQueueFull(circqueue_t *queue)//判满
{
	return (((queue->write + 1) % MAX_NODE_NUM == queue->read));
}

int writecircQueue(circqueue_t *queue, char newdata)//入队
{
        if(isQueueFull(queue))
        {
					printf("queue is full, add node failed!\n");
          return (queue->read-queue->write+MAX_NODE_NUM)%MAX_NODE_NUM;
        }
        queue->data[queue->write] = newdata;
        queue->write = (queue->write + 1)%MAX_NODE_NUM;
        //printf("write is %d, read is %d, %d\n", queue->write, queue->read, (queue->write-queue->read+MAX_NODE_NUM)%MAX_NODE_NUM);
        return (queue->write-queue->read+MAX_NODE_NUM)%MAX_NODE_NUM;
}


char readcircQueue(circqueue_t *queue)//出队
{
				char nodeValue;
        if(isQueueEmpty(queue))
        {
                printf("queue is empty, remove node failed\n");
                return NULL;
        }
        nodeValue = queue->data[queue->read];
        queue->read = (queue->read+1)%MAX_NODE_NUM;
        return nodeValue;
}

void printQueueData(circqueue_t *queue)//遍历队列
{
        int i=0;
        printf("write is %d, read is %d\n", queue->write, queue->read);
        for(i=queue->read; i!= queue->write; i=(i+1)%MAX_NODE_NUM)
        {
                printf("%c ", queue->data[i]);
        }
        printf("\n");
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值