目录
1. GPIO - General-purpose input/output
通用型IO, 功能如其名, pin脚可以自用控制使用,充当如clk, generator, chip select 等. 并且一定有寄存器来选择这些功能:
对于输入, 可以通过读取某个寄存器来确定pin脚电位的高低;
对于输出,一定可以通过写入某个寄存器来让这个引脚输出高低点位;
对于其他功能,则会由另外的寄存器来控制
操作
现在能够看到的关于GPIO操作的库函数是V1.8.0,可以在STM官方库支持中下载文档的综述表明其功能是管理GPIO的外设功能,总共是三点:
- 初始化;2.读写;3.复用
整个文件中包括14个函数: 初始化与配置4个; 读写操作9个; 复用1个
初始化函数 | |
---|---|
GPIO_DeInit() | 取消初始化,恢复为其默认复位值。默认引脚悬空(除JTAG) |
GPIO_Init() | 根据初始化结构体来自定义初始化引脚 |
GPIO_StructInit() | 根据默认模式初始化引脚 |
GPIO_PinLockConfig() | 锁定寄存器GPIOx_MODER, GPIOx_OTYPER, GPIOx_OSPEEDR,GPIOx_PUPDR, GPIOx_AFRL and GPIOx_AFRH,可使用复位操作来解除锁定 |
读写函数 | |
---|---|
GPIO_ReadInputDataBit() / GPIO_ReadInputData() | 获得在输入模式下配置的引脚电平 |
GPIO_ReadOnputDataBit() / GPIO_ReadOnputData() | 获得在输出模式下配置的引脚电平 |
GPIO_SetBits()/ GPIO_ResetBits() | 设置/复位在输出模式下使用的引脚电平 |
GPIO_Write() / GPIO_WriteBit() | 将数据写入指定的GPIO数据端口 |
GPIO_ToggleBits() | 切换指定的GPIO引脚使用的引脚电平,即是1变0,0变1 |
复用函数 | |
---|---|
GPIO_PinAFConfig() | 为单个引脚提供复用的函数 |
2. IIC - Inter-Integrated Circuit
全称是I2C Bus, aka. 集成电路总线
I2C是一种简单、双向二线制同步串行总线。它只需要两根线即可在连接于总线上的器件之间传送信息. 即SDA: 串行数据线;
SCL:串行时钟线, 都是双向I/O线,
数据传输
1. 数据帧格式
-
发送到SDA 线上的每个字节必须为8 bits,每次传输可以发送的字节数量不受限制; 每个字节后必须跟一个响应位( A=0表示应答) 即一帧一共9bits
-
I2C总线上传送的数据信号是广义的,即包括地址信号,又包括真正的数据信号
主机发起通信后,第一个字节是SLAVE地址(7bits + R/W寻址信号), 1表示读取数据Read; 0表示发送数据Transmita. Master → Slave send Data:
- 有阴影部分表示数据由主机向从机传送,无阴影部分则表示数据由从机向主机传送, A应答
b. Master ← Slave read Data
c. Master ↔ Slave Read/Transmit Data
扫描二维码关注公众号,回复: 16753215 查看本文章 -
首先传输的是数据的最高位(MSB)
- lsb(the least significant bit, 最低有效位), 指一个二进制数字中的第0位(即最低位), 具有权值为2^0,可以用它来检测数的奇偶性; ( 在大端序中,lsb指最右边的位 )
- msb(the maximum significant bit), 指一个n位二进制数字中的n-1位,具有最高的权值2^n − 1; (在大端序中,msb即指最左端的位 )
-
如果从机要完成一些其他功能后(例如一个内部中断服务程序)才能接收或发送下一个完整的数据字节,可以使时钟线SCL 保持低电平,迫使主机进入等待状态,当从机准备好接收下一个数据字节并释放时钟线SCL 后数据传输继续
2. 应答响应
1. 数据位的有效性规定
- 在I2C总线上传送的每一位数据都有一个时钟脉冲相对应(或称同步控制),即在SCL串行时钟的配合下,在SDA上逐位地串行传送每一位数据。
- I2C总线进行数据传送时,时钟信号为高电平期间,数据线上的数据必须保持稳定; 只有在时钟线上的信号为低电平期间,数据线上的高电平或低电平状态才允许变化
- SCL处于高电平的时候,如果SDA处于低电平; 传输数据0,SDA处于高电平:传输数据1
2. 起始和终止信号p
- SCL线为高电平期间,SDA线由高电平向低电平的变化表示起始信号S;而SDA线由低电平向高电平的变化表示终止S信号P (1 bit), 在起始信号产生后, 总线就处于被占用的状态; 在终止信号产生后, 总线就处于空闲状态
3. 应答信号
- I2C总线上的所有数据都是以8位字节传送的,发送器每发送一个字节,就在时钟脉冲9期间释放数据线,由接收器反馈一个应答信号。
- 应答信号为低电平时,规定为有效应答位(ACK简称应答位ACKNOWLEDGE),表示接收器已经成功地接收了该字节; 应答信号为高电平时,规定为非应答位(NACK),一般表示接收器接收该字节没有成功,对于反馈有效应答位ACK的要求是,接收器在第9个时钟脉冲之前的低电平期间将SDA线拉低,并且确保在该时钟的高电平期间为稳定的低电平
4. IIC 通信过程大概如下:
-
首先,主设备发一个START信号,这个信号就像对所有其它设备喊:请大家注意!然后其它设备开始监听总线以准备接收数据。接着,主设备发送一个7位设备地址加一位的读写操作的数据帧。当所设备接收数据后,比对地址自己是否目标设备。
-
如果比对不符,设备进入等待状态,等待STOP信号的来临;如果比对相符,设备会发送一个应答信号——ACKNOWLEDGE作回应。当主设备收到应答后便开始传送或接收数据。数据帧大小为8位,尾随一位的应答信号。主设备发送数据,从设备应答;相反主设备接数据,主设备应答。
-
当数据传送完毕,主设备发送一个STOP信号,向其它设备宣告释放总线,其它设备回到初始状态
-
如果从机要完成一些其他功能后(例如一个内部中断服务程序)才能接收或发送下一个完整的数据字节,可以使时钟线SCL 保持低电平,迫使主机进入等待状态,当从机准备好接收下一个数据字节并释放时钟线SCL 后数据传输继续
-
以下情况, Slave通过不应答, 即从机在SDA上的应答信号置于高位, 而由主机产生一个终止信号以结束总线的数据传送
- 由于某种原因从机不对主机寻址信号应答时(如从机正在进行实时性的处理工作而无法接收总线上的数据),它必须将数据线上的应答信号置于高电平, 而由主机产生一个终止信号以结束总线的数据传送
- 如果从机对主机进行了应答,但在数据传送一段时间后无法继续接收更多的数据时,从机可以通过对无法接收的第一个数据字节的“非应答”(从机sda处于高电平)通知主机,主机则应发出终止信号以结束数据的继续传送
- 当主机接收数据时,它收到最后一个数据字节后,必须向从机发出一个结束传送的信号。这个信号是由从机的“非应答”(拉高sda)来实现的。然后,从机释放SDA线,以允许主机产生终止信号
3. 时钟信号的同步
在I2C总线上传送信息时的时钟同步信号是由挂接在SCL线上的所有器件的逻辑“与”完成的。SCL线上由高电平到低电平的跳变将影响到这些器件,一旦某个器件的时钟信号下跳为低电平,将使SCL线一直保持低电平,使SCL线上的所有器件开始低电平期。此时,低电平周期短的器件的时钟由低至高的跳变并不能影响SCL线的状态,于是这些器件将进入高电平等待的状态。当所有器件的时钟信号都上跳为高电平时,低电平期结束,SCL线被释放返回高电平,即所有的器件都同时开始它们的高电平期。其后,第一个结束高电平期的器件又将SCL线拉成低电平。这样就在SCL线上产生一个同步时钟。可见,时钟低电平时间由时钟低电平期最长的器件确定,而时钟高电平时间由时钟高电平期最短的器件确定。
4. I2C发送与接收数据时序图
key words:
- 启动信号
- 应答信号
Master Send Data:
red : Master ctl green: Slave ctl
Master Read Data:
参考
I2C时序图
理解IIC与SPI
3. SPI - Serial Peripheral Interface
SPI是一种4线总线的协议,因为硬件强,所以SPI软件相对简单, 是一种高速全双工同步串行总线,可支持同时输入输出,使用3条通讯总线和1条片选线:
- SCK: 时钟信号线,用于通讯同步
- MOSI: 主机发送数据
- MISO: 主机接收数据
- NSS/CS: 片选信号线, 用于选择通讯的从设备
起始-停止信号
由NSS确定信号的起始和停止, 如图中1,6;
- 当NSS电平由高到低时产生起始信号;
- 当NSS电平由低到高时产生终止信号;
- Slave检测到自己的NSS电平被置低时,开始与Master通信
数据有效性
-
MOSI和MISO线在SCK的每个时钟周期传输一位数据,开发者可以自行设置MSB或LSB先行,不过需要保证两个通讯设备都使用同样的协定。从上图看到,在SCK的上升沿和下降沿时进行触发和采样。
-
SPI有四种操作模式——模式0、模式1、模式2和模式3,它们的区别是定义了在时钟脉冲的哪条边沿转换(toggles)输出信号,哪条边沿采样输入信号,还有时钟脉冲的稳定电平值(就是时钟信号无效时是高还是低), 每种模式由一对参数刻画,它们称为时钟极(clock polarity)CPOL与时钟期(clock phase)CPHA
-
[主从设备]必须使用相同的工作参数——SCLK、CPOL 和 CPHA,才能正常工作。如果有多个[从设备],并且它们使用了不同的工作参数,那么[主设备]必须在读写不同[从设备]间重新配置这些参数
CPOL CPHA
- CPOL: (pole), clock的空闲状态电平,即没有数据传输时间
CPOL = 0, 空闲时的sck时钟为低电平; CPOL = 1, 空闲时的sck时钟为高电平;- CPHA: (phase), clock的数据采样时刻
CPHA= 0, 非空闲时的sck时钟的第1边沿为采样时刻; CPHA= 0, 第2边沿为采样时刻
由此构成4中通讯模式如下如:
SPI API
API library
The libspi-master library provides an interface to mediate access to the SPI master. The resource manager layer registers a device name (usually /dev/spi0). Applications access the SPI master by using the functions declared in <hw/spi-master.h>
官网参考
參考
# include <hw/spi-master.h>
常用函数:
spi_open()
spi_read()
spi_write()
spi_close()
spi_setcfg()
spi_getdevinfo()
spi_getdrvinfo()
spi_xchange()
spi_cmdread()
spi_dma_xchange()
IIC 和 SPI区别
SPI不规定最大传输速率,没有地址方案;SPI也没规定通信应答机制,没有规定流控制规则。事实上,SPI[主设备]甚 至并不知道指定的[从设备]是否存在。这些通信控制都得通过SPI协议以外自行实现。例如,要用SPI连接一支[命令-响应控制型]解码芯片,则必须在SPI的基础上实现更高级的通信协议。SPI并不关心物理接口的电气特性,例如信号的标准电压。在最初,大多数SPI应用都是使用间断性时钟脉冲和以字节为单位传输数据的,但现在有很多变种实现了连续性时间脉冲和任意长度的数据帧。
SPI适合数据流应用,而IIC更适合“字节设备”的多主设备应用
IIC与SPI的单主设备不同,IIC 是多主设备的总线,IIC没有物理的芯片选择信号线,没有仲裁逻辑电路,只使用两条信号线—— ‘serial data’ (SDA) 和 ‘serial clock’ (SCL)
4. URAT - Universal Asynchronous Receiver/Transmitter
通用异步收发传输器,是异步通信协议
- 两根线,全双工,异步通信,速度较慢。也就是一根发送数据,一根接收数据,并且电平逻辑是时间的函数。
- 发送和接收一个bit都有固定的宽度,也就是只有等于这个时间宽度时才认为是1bit。
- 为了约定时间宽度,就诞生了比特率的概念:表示1s信号可以传输N bit的数据,单位bps=bit per second。比如,9600bps = 1s发送或接收9600 bit数据,那么1bit数据时间宽度也就是1/9600 s
- 常见比特率——9600bps 19200bps 38400bps 57600bps 115200bps
嵌入式里面说的串口,一般是指UART口, 但是我们经常搞不清楚它和COM口的区别, 以及RS232, TTL等关系,
实际上UART,COM指的物理接口形式(硬件), 而TTL、RS-232是指的电平标准(电信号)
UART有4个pin(VCC, GND, RX, TX), 用的TTL电平, 低电平为0(0V),高电平为1(3.3V或以上)
VCC:供电pin,一般是3.3v,在我们的板子上没有过电保护,这个pin一般不接更安全
GND:接地pin,有的时候rx接受数据有问题,就要接上这个pin,一般也可不接
RX:接收数据pin
TX:发送数据pin
COM口是我们台式机上面常用的口(下图),9个pin, 用的RS232电平, 它是负逻辑电平,它定义+5+12V为低电平,而-12-5V为高电平