20221213-BMP格式结构

docs.microsoft.com/zh-cn/windows/win32/gdibitmap-storage

简介

bmp 图形文件是windows 采用的图形文件格式,在windows 环境下运行的所有图像处理软件都支持BMP 图像文件格式,windows 系统内部各图像绘制操作都是以BMP 为基础的

因此把这种BMP 图像文件格式称为设备相关位图 DDB 文件格式,
目的是为了人windows 能够在任何类型的显示设备上显示所存储的图像

bmp 位图文件默认的文件扩展名是bmp

BMP 格式结构

BMP 文件的数据按照从文件头开始的先后顺序分为四个部分

位图文件头,提供文件的格式 大小等信息

位图信息头 提供图像数据的尺寸,位平面数,压缩方式,颜色索引等信息

调色板 可选,如使用索引来表示图像,调色板就是索引与其对饮的颜色的映射表

位图数据 图像数据区

BMP图片文件数据表如下:

数据段名称
大小(byte)
开始地址
结束地址
位图文件头(bitmap-file header)
14
0000h
000Dh
位图信息头(bitmap-information header)
40
000Eh
0035h
调色板(color table)
由biBitCount决定
0036h
未知
图片点阵数据(bitmap data)
由图片大小和颜色定
未知
未知

三、BMP 文件头

BMP文件头结构体定义如下:
typedef struct tagBITMAPFILEHEADER
{
UINT16 bfType; //2Bytes,必须为”BM”,即0x424D 才是Windows位图文件
DWORD bfSize; //4Bytes,整个BMP文件的大小
UINT16 bfReserved1; //2Bytes,保留,为0
UINT16 bfReserved2; //2Bytes,保留,为0
DWORD bfOffBits; //4Bytes,文件起始位置到图像像素数据的字节偏移量
} BITMAPFILEHEADER;

BMP文件头数据表如下:

变量名
地址偏移
大小
作用说明
bfType
0000h
2Bytes
文件标识符,必须为”BM”,即0x424D 才是Windows位图文件
‘BM’:Windows 3.1x, 95, NT,…  ‘BA’:OS/2 Bitmap Array  ‘CI’:OS/2 Color Icon   
‘CP’:OS/2 Color Pointer   ‘IC’:OS/2 Icon   
‘PT’:OS/2 Pointer
因为OS/2系统并没有被普及开,所以在编程时,你只需判断第一个标识“BM”就行
bfSize
0002h
4Bytes
整个BMP文件的大小(以位B为单位)
bfReserved1
0006h
2Bytes
保留,必须设置为0
bfReserved2
0008h
2Bytes
保留,必须设置为0
bfOffBits
000Ah
4Bytes
说明从文件头0000h开始到图像像素数据的字节偏移量(以字节Bytes为单位),以为位图的调色板长度根据位图格式不同而变化,可以用这个偏移量快速从文件中读取图像数据

四、BMP 信息头

BMP信息头结构体定义如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
typedef struct _tagBMP_INFOHEADER
{
DWORD biSize; //4Bytes,INFOHEADER结构体大小,存在其他版本I NFOHEADER,用作区分
LONG biWidth; //4Bytes,图像宽度(以像素为单位)
LONG biHeight; //4Bytes,图像高度,+:图像存储顺序为Bottom2Top,-:Top2Bottom
WORD biPlanes; //2Bytes,图像数据平面,BMP存储RGB数据,因此总为1
WORD biBitCount; //2Bytes,图像像素位数
DWORD biCompression; //4Bytes,0:不压缩,1:RLE8,2:RLE4
DWORD biSizeImage; //4Bytes,4字节对齐的图像数据大小
LONG biXPelsPerMeter; //4 Bytes,用象素/米表示的水平分辨率
LONG biYPelsPerMeter; //4 Bytes,用象素/米表示的垂直分辨率
DWORD biClrUsed; //4 Bytes,实际使用的调色板索引数,0:使用所有的调色板索引
DWORD biClrImportant; //4 Bytes,重要的调色板索引数,0:所有的调色板索引都重要
}BMP_INFOHEADER;

变量名
地址偏移
大小
作用说明
biSize
000Eh
4Bytes
BNP信息头即BMP_INFOHEADER结构体所需要的字节数(以字节为单位)
biWidth
0012h
4Bytes
说明图像的宽度(以像素为单位)
biHeight
0016h
4Bytes
说明图像的高度(以像素为单位)。这个值还有一个用处,指明图像是正向的位图还是倒向的位图,该值是正数说明图像是倒向的即图像存储是由下到上;该值是负数说明图像是倒向的即图像存储是由上到下。大多数BMP位图是倒向的位图,所以此值是正值。
biPlanes
001Ah
2Bytes
为目标设备说明位面数,其值总设置为1
biBitCount
001Ch
2Bytes
说明一个像素点占几位(以比特位/像素位单位),其值可为1,4,8,16,24或32
biCompression
001Eh
4Bytes
说明图像数据的压缩类型,取值范围为:
0 BI_RGB 不压缩(最常用)
1 BI_RLE8 8比特游程编码(BLE),只用于8位位图
2 BI_RLE4 4比特游程编码(BLE),只用于4位位图
3 BI_BITFIELDS比特域(BLE),只用于16/32位位图
4
biSizeImage
0022h
4Bytes
说明图像的大小,以字节为单位。当用BI_RGB格式时,总设置为0
biXPelsPerMeter
0026h
4Bytes
说明水平分辨率,用像素/米表示,有符号整数
biYPelsPerMeter
002Ah
4Bytes
说明垂直分辨率,用像素/米表示,有符号整数
biClrUsed
002Eh
4Bytes
说明位图实际使用的调色板索引数,0:使用所有的调色板索引
biClrImportant
0032h
4Bytes
说明对图像显示有重要影响的颜色索引的数目,如果是0,表示都重要。

BMP 调色板

BMP调色板结构体定义如下:
typedef struct _tagRGBQUAD
{
BYTE rgbBlue; //指定蓝色强度
BYTE rgbGreen; //指定绿色强度
BYTE rgbRed; //指定红色强度
BYTE rgbReserved; //保留,设置为0
} RGBQUAD;

1,4,8位图像才会使用调色板数据,16,24,32位图像不需要调色板数据,即调色板最多只需要256项(索引0 - 255)。
颜色表的大小根据所使用的颜色模式而定:2色图像为8字节;16色图像位64字节;256色图像为1024字节。其中,每4字节表示一种颜色,并以B(蓝色)、G(绿色)、R(红色)、alpha(32位位图的透明度值,一般不需要)。即首先4字节表示颜色号1的颜色,接下来表示颜色号2的颜色,依此类推。
颜色表中RGBQUAD结构数据的个数有biBitCount来确定,当biBitCount=1,4,8时,分别有2,16,256个表项。
当biBitCount=1时,为2色图像,BMP位图中有2个数据结构RGBQUAD,一个调色板占用4字节数据,所以2色图像的调色板长度为24为8字节。
当biBitCount=4时,为16色图像,BMP位图中有16个数据结构RGBQUAD,一个调色板占用4字节数据,所以16像的调色板长度为16
4为64字节。
当biBitCount=8时,为256色图像,BMP位图中有256个数据结构RGBQUAD,一个调色板占用4字节数据,所以256色图像的调色板长度为256*4为1024字节。
当biBitCount=16,24或32时,没有颜色表。

BMP 图像数据区

位图数据记录了位图的每一个像素值,记录顺序是在扫描行内是从左到右,扫描行之间是从下到上。位图的一个像素值所占的字节数:
当biBitCount=1时,8个像素占1个字节;
当biBitCount=4时,2个像素占1个字节;
当biBitCount=8时,1个像素占1个字节;
当biBitCount=24时,1个像素占3个字节;
Windows规定一个扫描行所占的字节数必须是4的倍数(即以long为单位),不足的以0填充,
一个扫描行所占的字节数计算方法:

235.125
264 * 8 = 2112 个像素
33 + 31
57 + 31

DataSizePerLine= (biWidth* biBitCount+31)/8;
// 一个扫描行所占的字节数
DataSizePerLine= DataSizePerLine/44; // 字节数必须是4的倍数
位图数据的大小(不压缩情况下):
DataSize= DataSizePerLine
biHeight;

颜色表接下来位为位图文件的图像数据区,在此部分记录着每点像素对应的颜色号,其记录方式也随颜色模式而定,既2色图像每点占1位(8位为1字节);16色图像每点占4位(半字节);256色图像每点占8位(1字节);真彩色图像每点占24位(3字节)。所以,整个数据区的大小也会随之变化。究其规律而言,可的出如下计算公式:图像数据信息大小=(图像宽度图像高度记录像素的位数)/8。

20221213-USB协议简析

https://zhuanlan.zhihu.com/p/431163780

USB 4将我的这种想法给部分实现,通过一种隧道技术的方式,将DP/USB3/PCIe信号集成到通信隧道里面去,接收端再通过数据包头来区分数据(这就有点像交换机里的数据分发,通过MAC地址或者报文帧头确定数据包目的地)。

因为硬件的局限性和可能的分发芯片性能功能问题,每个分发数据的协议速率是由各自的上限的,不能够动态调整每个接口的最大速度,

USB与I2C/SPI/UART类似,都是一种传输数据的协议规范,但USB主要设计是用于计算机与外接设备的数据交互和文件传输,这一点也正是它现在演变为相对高速的对外接口的原因,最高速的当然是PCIe。

特点

服务器交换机目前还是使用USB 2.0 居多

USB 3 开始和typeC 结合,将曾经的文件传输接口增加为文件加视频传输接口,并且视频一上来就是最新的DP 接口

USB 4,这兄弟更猛,除了USB、DP,还额外增加了PCIe的功能,1 LANE支持到10Gbps,通过隧道技术来最大限度发挥物理带宽性能,这个还没有开始投向商用,应该还要一两年。

技术细节

USB 3.2

就只有 type-C

pin location pin name function

USB2.0 数据信号4个,其实是两个,为了满足正反插需求所以正反都有

USB3.2 数据信号8个,包含两个通道的差分收发信号,VBUS 信号4个,GND 信号4个,一个8个信号处理电源
CC 信号两个,SBU 信号两个

全称Configuration Channel,分为CC1和CC2,在type C接口被引用,主要是为了解决正反插的信号交错问题和侦测插入的接口类型。

目前主要是在source端设计上拉电阻,sink端设计下拉电阻,通过不同电阻的配比来表示当前的设备类型和插入方式。具体方式比较复杂,参考type C spec里的两个截图,两个CC信号用来侦测正反插情况和设备信息。以后有机会调试CC信号再深入了解。

SBU信号是为USB 4.0 预留的,3.2里没有用到这个信号,不过这两个信号又在Alternate Mode(主要是DP)和Audio Adapter Accessory Mode里有使用,后面讲到这两个模式再具体分析。

信号完整性

此时开始引入redriver 来解决信号完整性的问题

repeater 分为两种,redriver 和retimer

retimer 指的是这种器件包含有CDR 电路,可以重新编码信号,好处是不会引入一些高频抖动

Redriver 指的是器件使用模拟电路的方式来增强信号,不会对码流进行操作,中间会有均衡放大和发送的部分

一个链路中能够使用的repeater个数是没有限制的,只要总体的时延和抖动能够满足要求,但一般是sink和source端各自处理自己接口上的信号质量,能满足协议规范就可以了,如果是cable厂商,可能也需要在cable中集成一到两个repeater。

USB 4.0

对于USB 4 来说,规定了一种可以同时传输三种通信协议的方式,但这是在芯片内部或者协议端实现的,物理层和逻辑层与所谓的通道互相独立,传输层和配置层需要针对通道方式做出改变

隧道技术采用了TMUS 来处理每一个交换功能,网上并不能看到太多有关这个技术的细节,但从上面的分析,有理由得出一下的猜测

TMUs位于芯片内部或者就是纯软件,与USB 4 协议是配套使用,在物理层和传输层没有体现
由第一点,如果device端是USB 4,则也需要集成TMU,如果只是三种协议中的一种,就要看host端是否有向下兼容的能力(USB3和DP是必须的,PCIe目前是可选)。
再来看下图就会对USB 4的整个拓扑有更多的了解。

简单来说,USB 4 host可以直接支持USB 3x,DP,PCIe的device;也可以通过USB Hub的方式去fan out直接输出USB 4隧道信号,让Hub来分发;更可以直接插入支持USB 4 的device来一根cable传输这三个协议的信号。

第一张图里有看到,不同的协议影响的是红圈中的设计,也即Adapter的选择;在USB 4的整个通信过程中,这些具体的协议是已经在比较上层的地方,所以对于不同协议的支持,需要做的有两点:

在USB 4 的block内有对应支持的协议种类的Adapter
在USB 4 与CPU更上层的连接中有对应的通信路径,例如PCIe需要有PCIe Switch或者链接到Root Port的Root Complex
当满足以上两点,从芯片对外提供的USB 4 interface上来看,它就可以支持所有的四种协议:USB 4,USB 3,DP,PCIe(目前只到Gen 1),根据插入的设备类型做到向下兼容。

SBU 信号

SBU 在usb4开始被引入,速度为1Mbps 有三个功能

配置USB4通道,进行初始化

和retimer进行交互,完成USB 4 Link TxFFE的握手
确保USB 4 通道的发送和retimer的上电或者wake up sequence的正确完成
与TMT3的兼容
Thunderbolt™ 3是Intel发布的Light Peak技术。Thunderbolt连接技术融合了PCI Express(PCI-E)数据传输技术和Display Port(DP)显示技术,可以同时对数据和视频信号进行传输。

具体细节不展开了,有一个点需要注意,当以兼容TMT3模式运行时,adapter需要在TBT3兼容的速度下运行,也即Gen 2 是10.3125Gbps,Gen 3 是20.625Gbps。

20221213-数字芯片中使能信号的作用

  1. 什么是使能信号,

所谓使能信号,英文叫enable 翻译成中文还有启用等意思

如图所示,当G1为低电平的时候,不管其它输入是什么。输出全为高电平。而当G2为高电平时(G2等于G2A与上G2B),不管其它输入是什么,输出也都一律为高电平。因此仅从功能上来判断,G1和G2就可以控制这颗芯片是不是被“启用”了。可以看出当G1为低或G2位高时,整个芯片的其它输入无论如何变化都不影响输出。简单的说就是整个芯片实际上没用发挥作用,功能没有“启用”。

  1. 为什么使能信号可以控制芯片的启用和停用

全部都连到了最后一级的所有与非门上。我们知道一个与非门,如果有1个输入为0,那么这个与非门的输出就会是1。因此,如果不满足G1为高电平,G2A和G2B都为低电平这个条件,就会让所有输出全为1。而这时无论别的输入是什么,都不会让输出有任何改变。从这一点上来说,要启用这颗芯片的功能就必须满足G1为高电平,G2A和G2B都为低电平这个条件。否则,其它输入影响不了输出,芯片“译码”的功能就没有被“启用”。

  1. 为什么需要使能信号

需要使能信号的主要原因是一个大型的数字系统中,通常都需要使用多个芯片/电路单元来配合完成一个功能,而这些芯片并不是每时每刻都在工作,因此需要用使能信号来控制硬功启用那个芯片来工作

假设4bit的二进制编码从高到低依次是A3A2A1A0

将A2A1A0分别对应连接到两片74XX138上。而将A3连接到低位片的G2B上和高位片的G1上。

这样我们实际上把4bit的二进制数据划分为了2段

其中一段从0000到0111,另外一段从1000到1111。当现在A2A1A0为111时,低位片的Y7和高位片的Y7都有可能输出。而假设此时A3为0(此时输入为0111),那么低位片的所有使能信号均有效,而高位片的G1是无效的。那么此时低位片被启用而高位片未被启用。所以低位片的Y7输出为低而其它均为高,高位片的所有输出都是高。因此,0111被译码为了1111111101111111(输出低有效)。反之,A3为1(此时输入为1111)。则低位片的G2B无效而高位片所有的使能信号都有效。1111倍译码为0111111111111111

  1. 使能信号还有哪些用法

使能信号的用途非常广泛,可以作为计算机系统中存储芯片选通信号,可以作为显式系统中的控制信号,但核心的一点就是使能信号控制了芯片的功能是否能被正常的启用,这在设计大型的数字系统中是非常重要的一环

20221213-RS485通讯基础及通讯应用详解

https://zhuanlan.zhihu.com/p/341845459

举例:plc向变频器从机1和变频器从机2传递数据,首先变频器从机1和变频器从机2设备之间必须通过电缆连接(硬件连接)。如果变频器从机1和变频器从机设备发送101010这样一串代码,那么变频器从机1就要在他的通讯端口产生如下图所示的高低电平的组合,通过电缆这个介质变频器从机2设备的通讯端口就会接收到A设备发出高低电平的组合,同时就会将接

RS-485概述

RS-485和RS-232一样,都是串行通信标准,现在的标准名称是TIA485/EIA-485-A,但是人们会习惯称为RS-485标准,RS-485常用在工业、自动化、汽车和建筑物管理等领域。

RS-485总线弥补了RS-232通信距离短,速率低的缺点,RS-485的速率可高达10Mbit/s,理论通讯距离可达1200米;RS-485和RS-232的单端传输不一样,是差分传输,使用一对双绞线,其中一根线定义为A,另一个定义为B。

双绞线

RS-485物理层

RS-485的物理层负责在设备和物理传输介质之间传输原始数据。它处理电信号到数字数据的转换,同时定义电压、时序、数据速率等。

① 差分信号

长距离布线会有信号衰减,而且引入噪声和干扰的可能性更大,在线缆A和B上的表现就是电压幅度的变化,但是,采用差分线的好处就是,差值相减就会忽略掉干扰依旧能输出正常的信号,把这种差分接收器忽略两条信号线上相同电压的能力称为共模抑制。

标准规定了,逻辑1:+2V to +6V;逻辑0:-6V to -2V。

RS-485不需要使用特定的总线电压,只看最小差分电压,在较长的电缆长度上,接收器接收到的电压可能会降低到+/- 200 mV,这对于RS-485仍然是完全可以接受的,这也是RS-485的优点之一。

很多收发器的标准达到甚至超过TIA/EIA-485A规范,在实际使用中,以器件的SPEC参数为主,如下某收发器的负输入阈值最小也是-200mV。

② 信号定义

现在很多的RS-485转换器都是兼容RS-422的,所以看到很多转换器上面的信号都是T/R+、T/R-,即对应RS-485的A+和B-。

对于DB9针型的母头,RS-485有如下的接线定义示意,Pin6~Pin9为N/A不接。

DB9 输出信号 RS-422全双工接线 RS-485半双工接线
1 T/R+ 发(A+) RS-485(A+)
2 T/R- 发(B-) RS-485(B-)
3 RXD+ 收(A+) 空
4 RXD- 收(B-) 空
5 GND 地线 地线

③ 拓扑结构

RS485有两线制和四线制两种接线,四线制只能实现点对点的通信方式,现很少采用,多采用的是两线制接线方式,这种接线方式为总线拓扑结构,在同一总线上最多可以挂接32个节点。

RS-485总线同I2C,也是主从模式,支持点对点单从机模式,也支持多从机模式,不支持多主机模式。

RS-485收发器

RS-485是差分传输,如果用单片机控制RS-485接口的设备,需要用到收发器,这一点和CAN总线是类似的,如下是一个MCU控制一个RS-485的图示。

收发器内部是一个接收器(上半部分)加一个发送器(下半部分),下面简单说说收发器的原理,便于理解MCU是如何和485设备通信的。

RS-485收发器内部结构

其中:

A和B为总线;
R为接收器输入;
RE为接收器使能信号;
DE为发送器使能信号;
D为发送器输出;
对于使能信号,字母上面加一横的为低电平有效(如上图RE),不加的为高电平有效(如DE)。

对于发送器,有如下的真值表:

1、当驱动器使能引脚DE为逻辑高时,差分输出A和B遵循数据输入D处的逻辑状态。D处的逻辑高导致A转为高,B转为低。在这种情况下,定义为VOD=VA-VB的差分输出电压为正。当D为低时,输出状态反转,B变高,A变低,VOD为负。

2、当DE低时,两个输出都变成高阻抗。在这种情况下,与D处的逻辑状态是不相关的。

发送器真值表

对于接收器,有如下的真值表:

1、当接收器使能引脚RE逻辑低时,接收器被激活。当定义为VID=VA–VB的差分输入电压为正且高于正输入阈值VIT+时,接收机输出R变高。当VID为负且低于负输入阈值VIT-,接收机输出R变低。如果VID在VIT+和VIT-之间,则输出不确定。

2、当RE为逻辑高或悬空时,接收机输出为高阻抗,VID的大小和极性无关。

接收器真值表

RS-485数据链路

上面讲到的RS-485收发器的工作原理,下面简单描述RS-485的数据链路,可以先看一下通俗易懂的UART协议帧格式

主机发送给从机或者从机发送给主机,都会占用到A和B线,所以RS-485多用在半双工模式。

主机的GPIO会控制RS-485收发器的DE管脚,设置发送模式,从UART TXD线向RS-485收发器的数据(D或DI)线发送一个字节,收发器将在A和B线上将单端UART位流转换为差分位流,数据离开收发器后,主机立即将收发器的模式切换为接收模式。

从机和主机是类似的,从机控制RS-485收发器的/RE管脚,设置为接收模式,接收主机发送的比特流,将其转换为单端信号,通过从机的UART RXD线接收,当从机准备好响应时,它按主机原来的方式进行发送,而主机变为接收。

RS-232和RS-485转换

RS-232和RS-485之间可以转换,一个方法是RS-232转换成TTL,再由TTL转换为RS-485,当然也有芯片支持将RS-232直接转换成RS-485,网上有很多模块。

RS-232和RS-485转换模块

RS-485和CAN的区别

虽说RS-485没有标准的数据协议格式,但和CAN总线在很多地方是有相似的,比如A&B和CANH&CANL都是差分信号,通信都需要收发器,都需要120欧姆的匹配电阻等等。

总线特性 CAN总线 RS-485总线
硬件成本 稍高 低廉
总线利用率 优先级自动仲裁,利用率高 采用轮询,利用率低
数据传输率 高 低
错误检测机制 控制器带校验机制,保证底层数据传输正确 只有物理层规范,无数据链路层规定
单节点故障影响 总线无影响 总线瘫痪
开发成本 软件开发灵活,时间成本低 开发难度较大
系统成本 较低 高

RS-485常用电路

网上找的一个常用的RS-485电路,其中需要注意两点:

1、使能信号RE和DE可采用一个GPIO控制,节省资源,GPIO25输出高电平,RE=DE=0V,进入接收模式;GPIO25输出低电平,RE=DE=3.3V,进入发送模式。

2、有一些电路中会在A上加上拉,B上加下拉电阻,主要原因是:RS-485总线在idle状态,电平是不固定的,即电平在-200mV~+200mV之间,收发器可能输出高也可能输出低,UART在空闲时需要保持高电平的,如果此时收发器输出一个低电平,对UART来说是一个start bit,会导致通信异常,关于Ru和Rd的阻值在这里不作过多赘述,后面有机会会详细写一篇文章。

关于第二点,需要注意:

① A上加上拉,B上加下拉,接反数据通信也可能出错。

② 某些收发器内部集成上下拉电阻,则外部不需要再添加。

今天的文章内容到这里就结束了,希望对你有帮助,我们下一期见。

20221213-UART串口通信介绍

串口通信 UART 介绍

通用异步收发传输器 ,通常称作UART ,是一种异步收发传输器

首先先来介绍一下同步和异步通信

在常见通信总线协议中,I2C SPI 属于同步通信而UART 属于异步通信

在UART 通信中,数据起始位和停止位是必不可少的

硬件层

常用RS-232标准,这里不详细解释,主要是对应设备的Tx 线和Rx 线要对应正确

协议层

协议层中,规定了数据包的内容,它由起始位,主体数据,校验位以及停止位组成,通信双方的数据包格式要约定一致才能正常收发数据

波特率 异步通信中由于没有时钟信号,所以2个通信设备需约定好波特率,常见的有4800 9600 15200 等

通信的起始和停止信号,串口通信的一个数据包从起始信号开始,知道停止信号结束,数据包的起始信号由一个逻辑0 的数据位表示,而数据包的停止信号可由0.5 1 1.5 2 个逻辑1 的数据位表示,只要双方约定一致即可

有效数据,在数据包的起始位置之后紧接着的就是要传输的主体数据内容,也称为有效数据,有效数据的长度常被约定为8位或9位长

数据校验 可以在传输过程中加上校验位来解决这个问题,校验方法有奇校验 偶校验 0校验 1校验 以及无校验

奇校验要求有效数据和校验位中“1”的个数为奇数,比如一个 8 位长的有效数据为:01101001,此时总共有 4 个“1”,为达到奇校验效果,校验位为“1”,最后传输的数据将是 8 位的有效数据加上 1 位的校验位总共 9 位。偶校验与奇校验要求刚好相反,要求帧数据和校验位中“1”的个数为偶数,比如数据帧:11001010,此时数据帧“1”的个数为 4 个,所以偶校验位为“0”。0 校验是不管有效数据中的内容是什么,校验位总为“0”,1 校验是校验位总为“1”。

UART 功能框图剖析

这张图是当年上学时使用system C 对uart 建模的模块图,对于接口部分,重要的即为Tx Rx 数据输出,接受接口,clk 提供波特率生成模块的初始时钟信号,

有关控制器部分,在这里使用逻辑电路来实现,具体控制输出/接收使能,设备使能等

在目前的微控制器上,数字电路控制部分已被封装,现在只需要操作对应寄存器的对应位即可实现对UART 的控制
下图是uart 框图

波特率生成模块

USART 的发送器和接收器使用相同的波特率,有以下的计算公式

其中,fck为 USART 时钟, USARTDIV 是一个存放在波特率寄存器(USART_BRR)的一个无符号定点数。其中 DIV_Mantissa[11:0]位定义 USARTDIV 的整数部分,DIV_Fraction[3:0]位定义 USARTDIV 的小数部分。

例如:DIV_Mantissa=24(0x18),DIV_Fraction=10(0x0A),此时 USART_BRR 值为0x18A;那么USARTDIV的小数位10/16=0.625;整数位24,最终USARTDIV的值为24.625。

波特率的常用值有 2400、9600、19200、115200。下面以实例讲解如何设定寄存器值得到波特率的值。我们知道 USART1 使用APB2总线时钟,最高可达72MHz,其他USART的最高频率为36MHz。我们选取USART1作为实例讲解,即fck=72MHz。为得到115200bps的波特率,此时:115200=72000000/(16∗USARTDIV),解得USARTDIV=39.0625,可算得DIV_Fraction=0.0625*16=1=0x01,DIV_Mantissa=39=0x27,即应该设置USART_BRR的值为0x171。

数据寄存器

UART 数据寄存器 只有低9位有效,并且第9位 数据是否有效要取决于uart 控制寄存器1的M 位设置,当M 位为0 时表示8位数据字长,当M 位为1 表示9位数据字长,我们一般使用8位数据字长

USART_DR包含了已发送的数据或者接收到的数据。USART_DR实际是包含了两个寄存器,一个专门用于发送的可写TDR,一个专门用于接收的可读RDR。当进行发送操作时,往USART_DR写入数据会自动存储在TDR内;当进行读取操作时,向USART_DR读取数据会自动提取RDR数据。

TDR和RDR都是介于系统总线和移位寄存器之间。串行通信是一个位一个位传输的,发送时把TDR内容转移到发送移位寄存器,然后把移位寄存器数据每一位发送出去,接时把接收到的每一位顺序保存在接收移位寄存器内然后才转移到RDR。

UART支持DMA传输,可以实现高速数据传输(不经过CPU),使能UART的DMA功能需要将USART_CR1寄存器DMAT位置1。

控制器

UART 有专门控制发送的发送器,控制接收的接收器,还有唤醒单元,中断控制等,使用uart 之前需要向 usart_CR1 寄存器的ue位置使能UART UE 位用于开启供给串口的时钟

发送器

当USART_CR1寄存器的发送使能位TE置1时,启动数据发送,发送移位寄存器的数据会在TX引脚输出,低位在前,高位在后。

一个字符帧发送需要3部分,起始位 数据帧 停止位,起始位是一个位周期的低电平,位周期就是每一位占用的时间,数据帧就是我们要发送的8 或9 位数据,数据是最低位开始传输的,停止位是一定时间周期的高电平

停止位的时间长短可以通过UART控制寄存器2(USART_CR2)的STOP[1:0]位控制,可选0.5个、1个、1.5个、2个停止位。默认使用1个停止位。2个停止位适用于正常USART模式、单线模式和调制解调器模式。0.5和1.5个停止位用于智能卡模式。

当发使能位TE置1之后,发送器开始会发送一个空闲帧(一个数据帧长度的高电平),接下来就可以往USART_DR寄存器写入要发送的数据。在写入最后一个数据后,需等待UART状态寄存器(USART_SR)的TC位为1,表示数据传输完成。USART_CR1寄存器的TCIE位置1,则产生中断。

发送数据时,几个重要的标志位如下

TE 发送使能
TXE 发送寄存器为空,发送单个字节时使用
TC 发送完成,发送多个字节数据时候使用
TXIE 发送完成中断使能

接收器

将CR1寄存器的RE位置1,使能USART接收,使得接收器在RX线开始搜索起始位。在确定起始位后,就根据RX线电平状态把数据存放在接收移位寄存器内。接收完成后就把接收移位寄存器的数据移到PDR内,并把USART_SR寄存器的RXNE位置。如果USART_CR2寄存器的RXNEIE置1可以产生中断。

接收数据时,几个重要的标志位如下

RE 接收使能
RXNE:读数据寄存器非空。

RXNEIE:发送完成中断使能。

USART_CR1寄存器:
USART_CR2寄存器:
USART_CR3寄存器:

之后会基于STM32继续介绍怎样配置并使用UART,包括串口轮询/中断/DMA方式发送/接收数据。

20221213-VGA显示图像详细总结

https://blog.csdn.net/weixin_44406200/article/details/103823607

VGA 显示原理

VGA 概念

VGA 不是用来显示的那块屏幕,而是用来传输信号的接口,VGA 全称是video graphics array 及视频图形阵列,是模拟信号的一种视频传输标准,VGA 传输接口实物图如下

自测试 地址码 蓝基色 绿基色 红基色

数字地 蓝地 绿地 红地
地址码 场同步 行同步 地址码 地址码

操作VGA 的过程就是给你一块有横纵坐标范围的区域,区域上的每一个坐标点就是一个像素点,你可以做的事情是给这个像素点特定的rgb 色彩,既可以通过自定义rgb 也可以去取图像某个像素点的rgb ,这也就提供了你在vga 上画图以及显示图片的能力

VGA 分辨率及理解误区

640 * 480 的规格就是显示屏幕上每行有640 个像素点,总共有480行,注意,一件很重要的事情是,虽然你看到的屏幕上的大小是640 * 480 的 但是它实际大小并不只有那么点,形象一点就是说,VGA 的扫描范围是包含了你能够看到的640 480 这一块区域的更大区域,他会在周围一圈你看不到的区域部分进行扫描,因此,我们在处理扫描信号的时候一定要注意只有扫描到有效区域的时候才能把像素点数据传给 VGa 显示

VGA 显示器扫描方式从屏幕左上角一点开始,从左向右逐点扫描,每扫描完一行,电子束回到屏幕的左边下一行的起始位置,在这期 间,CRT 对电子束进行消隐,每行结束时,用行同步信号进行同步,当扫描完所有的行,形成一帧,用场同步信号进行场同步,并使扫描回到屏幕左上方,同时进行场消隐,开始下一帧,完成一行扫描的时间称为水平扫描时间,其倒数称为行频率,完成一帧,扫描的时间称为垂直扫描时间,其倒数称为场频率,及屏幕的刷新频率,其扫描示意图如下图所示

有效显示区域

关于那一块非有效显示区域,实际上是因为每一行和每一列的扫描区间都是由以下几部分组成

行扫描 Hor Sync 、Hor Back Porch 、Hor Active Video和Hor Front Porch

Hor Scan Time 是一个扫描周期,它会先扫描到hor sync 再扫描 hor back porch 然后才进入有效显示区 hor active video 最后是一段 hor front porch 可以看出来,四段区间只有hor active video 这一段是能够正常显示图像信息的,也就是屏幕上显示的那一块区间

列扫描也同理

给定参数

实际上,根据固定的分辨率大小,比如我们实验室的板子使用的640 480 的屏幕大小,这些非有效区间的长度值都是一个固定的常数,因此你只要在扫描的时候把这些常数稍加处理即可

下图罗列了不同分辨率所对应的各个参数,其中的a、b、c、d、e、f、g、h、i、k的含义,与上面给出的两张图的标注一一对应;我们实验使用的是第一组数据,可以看到行时序参数中的c代表每一行的有效显示区间640,列时序参数中的h代表每一列的有效显示区间480

需要扫描频率,很重要的一件事,无论是行扫描还是给像素点赋值,我们都需要用一个时钟,这个时钟不是系统时针,必须要先将50MHZ 的时钟分频为25MHZ 然后拿去作为扫描信号的时钟

这一点是特别需要注意的,否则到时候会出现out of range 的现象

前期准备 coe 文件的生成

coe 和ip 核介绍

我们调用VGA 的终极目标是想要能够显示一张图片,在这之前,我们要先对这张图片进行一些预处理,因为我们是通过verilog 语言去调用图片数据的,但是verilog 并不知道怎么从一张已有的图片上去取相应的数据

因此我们要先将图片转换为coe 文件,coe 文件实际上就是按照某种规律将图像每一个像素点的rgb 数据都摆放成单独一行 16进制,然后借助ISE 的IP 核生成将coe 文件转化成ROM ,生成的ROM.xco 和ROM.v 文件就可以被verilog 语言所识别调用,最终就能够取到图像的数据了

24位bmp 图像转换为coe 文件 复原代码

为了统一规范,这里我们使用24位真彩色的bmp 格式图像进行转换,好处是,bmp 的三通道数据特征是非常明显的,易于处理

如何获取24位bmp 图像

然后bmp 格式也有很多种,如单色 16色 24 256 ,这里我们统一选择24位位图选项,点击保存即可

使用matlab 将24位真彩色bmp 位图转化为coe 文件

由于24位共rgb 三个通道,每个通道分到的是8位,占用资源太多,且老师给的ucf 引脚约束对rgb 每一个通道只给了4位,因此我们在转化为coe 文件的同时,要将每个通道压缩成4位,即整张图像同时转化为12位

压缩图像是一件非常重要的事情,因为经过后续的实践我们发现,板子内存资源有限,无法同时加载多张大图

为了能够对多张图像进行批量处理,我使用matlab 写了一个 img2coe.m 函数,只要对bmp 图像调用这个函数即可转换成coe 文件了,转换过程介绍如下

先将rgb 提取为三个通道,用reshape 函数对转置后的矩阵进行重组,对rgb 三个分量的数据都右移,舍去细节,留下高四位作为最终的数据,然后写入到coe 文件中

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
function img2coe(path,name)
% 利用imread函数把图片转化为一个三维矩阵
image_array = imread(path);

% 利用size函数把图片矩阵的三个维度大小计算出来
% 第一维为图片的高度,第二维为图片的宽度,第三维为图片的RGB分量
[height,width,z]=size(image_array);

red = image_array(:,:,1); % 提取红色分量,数据类型为uint8
green = image_array(:,:,2); % 提取绿色分量,数据类型为uint8
blue = image_array(:,:,3); % 提取蓝色分量,数据类型为uint8

% 把上面得到了各个分量重组成一个1维矩阵,由于reshape函数重组矩阵的
% 时候是按照列进行重组的,所以重组前需要先把各个分量矩阵进行转置以后再重组
% 利用reshape重组完毕以后,由于后面需要对数据拼接,所以为了避免溢出
% 这里把uint8类型的数据扩大为uint32类型
r = uint32(reshape(red' , 1 ,height*width));
g = uint32(reshape(green' , 1 ,height*width));
b = uint32(reshape(blue' , 1 ,height*width));

% 初始化要写入.coe文件中的RGB颜色矩阵
rgb=zeros(1,height*width);

% 因为导入的图片是24-bit真彩色图片,每个像素占用24-bit,其中RGB分别占用8-bit
% 而我这里需要的是12-bit,其中R为4-bit,G为4-bit,B为4-bit,所以需要在这里对24-bit的数据进行重组与拼接
% bitshift()函数的作用是对数据进行移位操作,其中第一个参数是要进行移位的数据,第二个参数为负数表示向右移,为
% 正数表示向左移,更详细的用法直接在Matlab命令窗口输入 doc bitshift 进行查看
% 所以这里对红色分量先右移4位取出高4位,然后左移11位作为ROM中RGB数据的第11-bit到第8-bit
% 对绿色分量先右移4位取出高4位,然后左移5位作为ROM中RGB数据的第7-bit到第4-bit
% 对蓝色分量先右移4位取出高4位,然后左移0位作为ROM中RGB数据的第3-bit到第0-bit
for i = 1:height*width
rgb(i) = bitshift(bitshift(r(i),-3),11) + bitshift(bitshift(g(i),-2),5) + bitshift(bitshift(b(i),-3),0);
end

fid = fopen( name , 'w+' );

% .coe文件的最前面一行必须为这个字符串,其中16表示16进制
fprintf( fid, 'memory_initialization_radix=16;\n');

% .coe文件的第二行必须为这个字符串
fprintf( fid, 'memory_initialization_vector =\n');

% 把rgb数据的前 height*width-1 个数据写入.coe文件中,每个数据之间用逗号隔开
fprintf( fid, '%x,\n',rgb(1:end-1));

% 把rgb数据的最后一个数据写入.coe文件中,并用分号结尾
fprintf( fid, '%x;',rgb(end));

fclose( fid ); % 关闭文件指针
end

中期准备 coe 转换为rom

经过上面的步骤我们已经得到了coe 文件

接下来就是把它转化成verilog 能够调用的rom 文件了

在ISE 工程中,点击右键新建文件,选择ip 核生成

选择Memories选项中的RAMs&ROMs里的Block Memory Generator

然后进入到这个设置参数的界面

其中width代表你设置的图片数据是几进制,由于之前写coe的时候是用16进制写的,因此这里写16;depth表示图像的大小,即长乘宽,由于我使用的是640480的图片,因此这里填207200(=640480)

当你的文件路径成功出现的时候,你就可以点击下方的generate生成了,当然这个generate也要很久很久,一般一张640 *480的图片要generate近一个小时左右才能生成

生成完毕的标志是creating结束,并且在你的目录下出现类型太阳的这个标记

后期调用与测试

VGA 显示的过程中会遇到很多小bug 有些小bug 的原因你根本找不出,比如 out of range ,你只能静下心来慢慢调试仿真

20221212-SPI协议详解

https://zhuanlan.zhihu.com/p/290620901

UART 没有时钟信号,无法控制何时发送数据,也无法保证双方按照完全相同的速度接收数据,因此,双方以不同的速度进行数据接收和发送,就会出现问题

如果要解决这个问题,uart 为每个字节添加额外的起始位和停止位,以帮助接收器在数据到达时进行同步

双方还必须事先就传输速度达成共识,设置相同的波特率 例如每秒9600位

传输速率如果有微小差异不是问题,因为接收器会在每个字节的开头重新同步

如果您注意到上图中的11001010不等于0x53,这是一个细节。串口协议通常会首先发送最低有效位,因此最小位在最左边LSB。低四位字节实际上是0011 = 0x3,高四位字节是0101 = 0x5。

异步串行工作得很好,但是在每个字节发送的时候都需要额外的起始位和停止位 以及在发送和接收数据所需的复杂硬件方面都有很多开销

不难发现,如果接收端和发送端设置的速度都不一致,那么接收到的数据将是垃圾 乱码

SPI 通讯协议

spi 是一个同步的数据总线,也就是说它是用单独的数据线和一个单独的时钟信号来保证发送端和接收端的完美同步

时钟是一个振荡信号,它告诉接收端在确切的时机对数据线上的信号进行采样

产生时钟的一侧称为主机,另一侧为从机,总是只有一个主机 一般来说可以是微控制器 MCU 但是可以有多个从机

数据的采集时机可能是时钟信号的上升沿 或下降沿

具体要看对 spi 的配置

整体的传输大概可以分为以下几个过程

主机先将NSS 信号拉低,这样保证开始接收数据

当接收端检测到时钟的边沿信号时,它将立即读取数据线上的信号,这样就得到了一位数据 1bit

由于时钟是随数据一起发送的,因此指定数据的传输速度并不重要,尽管设备将具有可以运行的最高速度

主机发送到从机时:主机产生相应的时钟信号,然后数据一位一位地将从MOSI信号线上进行发送到从机;
主机接收从机数据:如果从机需要将数据发送回主机,则主机将继续生成预定数量的时钟信号,并且从机会将数据通过MISO信号线发送;

注意 spi 是全双工 具有单独的发送和接收线路,因此可以在同一时间发送和接收数据,另外 spi 的接收硬件可以是一个简单的移位寄存器,这笔异步串行通信所需的完整uart 要简单得多,并且更加便宜

spi 特性

spi 总线包括4条 逻辑线,定义如下

MISO 主机输入,从机输出,数据来自从机

MOSI 主机输出,从机输入

SCLK 串行时钟信号,由主机产生发送给从机

SS 片选信号,由主机发送,以控制与哪个从机通信,通常是低电平有效信号

其他制造商可能会遵循其他命名规则,但是最终他们指的相同的含义。以下是一些常用术语;

MISO也可以是SIMO,DOUT,DO,SDO或SO(在主机端);
MOSI也可以是SOMI,DIN,DI,SDI或SI(在主机端);
NSS也可以是CE,CS或SSEL;
SCLK也可以是SCK;
本文将按照以下命名进行讲解[MISO, MOSI, SCK,NSS]

时钟频率

SPI 总线上的主机必须在通信开始时候配置并生成相应的时钟信号,在每个SPI 时钟周期内,都会发生全双工数据传输

主机在mosi 线上发送一位数据,从机读取它,而从机在miso 线上发送一位数据,主机读取它

就算只进行单向的数据传输,也要保持这样的顺序,这就意味着无论接收任何数据,必须实际发送一些东西,在这种情况下,我们称其为虚拟数据

从理论上讲,只要实际可行,时钟速率就可以是您想要的任何速率,当然这个速率受限于每个系统能提供多大的系统时钟频率,以及最大的SPI传输速率。

时钟极性 CKP Clock Polarity

除了配置串行时钟频率 外,SPI 主设备还需要配置时钟极性

根据硬件制造商的命名规则不同,时钟极性通常写为CKP或CPOL。时钟极性和相位共同决定读取数据的方式,比如信号上升沿读取数据还是信号下降沿读取数据;

CKP 可以配置为1或0 ,这意味着您可以根据需要将时钟的默认状态 IDLE 设置为高或低,极性反转可以通过简单的逻辑逆变器实现,您必须参考设备的数据手册才能正确设置CKP 和CKE

CKP = 0:时钟空闲IDLE为低电平0;
CKP = 1:时钟空闲IDLE为高电平1;

时钟相位 CKE Clock Phase Edge

除配置串行时钟速率和极性外,SPI 主设备还应配置时钟相位,根据硬件制造商的不同,时钟相位通常写为CKE 或CPHA

顾明思义,时钟相位/边沿,也就是采集数据时是在时钟信号的具体相位或者边沿

CKE = 0 在时钟信号SCK 的第一个跳变沿采样

CKE = 1 在时钟信号SCK 的第二个跳变沿采样

时钟配置总结

综上几种情况,下图总结了所有时钟配置组合,并突出显示了实际采样数据的时刻

其中黑色线为采样数据的时刻

蓝色线为SCK 时钟信号

具体如下图所示

模式编号

SPI 的时钟极性和相位的配置通常称为SPI 模式,所有可能的模式都遵循以下约定,具体如下表所示

除此之外,我们还应该仔细检查微控制器数据手册中包含的模式表,以确保一切正常

多从机模式

前面说到的SPI 总线必须有一个主机,可以有多个从机,那么具体连接到SPI 总线的方法有以下两种

第一种方法 多NSS

通常,每个从机都需要一条单独的SS 线

如果要和特定的从机进行通讯,可以将相应的NSS 信号线拉低,并保持其他NSS 信号线的状态为高电平,如果同时将两个NSS 信号线拉低,则可能会出现乱码,因为从机可能都试图在同一条MISO 线上传输数据,最终导致接收数据乱码

具体连接方式如下图所示

第二种方法 菊花链

在数字通信世界中,在设备信号 (总线信号或中断信号) 以串行的方式从一个设备依次传到下一个设备,不断循环直到数据到达目标设备的方式被称为菊花链

  1. 菊花链的最大缺点是因为信号串行传输,所以一旦数据链路中的某设备发生故障的时候,它下面优先级较低的设备就不可能得到服务了

另一方面,距离主机越远的从机,获得服务的优先级越低,所以需要安排好从机的优先级,并且设置总线检测器,如果某个从机超时,则对该从机进行短路,防止单个从机损坏造成整个链路崩溃的情况

具体的连接如下图所示

其中红线加粗为数据的流向

所以最终的数据流向图可以表示为

SCK 为时钟信号,8clks 表示8个边沿信号

其中D 为数据,X 为无效数据

所以不难发现,菊花链模式充分使用了SPI 其移位寄存器的功能,整个链充当通信移位寄存器,每个从机在下一个时钟周期将输入数据复制到输出

优缺点

SPI 通讯的优势

使SPI 作为串口通信接口脱颖而出的原因很多

全双工串行通信;
高速数据传输速率。
简单的软件配置;
极其灵活的数据传输,不限于8位,它可以是任意大小的字;
非常简单的硬件结构。从站不需要唯一地址(与I2C不同)。从机使用主机时钟,不需要精密时钟振荡器/晶振(与UART不同)。不需要收发器(与CAN不同)。

SPI 的缺点

没有硬件从机应答信号 主机可能在不知情的情况下无处发送

通常仅支持一个主设备

需要更多的引脚 与I2C 不同

没有定义硬件级别的错误检查协议

与RS232 和CAN 总线相比,只能支持非常短的距离

编程实现
下面是通过STM32的cubemx自动生成的HAL库代码,比较简单,截取了其中一部分,具体如下;

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
static void MX_SPI1_Init(void)
{
hspi1.Instance = SPI1;
hspi1.Init.Mode = SPI_MODE_MASTER; //主机模式
hspi1.Init.Direction = SPI_DIRECTION_2LINES; //全双工
hspi1.Init.DataSize = SPI_DATASIZE_8BIT; //数据位为8位
hspi1.Init.CLKPolarity = SPI_POLARITY_LOW; //CPOL=0
hspi1.Init.CLKPhase = SPI_PHASE_1EDGE; //CPHA为数据线的第一个变化沿
hspi1.Init.NSS = SPI_NSS_SOFT; //软件控制NSS
hspi1.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_2;//2分频,32M/2=16MHz
hspi1.Init.FirstBit = SPI_FIRSTBIT_MSB; //最高位先发送
hspi1.Init.TIMode = SPI_TIMODE_DISABLE; //TIMODE模式关闭
hspi1.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLE;//CRC关闭
hspi1.Init.CRCPolynomial = 10; //默认值,无效
if (HAL_SPI_Init(&hspi1) != HAL_OK) //初始化
{
_Error_Handler(__FILE__, __LINE__);
}
}

//发送数据
HAL_StatusTypeDef
HAL_SPI_Transmit(SPI_HandleTypeDef *hspi,
uint8_t *pData,
uint16_t Size,
uint32_t Timeout);
//接收数据
HAL_StatusTypeDef
HAL_SPI_Receive(SPI_HandleTypeDef *hspi,
uint8_t *pData,
uint16_t Size,
uint32_t Timeout);

% SPI、UART、RS232、RS485、IIC 5

20221212-RS2329针串口定义

电脑 9 针串口
电脑串口引脚定义
这里写图片描述
按序号说明:
1 载波检测(DCD)
2 接受数据(RXD)
3 发出数据(TXD)
4 数据终端准备好(DTR)
5 信号地线(SG)
6 数据准备好(DSR)
7 请求发送(RTS)
8 清除发送(CTS)
9 振铃指示(RI)
串口母头连接器的管脚定义
这里写图片描述
此上为计算机串口管脚定义说明。
1、 RS-232C 母接头定义(9 芯):
这里写图片描述
注意图和总引脚的标号。
针脚 定义 符号
1 载波检测 DCD
2 接收数据 RXD
3 发送数据 TXD
4 数据终端准备好 DTR
5 信号地 SG
6 数据准备好 DSR
7 请求发送 RTS
8 清除发送 CTS
9 振铃提示 RI
Pin 1 Received Line Signal Detector(Data Carrier Detect)
Pin 2 Received Data
Pin 3 Transmit Data
Pin 4 Data Terminal Ready
Pin 5 Signal Ground
Pin 6 Data Set Ready
Pin 7 Request To Send
Pin 8 Clear To Send
Pin 9 Ring Indicator

2、 RS-232C 母接头定义(25 芯)
针脚 定义 符号
1 频蔽地线
2 发送数据 TXD
3 接收数据 RXD
4 请求发送 RTS
5 允许发送 CTS
6 数据准备好 DSR
7 信号地 SG
8 载波检测 DCD
9 发送返回(+)
10 未定义
11 数据发送(-)
1217 未定义
18 数据接收(+)
19 未定义
20 数据终端准备好 DTR
21 未定义
22 振铃 RI
23
24 未定义
25 接收返回(-)
Pin 1 Protective Ground
Pin 2 Transmit Data
Pin 3 Received Data
Pin 4 Request To Send
Pin 5 Clear To Send
Pin 6 Data Set Ready
Pin 7 Signal Ground
Pin 8 Received Line Signal Detector
(Data Carrier Detect)
Pin 20 Data Terminal Ready
Pin 22 Ring Indicator
RS-232C,25 芯针转换为 9 芯针
这里写图片描述

二、 补充 (几个小时的查询和求助才弄明白的,呵呵,珍贵
啊)

1.RX232 公接头的图片和引脚编号 :
这里写图片描述
2.从两个图可以看出, 公接头和母接头相连时 rx-rx,
tx-tx,进而可知下载线的两端接口本应该 rx-rx、t
x-tx 的,但买串口线时需要买交叉串口线(实现 RX-
tx 的连接),进而实现一段发送一段接收。
三、更详细的引脚标号规则(超准)
DB9 Male (Pin Side) DB9 Female (Pin Side)
DB9 Female (Solder Side) DB9 Male (Solder Side)
这里写图片描述
1 ,RS232 的定义:
RS-232 串行接口标准详细介绍
目前 RS-232 是 PC 机与通信工业中应用最广泛的一种串行接口。RS-232 被定义为一种在低速率串
行通讯中增加通讯距离的单端标准。RS-232 采取不平衡传输方式,即所谓单端通讯。
这里写图片描述
图一
在 RS-232 的通讯标准中是以一个 25 针的接口来定义的,并在早期的计算机如 PC 或 XT 机型上广
泛使用,但在 AT 机以后的机型上,实际均采用了 9 针的简化版本应用,现在所说的 232 通讯均默认为 9
针的接口。图一显示了 9 针通讯的接口管脚名称,以下是各管脚的说明:
这里写图片描述
现在通常计算机均配有这种标准的 232 接口,通常这种接口用于联接鼠标、MODEM 或打印机等外
部设备。
实际应用中,电子工程师在设计计算机与外围设备的通信时,通常在 9 针的基础再进行简化,只用
其中的 2、3、5 三个管脚进行通信。这三个管脚分别是接收线、发送线和地线,在一般情况下即可满足通
讯的要求,计算机和外部通讯的接线方法如图二:
这里写图片描述
值得注意的是,图二中 2、3 两脚是交叉互联的,这很容易理解,因为一个设备的发送线必须联接到
另外一台设备的接收线上,反之亦然。
对于 232 信号的电器特性等知识,在这里无法详细解说,有兴趣的话可以去网站查阅这方面的文章,
232 是最常用的通信方式之一,大量应用于各种工业控制或电子家电等产品中,是电子工程师必须掌握的
知识之一。
另外说明一下,232 信号的有效通讯距离是 15M。
2.RS232 TO TTL 电路:

20221212-蓝牙协议分析

https://zhuanlan.zhihu.com/p/482020575

本文介绍蓝牙协议的基本特点,版本演进,协议的构成,学习路线等基础知识分享

​ 蓝牙(英语:Bluetooth),一种无线通讯技术标准,用来让固定与移动设备,在短距离间交换资料,以形成个人局域网(PAN)。其使用短波特高频(UHF)无线电波,经由2.4至2.485 GHz的ISM频段来进行通信。1994年由电信商爱立信(Ericsson)发展出这个技术。它最初的设计,是希望创建一个RS-232数据线的无线通信替代版本。它能够链接多个设备,克服同步的问题。

技术类型

蓝牙技术分为 基础率 增强数据率,和低功耗 LE 两种技术类型,其中 、BR EDR 是以点对点网络拓扑结构创建一对一设备通信 LE 型则使用点对点 一对一 广播 一对多和网格 多对多 等多种网络拓扑结构

蓝牙技术联盟(英语:Bluetooth Special Interest Group,缩写为SIG)拥有蓝牙的商标,负责制定蓝牙规范、认证制造厂商,授权他们使用蓝牙技术与蓝牙标志,但本身不负责蓝牙设备的设计、生产及贩售。

蓝牙 2.x EDR
加入了非跳跃窄频通道,因为不需要与每个设备交换应答信号,这种通道可以用来将给中器件的蓝牙服务概要同时广播到巨量的蓝牙器件,应答信号交换过程当前需要大约一秒,实时公共交通的时刻表,基本的交通畅通性信息和高级交通指向指示灯未加密信息可以以高速度发送给设备,更高的连接速度,支持多个速度水平

​ 2007年7月26日,蓝牙技术联盟通过了蓝牙核心规范2.1+EDR,向下对1.2版本完全兼容,并增加了Sniff省电功能,使得适配器与设备的联系时间延长到0.5秒,能节约不小电量;增强功能有简单安全配对(SSP),这改善了蓝牙设备的配对经验,同时提升了使用和安全强度。

蓝牙 3.0 HS

是一种全新的交替射频技术,蓝牙3.0 + HS 提高了资料传输速率,集成802.11 PAL 最高速度可达24Mbps 此外引入了增强电源控制,实际空闲功耗明显降低

蓝牙 4.x

提出了低功耗蓝牙 传统蓝牙 和高速蓝牙 三种模式

高速蓝牙 主攻数据交换与传输

传统蓝牙 则以信息沟通,设备连接为重点

低功耗蓝牙 以不需要占用太多带宽的设备连接为主,

这三种协议规范还能够互相组合搭配,从而实现更广泛的应用模式,此外,Bluetooth 4.0 还包蓝牙的传输距离提升到100米以上 低功耗模式调条件下

调频 使用所有蓝牙规范版本通用的自适应调频,最大程度地减少 和其他 2.4GHz ISM 频段无线技术的串扰

蓝牙 5.x

在有效传输距离上将是4.2 LE 版本的4倍 传输速度将是4.2LE 版本的2倍

蓝牙5.0 还支持室内定位导航功能,允许无需配对接受信标的数据 ,针对物联网进行了很多底层优化

1.6 总结

我们常说的蓝牙4.0 不等同于BLE BLE 只是蓝牙4.0 的子集,蓝牙4.0 是一个综合性协议规范

蓝牙4.0 版本以后技术模式上分为低功耗蓝牙 和经典蓝牙 两种,市场芯片多数为仅支持BLE 的,也有两者都支持的 双模蓝牙芯片

蓝牙芯片的三种功能配置

  1. 蓝牙协议栈

蓝牙协议栈由主机 +HCI 可选 +控制器三大块组成,其中对于单芯片方案是没用HCI 的

主机 Host 主机部分由核心协议层 和核心规范构成

控制器 此部分拆分为低功耗蓝牙和经典蓝牙两个章节说明

HCI 此部分定义了主机和控制器之间通信的接口标准,可以是UART USB 等通信方式

上图中红色部分是 BR/RED 经典蓝牙的必选项,绿色部分是LE 低功耗蓝牙必选项,蓝色部分是公共部分,当然经典蓝牙也可以具备绿色部分特性,HCI 接口根据芯片架构有关,是可选项,两者在物理层的差异性图中没有体现,不涉及芯片设计,这块可暂不关注

GPA 规范,通用接入规范,定义了所有蓝牙设备的基础功能,设备键发现,连接、配对,绑定的流程,蓝牙设备中四种角色,广播和扫描响应报文的格式,还有一些通用蓝牙参数定义,比如设备地址,名称、配对密钥和设备的外观特征值,用于区分是什么设备,手机还是电脑;明确了作为一个低功耗蓝牙设备的基本需求,包含哪些层级以及如何协同工作的,规范了一些通用的蓝牙参数,蓝牙设备地址、设备名称、配对密钥、外观特征值 用于区分是手机还是电脑

ATT 属性协议,定义了访问对端设备上数据的一组规则,是GATT 规范的基础,也是低功耗蓝牙的基石,定义了host 端属性报文格式和报文类型

GATT 通用属性规范,位于ATT 之上,定义了属性的类型及其使用方法,GATT 用来规范attribute 中的数据内容,并运用 group 的概念对attribute 进行分类管理,没有GATT BLE 协议栈也能跑,但互联互通就会出现问题

L2CAP 层,屏蔽了控制器传输协议中的许多特性,方便高层协议的开发,报文分片和重组,SAR 流控,重传 报文完整性校验等

SMP 安全管理协议,定义了蓝牙设备配对,认证,解密等行为的安全操作

LLCP LL 链路层控制,

PHY 物理层,低功耗蓝牙采用40个信道,分为数据信道和广播信道;广播信道占用3个,用于发现设备、建立连接、广播数据;数据信道占用37个,用于已建立连接设备间的数据通信。建立连接的两个设备,必须同一时间处于同一信道上才能通信。

  1. 学习路线

此部分给出低功耗蓝牙的基本学习路线,不一定适合所有人

初步理解协议栈基本组成、专业术语,对协议栈有整体的认识。
结合相关项目抓包分析,结合理论和实际表现分析每个子过程,比如ble广播功能、ble建立连接等。有条件的可以整个开发板,都有配套教程代码,可以直接运行的。
相关协议栈源码移植和学习,推荐Zephyr.
4. 协议文档
蓝牙联盟官方下载入口:http://www.bluetooth.com
个人网盘分享:https://www.aliyundrive.com/s/dhKyo

20221212-MQTT协议笔记

https://www.runoob.com/w3cnote/mqtt-intro.html

MQTT 入门介绍

MQTT 消息队列遥测传输协议,是一种基于发布/订阅模式的轻量级 通讯协议,该协议构建于TCP/IP 协议上,由IBM 在1999年发布,MQTT 最大优点在于,可以以极少的代码和有限的带宽,为连接远程设备提供实时可靠的消息服务,作为一种低开销,低带宽占用的即时通讯协议,使其在物联网、小型设备、移动应用等方面有较广泛的应用

MQTT 是一个基于客户端-服务器的消息发布/订阅传输协议。MQTT协议是轻量、简单、开放和易于实现的,这些特点使它适用范围非常广泛。在很多情况下,包括受限的环境中,如:机器与机器(M2M)通信和物联网(IoT)。其在,通过卫星链路通信传感器、偶尔拨号的医疗设备、智能家居、及一些小型化设备中已广泛使用。

二、设计规范

由于物联网的环境是非常特别的,所以MQTT 遵循以下设计原则

精简,不添加有可无的功能

发布/订阅 模式,方便消息在传感器之间传递

允许用户动态创建主题,零运维成本

把传输量降到最低以提高传输效率

把低带宽、高延迟、不稳定的网络等因素考虑在内

支持连续的会话控制

理解客户端计算能力可能很低

提供服务质量管理

假设数据不可知,不强求传输数据的类型与格式,保持灵活性

三、主要特性

MQTT 协议工作在低带宽、不可靠的网络的远程传感器和控制设备通讯而设计的协议,它具有以下主要的几项特性。

使用发布/订阅消息模式,提供一对多的消息发布,解除应用程序耦合

这一点很类似于XMPP,但是MQTT 的信息冗余远小于XMPP,因为XMPP 使用XML 格式文本来传递数据

对负载内容屏蔽的消息传输

使用TCP/IP提供网络连接

主流的MQTT 是基于TCP 连接进行数据推送的,但是同样有基于UDP 的版本,叫做MQTT-SN 这两种版本由于基于不同的连接方式,优缺点自然也就各有不同了

有三种消息发布服务质量

至多一次,消息发布完全依赖底层TCP/IP 网络,会发生消息丢失或重复,这一级别可用于如下情况,环境传感器数据,丢失一次读记录无所谓,因为不久后还会有第二次发送,这一种方式主要普通APP 的推送,倘若你的智能设备在消息推送时未联网,推送过去没收到,再次联网也就收不到了

至少一次,确保消息到达,但消息重复可能会发生

只有一次,确保消息到达一次。在一些要求比较严格的计费系统中,可以使用此级别,在计费系统中,消息重复或丢失会导致不正确的结果,这种最高质量的消息发布服务还可以用于即时通讯类的app 的推送,确保用户收到且只会收到一次

小型传输,开销很小,协议交换最小化,以降低网络流量。这就是为什么在介绍里说它非常适合 在物联网领域,传感器与服务器的通信,信息的收集,要知道嵌入式设备的运算能力和带宽都相对薄弱,使用这种协议来传递消息再适合不过了

使用 last will 和testament特性通知有关各客户端异常中断的机制

last will 即遗言机制,用于同位置同一主题下的其他设备发送遗言的设备已经断开了连接

testament 医嘱机制,功能类似于 last will

MQTT 协议原理

实现MQTT 协议需要客户端和服务器端通讯完成,在通讯过程中,MQTT 协议中有三种身份 发布者,代理,服务器,订阅者,其中,消息的发布者和订阅者都是客户端,消息代理是服务器,消息发布者可以同时是订阅者

MQTT 传输的消息分为,主题,和负载 两部分

topic 可以理解为消息的类型,订阅者订阅后,就会收到该主题的消息内容

payload 可以理解为消息的内容,是指订阅者具体要使用的内容

4.2 网络传输与应用消息

MQTT 会构建底层网络传输,它将建立客户端到服务器的连接,提供两者之间的一个有序的、无损的、基于字节流的双向传输

当应用数据通过MQTT 网络发送时,MQTT 会把与之相关的服务质量和主题名 相关连

MQTT 客户端

一个使用MQTT 协议的应用程序或者设备,它总是建立到服务器的网络连接,客户端可以

发布其他客户端可能会订阅的信息

订阅其他客户端发布的消息

退订或删除应用程序的消息

断开与服务器连接

4.4 MQTT 服务器

MQTT 服务器以称为消息代理,可以是一个应用程序或一台设备,它是位于消息发布者和订阅者之间,它可以

接受来自客户的网络连接

接受客户发布的应用信息

处理来自客户端的订阅和退订请求

向订阅的客户转发应用程序消息

4.5 MQTT 协议中的订阅、主题、会话

订阅

订阅包含主题筛选器 和最大服务质量,订阅会与一个会话关联,一个会话可以包含多个订阅,每一个会话中的每个订阅都有一个不同的主题筛选器

会话

每个客户端与服务器建立连接后就是一个会话,客户端和服务器之间有状态交互,会话存在于一个网络之间,也可能在客户端和服务器之间跨越多个连续的网络连接、

主题名

连接到一个应用程序消息的标签,该标签与服务器的订阅相匹配,服务器会将消息发送给订阅所匹配标签的每个客户端

主题筛选器

一个对主题名通配符筛选器,在订阅表达式中使用,表示订阅所匹配到的多个主题

负载

消息订阅者所具体接收的内容

MQTT 协议中的方法

MQTT 协议中定义了一些方法 也被称为动作,来于表示对确定资源所进行操作,这个资源可以代表预先存在的数据或动态生成数据,这取决于服务器的实现,通常来说,资源指服务器上的文件或输出,主要方法有

connect 等待与服务器建立连接

disconnect 等待MQTT 客户端完成所做的工作,并与服务器断开TCP/IP 会话

subscribe 等待完成订阅

unsubscribe 等待服务器取消客户端的一个或多个topics 订阅

publish MQTT 客户端发送消息请求,发送完成后返回应用程序线程

MQTT 协议数据包结构

在MQTT 协议中,一个MQTT 数据包由固定头,可变头,消息体 三部分构成,MQTT 数据包结构如下

固定头 fixed header 存在于所有MQTT 数据包中,表示数据包类型及数据包的分组类表示

可变头 存在于部分MQTT 数据包中,数据包类型 决定了可变头是否存在及其具体内容

消息体 pyload 存在于部分MQTT 数据包中,表示客户端收到的具体内容

MQTT 固定头

固定头存在于所有MQTT 数据包中,其结构如下

MQTT 数据包类型

位置byte1 中bits 7-4

相当于一个4位的无符号值,类型,取值及描述如下

标识位

在不使用标识位的消息类型中,标识位被作为保留位,如果收到无效的标志时,接收端必须关闭网络连接

DUP 发布消息 的副本,用来在保证消息的可靠传输,如果设置为1 则在下面的变长中增加 messageid 并且需要回复确认,以保证消息传输完成,但不能用于检测消息重复发送

QoS 发布消息的服务质量,即:保证消息传递的次数

1
2
3
4
5
6
7
Ø00:最多一次,即:<=1

Ø01:至少一次,即:>=1

Ø10:一次,即:=1

Ø11:预留

RETAIN 发布保留标识,表示服务器要保留这次推送的信息,如果有新的订阅者出现,就把消息推送给它,如果没有那么推送至当前订阅者后释放

剩余长度

固定头的第二字节用来保存变长头部和消息体的总大小,但不是直接保存的,这一字节是可以扩展的,其保存机制,前7位用于保存长度,后一部用作标识,当最后一位为1时,表示长度不足,需要使用两个字节继续保存,例如,计算出后面的大小为0

MQTT 可变头

MQTT 数据包中包含一个可变头,它驻位于固定的头和负载之间,可变头的内容因数据包类型而不同,较常的应用是作为包的标识

很多类型数据包中都包括一个2字节的数据包标识字段,这些类型的包有

PUBLISH (QoS > 0)、PUBACK、PUBREC、PUBREL、PUBCOMP、SUBSCRIBE、SUBACK、UNSUBSCRIBE、UNSUBACK。

Payload 消息体

payload 消息体位MQTT 数据包的第三部分,包含 connect subscribe subback unsubscribe 四种类型的消息

connect 消息体内容主要是客户端的clientID 订阅的topic message 以及用户名和密码

subscribe 消息体内容是一系列的要订阅的主题以及QoS

suback 消息体内容是服务器对于subscribe 所申请的主题及QoS 进行确认和回复

unsubscribe 消息体内容是要订阅的主题

  • Copyrights © 2015-2024 TeX_baitu
  • 访问人数: | 浏览次数:

请我喝杯咖啡吧~