STM32 串口驱动,分层通信

以前在使用串口的时候都是直接使用中断,每收发一个字节都要进一次中断,然后直接在中断进行封包,现在做了一个简单的分层设计,其实这个设计还是驱动设计,后期将逻辑层划分再细致一点,争取做到和linux的shell类似的分层。

软件分层如下

驱动层:串口、DMA、初始化,串口只开启接收空闲中断,DMA中断不开启。

缓冲区:利用malloc和free函数创建的链表,缓冲区管理有两个,一个是接收缓冲区,每次进入接收空闲中断就把数据扔到接收缓冲队列里面去;另一个是发送缓冲区,发送缓冲区无逻辑,这只是一个数据结构。

 

示意图中的数据指针实际上用的是uint8 数组,当然,第一个数据完全可以塞到第二个数据里面,但是如果使用的是M0芯片的时候,会有一个指针地址的对齐问题,这个就不展开说了,只要是问题都有规避办法的。

逻辑层:逻辑里面关于串口接收队列,因为无法保证发送方的数据连续,所以需要将接收缓冲队列的数据重新打包,打包函数主要检测接收队列是否有数据,如果有,进行数据打包,如果能保证数据帧的完整性,无粘包、无断包,数据打包函数可以去除。串口发送函数,串口发送函数定时10ms检测DMA发送通道是否为空,如果通道空,延时10ms启动DMA发送,发送数据在发送队列缓冲中获取,发送的帧间隔范围在10~20ms之间,延时10ms保证了发送帧间隔至少10ms。


设计一个发送函数的接口,有数据发送时,应用只管往里面扔数据,然后再用一个封包函数封起来,再加一个封包函数,对于用户而言只有一个发送函数的api,用户层只管发送数据,底层逻辑不要管,也不允许动。发送函数只管定时从发送队列里面取数据,取一帧,然后调用dma,然后等待帧间隔,进行下一帧数据获取,发送,做到软件层面的分层,责任划分明确,一个函数只干一件事。


软件设计思想说完,下面直接放代码。

usart.h

#ifndef _USART_H
#define _USART_H
#include "stm32f10x.h"

#define SEND_BUSY 1
#define SEND_IDLE 0
#define BOUND_RATE	38400			//串口通信波特率
#define SENDBUFF_SIZE 50
#define SENDBUFF_SIZE_INTIT 0
#define RECEBUFF_SIZE 200
#define USART1_DR_Base  0x40013804
#define COMM_SEND_INTERNAL_20MS	20

struct COM_DATA_ST
{
	uint8_t SendBuff[SENDBUFF_SIZE];
	uint8_t ReceBuff[RECEBUFF_SIZE];
	uint8_t Send_Complete_Flag;
	uint8_t Bus_Idle_Count;
};

void usart1_init(void);
void usart1_rev_irq(void);
void usart1_send_irq(void);
void DMA_Config(void);
void Send_data(uint8_t *ptr,uint8_t length);
void usart1_dma_send_irq(void);
void Check_Send_Quene(void);
void usart1_send_interval_deal(void);

#endif
usart.c
#include "stm32f10x.h"
#include "string.h"
#include "usart.h"
#include "quene.h"


struct COM_DATA_ST Com_Data;

struct node Rece_Quene;			/*接收的数据队列*
  • 5
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值