硬件资源:

使用stm32f103c8t6单片机作为主控,CH340USB转串口模块进行串口数据收发,0.96寸支持IIC协议的显示屏进行效果显示。

接线图:

项目思路:

①:什么是串口数据包?

用来存放数据的一串数据,由包头,包尾和中间的数据组成,数据长度可变,这里使用数据长度4个字节。

②:为什么要使用串口数据包?

例:MPU6050陀螺仪向单片机发送姿态数据,单片机如何了解哪里是数据的开头和结尾呢?

将数据的开头和结尾加上特殊的标识符或者16进制数(头:0XFF 尾:0XFE)

这样就可以分辨出数据的头尾了,便于收发数据,提高效率。

③:如何收发串口数据包?

这里对要发送的数据包打包,接收的数据进行解包

打包就是在想要发送的数据开头和结尾加上标识符(这里是0XFF和0XFE)

解包就是对接收到的数据包过滤掉包头和包尾进行显示。

代码部分:

废话不多说,上代码,首先是串口的初始化及数据包定义:

#include "stm32f10x.h"                  // Device headerlong int  rxbuf[4];//定义存放十六进制数的接收数据包
long int  sedbuf[4];//定义存放十六进制数的发送数据包int rxflag = 0;//接收标志位void Uart1_init(int Buad)//串口初始化
{GPIO_InitTypeDef gpioinitstructure;USART_InitTypeDef USART_InitStructure;RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);//RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE);RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE);//配置PA9  TXgpioinitstructure.GPIO_Mode = GPIO_Mode_AF_PP;gpioinitstructure.GPIO_Pin = GPIO_Pin_9;gpioinitstructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_Init(GPIOA, &gpioinitstructure);//PA10  RXgpioinitstructure.GPIO_Mode = GPIO_Mode_IPU;gpioinitstructure.GPIO_Speed = GPIO_Speed_50MHz;gpioinitstructure.GPIO_Pin = GPIO_Pin_10;GPIO_Init(GPIOA, &gpioinitstructure);//串口结构体初始化USART_InitStructure.USART_BaudRate = Buad;//波特率设置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(USART1, &USART_InitStructure); //初始化串口1USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);NVIC_InitTypeDef NVIC_InitStructure;NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;NVIC_Init(&NVIC_InitStructure);USART_Init(USART1, &USART_InitStructure);USART_Cmd(USART1, ENABLE);
}//发送字符
void USART_SendByte(USART_TypeDef* USARTx, char  str)
{USART_SendData(USARTx, str);//发送单个字符while(USART_GetFlagStatus(USART1, USART_FLAG_TXE) == RESET);//判断是否发送完成}/*自己封装的发送字符串函数,通过检测是否到达字符串末尾来判定是否跳出循环
参数:①:串口号②: 字符串*/
void USART_SendString(USART_TypeDef* USARTx, char * str)
{while(*str != '\0'){USART_SendData(USARTx, *str);//发送单个字符str++;while(USART_GetFlagStatus(USART1, USART_FLAG_TXE) == RESET);//判断是否发送完成//Delay_ms(500);}}void send_pack(long int * sendbuf)//发送包
{USART_SendByte(USART1, 0xFF);USART_SendByte(USART1,sendbuf[0]);USART_SendByte(USART1,sendbuf[1]);USART_SendByte(USART1,sendbuf[2]);USART_SendByte(USART1,sendbuf[3]);USART_SendByte(USART1, 0xFE);}void USART1_IRQHandler(void)
{/*定义静态变量记录接收状态*/static int rxstate;//接收状态  0--等待包头  1--接收数据   2--等待包尾static int rxdata;//串口数据暂存static int i;if(USART_GetITStatus(USART1, USART_IT_RXNE) == SET)//检测串口状态是否处于接收状态{rxdata = USART_ReceiveData(USART1);//将接收到的数据暂存到rxdata/*根据接收状态判定进入哪个条件判断*/if(rxstate == 0){if(rxdata == 0xFF)//接收到包头,下一位是数据,状态置1{rxstate = 1;}}else if(rxstate == 1)//接收到的是数据{rxbuf[i] = rxdata;//将接收缓冲区数据存放到,接收数组i++;if(i > 4 | i == 4)//固定长度4个字节,接收到4个之后下一位默认是包尾{i = 0;rxstate = 2;}}else if(rxstate == 2)//检测到包尾{if(rxdata == 0xFE){rxflag = 1;//接收标志置1,代表接收完成rxstate = 0;//接收状态置0,准备接收下一段数据的包头}}USART_ClearITPendingBit(USART1, USART_IT_RXNE);//清空中断标志,每接收到一次数据进入一次中断}}

下面是主程序的初始化,及数据包收发:

#include "stm32f10x.h"                  // Device header
#include "stm32f10x_usart.h"
#include "Delay.h"
#include "stdio.h"
#include "USART.h"
#include "OLED.h"extern long int  rxbuf[4];
extern long int  sedbuf[4];extern int rxflag;int main(void)
{OLED_Init();OLED_Clear();Uart1_init(9600);OLED_ShowString(1, 1, "TxPacket");OLED_ShowString(3, 1, "RxPacket");sedbuf[0] = 0x01;sedbuf[1] = 0x02;sedbuf[2] = 0x03;sedbuf[3] = 0x04;while(1){send_pack(sedbuf);OLED_ShowHexNum(2, 1, sedbuf[0], 2);OLED_ShowHexNum(2, 4, sedbuf[1], 2);OLED_ShowHexNum(2, 7, sedbuf[2], 2);OLED_ShowHexNum(2, 10,sedbuf[3], 2);if(rxflag == 1){OLED_ShowHexNum(4, 1, rxbuf[0], 2);OLED_ShowHexNum(4, 4, rxbuf[1], 2);OLED_ShowHexNum(4, 7, rxbuf[2], 2);OLED_ShowHexNum(4, 10, rxbuf[3], 2);}}}

实验效果:

上位机:不断接收单片机发送的数据

下位机:

总结:使用数据包进行收发数据,能够有效保证数据传输的准确性和效率。

stm32f103c8t6串口数据包收发相关推荐

  1. 【STM32学习】——USART串口数据包HEX/文本数据包收发流程串口收发HEX/文本数据包实操

    文章目录 前言 一.数据包格式(江科大规定) 1.HEX数据包 2.文本数据包 3.两者对比 二.数据包收发流程 1.HEX数据包接收(只演示固定包长) 2.文本数据包接收(只演示可变包长) 三.实操 ...

  2. 数据包收发c语言程序,在C程序中发送ICMP数据包

    我正在尝试用C创建一个ICMP ping测试程序,但是在成功发送数据包时遇到了困难. sendto函数返回字节数和所有内容但实际上没有发送数据包.我已经在目标计算机上使用WireShark验证了这一点 ...

  3. 数据包收发c语言程序,使用C在套接字编程中创建数据包以及发送和接收数据包的正确方法...

    指针pkt未在您的应用程序中定义.您有两种选择: 1)将pkt声明为正常变量 struct packet pkt; pkt.srcID = 01; .... send(sockfd, &pkt ...

  4. 江科大32——USART发送数据包原理

    1.HEX数据包格式  数据包的作用: 把一个个单独的数据打包起来,方便进行多字节的数据通信. 比如:陀螺仪传感器需要用串口发送数据到STM32,陀螺仪的数据有X轴一个字节,Y轴一个字节,Z轴一个字节 ...

  5. 2023-3-5数据包备注

    数据备注 收发距离为三米时第一组数据出现213字节的数据包,同时有行人路过. 第三组数据质量好一些. 收发距离为四米时第一组数据出现很多的213字节的数据包,第四组和第五组数据也是213和393混杂 ...

  6. STM32f407与STM32F103 串口采用DMA收发数据配置方法的异同

    最近有个项目需要用到STM32F407ZET6这款芯片,其中有一个串口收发数据的应用.因为之前有用过STMF32F103ZET6通过DMA收发数据的方案,所以我打算移植之前的代码实现这个功能,STM3 ...

  7. 沁恒微电子CH9121 集成TCP/IP 协议栈,可实现网络数据包和串口数据的双向透明传输

    概述 沁恒微电子CH9121 集成TCP/IP 协议栈,可实现网络数据包和串口数据的双向透明传输,具有TCPCLIENT.TCP SERVER.UDP 3 种工作模式,串口波特率最高可支持到92160 ...

  8. STM32学习之串口采用DMA收发数据:需要利用状态机加DMA加串口

    写在前面 在学习这一节知识点的时候,真的是感觉太抽象了,没有一个合适的视频讲的我有那种豁然开朗的感觉,直到我看到了这篇文章,大家可以去看看,里面的描述特别形象. 链接:https://blog.csd ...

  9. node-serialport —— Node.js 串口数据读写包

    node-serialport 是一个 Node.js 的包,用来对串口数据进行读写操作. 基本示例代码: var SerialPort = require("serialport" ...

最新文章

  1. 凌晨三点,各类程序员都在干吗?
  2. 零基础入门学习Python(17)-函数的参数
  3. Modelsim初级使用教程
  4. The 13th Zhejiang Provincial Collegiate Contest(2016年浙江省赛)
  5. 【Android 逆向】Android 系统中文件的用户和分组 ( 文件所有者与分组 | /sdcard/ 的文件分组 | /data/ 目录分析 | 用户类型 )
  6. 基于对偶学习的跨领域图片描述生成
  7. java 存储png文件_vue图片上传及java存储图片(亲测可用)
  8. java 线程停止在那个为止_java停止线程
  9. python中{%%}在HTML中的用法
  10. 工信部:老年人拨打三大运营商客服享受一键呼入等服务
  11. Python中 模块、包、库
  12. 在VSCode中编辑HTML文档时,在Dom标签上写style属性时智能提示的问题
  13. Python退出命令-为什么要使用这么多?何时使用?
  14. 毕业论文中含有Java需要哪些参考文献_Java毕业论文参考文献
  15. 计算机一级安装包怎么升级,详细教您win7如何升级为sp1
  16. PHP 图片上文字排版,文字输出至图片的排版有关问题
  17. python安装numpy模块教程_Python中Numpy包的安装与使用方法简明教程
  18. 2022年(2023届)西电计算机保研经历分享(清深、自所、计算所、浙科南、北航、哈工等)
  19. 狐妖小红娘手游服务器维护,狐妖小红娘手游:游戏界面详细解析,狐妖小粉丝不要错过哦...
  20. 看了这个,再也不怕流量劫持了!

热门文章

  1. 输入两个实数,用一个函数求出它们之和
  2. python 批量读取csv_Python Pandas批量读取csv文件到dataframe的方法
  3. 安卓GB28181设备语音广播和语音对讲(Android GB28181 语音广播和语音对讲)实现
  4. python 实现实时语音对讲
  5. ubuntu打开浏览器无法上网的问题解决方法?
  6. 手机号码11位以及格式验证规则
  7. 密钥加密法(指针应用)
  8. amigo幸运字符什么意思_QQ幸运字符有几个一共多少种 qq幸运字符标识都有哪些介绍...
  9. winrar 百度网盘_不冲百度网盘会员,如何在手机上打开网盘里的压缩包?
  10. 搭建Linux内核代码浏览工具LXR