STM32具有的协议

UASRT是通用异步/同步收发器,UART是通用异步收发器

串口空闲状态时高电平,开始传输数据时,第一个数据为固定的低电平; 数据;最后为高电平的停止位

奇偶校验:通过+1或者不变,使数据中1的个数为奇数或者偶数

CRC校验

UASRT外设自动完成电平的高低反转(低位先行),虽有时钟线(为了兼容),但主要还是用的异步通信

配置好USART电路,只需要读写对应的寄存器就可以实现自动发送和接收

硬件流控制:多一根线来显示接受状态(准备好接受就置低电平)

实现逻辑:

发送,写一个数据到TDR中(以二进制保存),硬件检测到后,就会检查当前的移位寄存器是不是有数据在转运,没有的话就立即上,此时会置一个标志位TXE(empty)[发送寄存器空]为1,判断后就可以在TDR写入下一个数据,循环

接收,数据先到接受移位寄存器中,接受一个周期完毕后,转运到RDR,此时置标志位RXNE(RX Not Empty), 判断后就可以从RDR读取数据

流控引脚nRTS  请求发送,是输出脚,告诉别人我当前能不能接收   ;nCTS清除发送,是输入脚(接受别人nRTS的信号),能不能发送。 n表示低电平有效

流控逻辑,外部TX接我的RX,我的nRTS输出一个能不能接收的反馈信号,接外部的nCTS; 我能接收的时候RTS低电平,对方接受信号就可以一直发。反之亦然。

发送寄存器每移位一次。同步时钟电平就跳变个周期,(时钟功能一般不用)

唤醒单元:实现挂载多设备,通过给串口分配地址,用到哪个设备就把它的地址写到唤醒单元里

分频,支持小数点后4位,然后除以16,得到发送器时钟和接收器时钟

代码提示:CTRL+ALT+空格

单数据

发送:发送单字节,字符串,数组,数字(字符型)

void Serial_Init(void)
{ // 开启USART和GPIO的RCC时钟
RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE); GPIO_InitTypeDef GPIO_InitStructure;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;//初始化TX引脚是USART外设控制的输出脚,复用推挽
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &GPIO_InitStructure);
USART_InitTypeDef USART_InitStructure;
USART_InitStructure.USART_BaudRate = 9600;
USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None; //流控
USART_InitStructure.USART_Mode = USART_Mode_Tx | USART_Mode_Rx; // 串口模式
USART_InitStructure.USART_Parity = USART_Parity_No; //校验位
USART_InitStructure.USART_StopBits = USART_StopBits_1;//停止位
USART_InitStructure.USART_WordLength = USART_WordLength_8b; //字长
USART_Init(USART1, &USART_InitStructure); USART_Cmd(USART1, ENABLE);
} void Serial_SendByte(uint8_t Byte)
{
USART_SendData(USART1, Byte);//写DR寄存器
while (USART_GetFlagStatus(USART1, USART_FLAG_TXE) == RESET);//等待TDR数据转移到移位寄存器(对其写操作会自动使其清零)
}

打印换行“hello \r \n”  ,POW()函数数字分解

printf设置

对输出进行重定向(从输出屏幕重定向到电脑)

#include <stdio.h>

int fputc(int ch, FILE *f) //是printf的底层
{
Serial_SendByte(ch);
return ch;
} printf("hello,%d\r\n",9); //多串口使用printf
char String[100]
sprintf(String,"hello,%d\r\n",9);
Serial_SendString(String) //使用其他串口发送 //可变参数
void Serial_Printf(char *format, ...)
{
char String[100];
va_list arg;
va_start(arg, format);
vsprintf(String, format, arg); // 数据源地址,格式化字符串,参数表
va_end(arg);
Serial_SendString(String);
}

打印汉字(编译器设置)

Serial_Printf(“你好呀”),串口工具也使用UTF-8显示才行
方法2:GBK模式,在keil选择Chinese GB2312(Simplified)),串口就直接可以融合中文 (记得关闭.c文件重新打开刷新字体)

发送+接收
查询:

中断:

void Serial_Init(void)
{ // 开启USART和GPIO的RCC时钟
RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
//发送
GPIO_InitTypeDef GPIO_InitStructure;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;//初始化TX引脚是USART外设控制的输出脚,复用推挽
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &GPIO_InitStructure);
//接收
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU; //初始化RX
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &GPIO_InitStructure); USART_InitTypeDef USART_InitStructure;
USART_InitStructure.USART_BaudRate = 9600;
USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None; //流控
USART_InitStructure.USART_Mode = USART_Mode_Tx | USART_Mode_Rx; // 串口模式
USART_InitStructure.USART_Parity = USART_Parity_No; //校验位
USART_InitStructure.USART_StopBits = USART_StopBits_1;//停止位
USART_InitStructure.USART_WordLength = USART_WordLength_8b; //字长
USART_Init(USART1, &USART_InitStructure);
//串口接收可以用查询(不用下面的代码【比较简单】)和中断(使用下面代码)
USART_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_Cmd(USART1, ENABLE);
} uint8_t Serial_RxData;
uint8_t Serial_RxFlag; uint8_t Serial_GetRxFlag(void)
{
if (Serial_RxFlag == 1)
{
Serial_RxFlag = 0;
return 1;
}
return 0;
} uint8_t Serial_GetRxData(void)
{
return Serial_RxData;
} void USART1_IRQHandler(void)
{
if (USART_GetITStatus(USART1, USART_IT_RXNE) == SET)
{
Serial_RxData = USART_ReceiveData(USART1);// 接收数据,读DR寄存器
Serial_RxFlag = 1;
USART_ClearITPendingBit(USART1, USART_IT_RXNE);
}
}

串口助手是用visual studio软件,winform模板写的

输入数据处理:以波特率的频率连续采样一帧的数据,采样要在正中间,如何实现?:以波特率的16倍进采样,

比如起始位,在下降沿后的3 5 7 次进行一批采样,8 9 10(正中间)再进行一次采样,两批采样要求每三位里面至少2个0,若有噪声则会置标志位NE(Noise Error)

数据包的接收,利用串口进行人机交互

如何避免数据包含包头包尾呢?:增加包头尾的长度,严格限定数据长度或范围吗,也可以只要包头不要尾(兼容差)

接受数据包

code

通过状态机判断,可将数据部分存储到数组中读出(包头和包尾为条件判断使用)

跟接收HEX的区别是:char Serial_RxPacket[100];

状态机,在进中断时判断处于哪个状态,从而执行不同的逻辑

协议 UARST & 数据发送与接收的更多相关文章

  1. L2CAP数据发送和接收

    ACL 链路在 Bluetooth 中非常重要,一些重要的应用如 A2DP, 基于 RFCOMM 的应用.BNEP等都要建立 ACL 链路,发送/接收ACL 包.跟大家一起来分析 ACL 包发送/接收 ...

  2. ASP.NET POST XML JSON数据,发送与接收

    接收端通过Request.InputStream读取:byte[] byts = new byte[Request.InputStream.Length];Request.InputStream.Re ...

  3. (Spring4 json入门)Spring4+SpringMVC+页面数据发送与接收(json格式)

    jar包(Maven仓库): Spring4 jar包(Maven仓库): 在测试过程中我查看了网上的一些教程,但是那些教程都是在Spring3环境下的,Spring3和Spring4解析json需要 ...

  4. udp协议的数据接收与发送的代码

    我想基于lwIP协议中的UDP协议,用单片机做一个服务器,接受电脑的指令然后返回数据.以下是我的代码 /************************************************ ...

  5. [转帖]Linux TCP/IP协议栈,数据发送接收流程,TCP协议特点

    Linux TCP/IP协议栈,数据发送接收流程,TCP协议特点 http://network.51cto.com/art/201909/603780.htm 可以毫不夸张的说现如今的互联网是基于TC ...

  6. C#串口通信—向串口发送数据,同步接收返回数据

    最近写C#串口通信程序,系统是B/S架构.SerialPort类有一个DataReceived事件,用来接收串口返回的数据,但这种方式在C/S架构下很好用,但B/S就不好处理了.所以写了一个同步模式接 ...

  7. [Socket网络编程]由于套接字没有连接并且(当使用一个 sendto 调用发送数据报套接字时)没有提供地址,发送或接收数据的请求没有被接受。

    原文地址:http://blog.sina.com.cn/s/blog_70bf579801017ylu.html,记录在此方便查看 解决办法: MSDN的说明: Close 方法可关闭远程主机连接, ...

  8. C#中UDP数据的发送、接收

    Visual C# UDP数据的发送、接收包使用的主要类及其用法: 用Visual C# UDP协议的实现,最为常用,也是最为关键的类就是UdpClient,UdpClient位于命名空间System ...

  9. 项目总结22:Java UDP Socket数据的发送和接收

    项目总结22:Java UDP Socket数据的发送和接收 1-先上demo 客户端(发送数据) package com.hs.pretest.udp; import java.io.IOExcep ...

  10. stm32实现DMX512协议发送与接收(非标)

    最近把玩了一下485,期间也接触了dmx512通信协议,该协议主要用于各种舞台灯光的控制当中,进而实现各种光效以及色彩变化.根据标准的512协议,其物理连接与传统上的RS485是完全一致的,并没有什么 ...

随机推荐

  1. 遥感图像处理笔记之【U-Net for Semantic Segmentation on Unbalanced Aerial Imagery】

    遥感图像处理学习(5) 前言 遥感系列第5篇.遥感图像处理方向的学习者可以参考或者复刻 本文初编辑于2023年12月15日 2024年1月24日搬运至本人博客园平台 文章标题:U-Net for Se ...

  2. P4103 [HEOI2014] 大工程 题解

    题目链接:大工程 先考虑只有一次查询,很显然我们可以暴力树上 dp 处理出答案. 对于每个节点而言,有: 容易看出类似点分治逐个遍历子树计算前面一堆子树对后面子树的贡献思想,我们可以很容易的知道: 对 ...

  3. Java 运算符 - 除法

    1. 除法运算符 Java中的除法运算符是"/"符号,表示将左侧操作数除以右侧操作数. 2. 整数除法 在Java中,整数除法的结果是一个整数,即只保留除法的整数部分,舍去小数部分 ...

  4. Linux-编译源码时所需提前安装的常用依赖包列表

    编译源码时所需提前安装的常用依赖包列表: yum -y install gcc gcc-c++ autoconf libjpeg libjpeg-devel libpng libpng-devel f ...

  5. NC14291 Cut

    题目链接 题目 题目描述 给你一个长度为 \(n\) 的序列,你每次可以将一个序列分割成两个连续的的子序列, 分割的代价为原序列的总和. 现在允许你在初始时将序列重新排列一次. 问分割成 \(n\) ...

  6. python绘图总结

    1 二维图像 1.1 二维曲线 plot(x, y, ls="-", lw=1.5, label=None) x, y:横坐标和纵坐标 ls:颜色.点标记.线型列表,如 ls='r ...

  7. Git合并固定分支的某一部分至当前分支

    在 Git 中,通常使用 git merge 命令来将一个分支的更改合并到另一个分支.如果你只想合并某个分支的一部分代码,可以使用以下两种方法: 1.批量文件合并 1.1.创建并切换到一个新的临时分支 ...

  8. jsp中无法识别EL表达式问题

    今天在开发系统时需要在JSP中遍历List<javabean>,其中用到了EL表达式:${item.value} 页面死活不出数据,只显示表达式本身:${item.value}. 页面代码 ...

  9. JVM之直接内存与非直接内存

    直接内存 直接内存:概指系统内存,而非堆内存,不指定大小时它的大小默认与堆的最大值-Xmx参数值一致. 非直接内存: 也可以称之为堆内存,运行JVM都会预先分配一定内存,我们把JVM管理的这些内存称为 ...

  10. Detours 的使用

    Detours 是一个用于在 ARM, ARM64, X86, X64 和 IA64 机器上拦截二进制函数的库. Detours 最常用来拦截应用程序中的 win32 api 调用,比如添加调试工具. ...