嵌入式系统得片内外设学习

连接片内外设功能的VLSI外设总线的VPB以及各种片内外设,包括定时器、ADC、GPIO、实时时钟、I2C接口、SPI接口等。片上外设(On-chip Peripherals)是指嵌入式系统或集成电路芯片上集成的各种功能模块或接口,用于与外部设备进行通信、控制和数据交换。这些外设可以与主处理器或控制器协同工作,扩展系统的功能和应用范围。常见的片上外设包括但不限于以下几种:

1、通用输入/输出(GPIO):提供通用的数字输入/输出接口,用于连接和控制外部设备,如按钮、开关、传感器等。
2、串行通信接口:包括UART(通用异步收发传输器)、SPI(串行外设接口)、I2C(串行总线接口)等,用于与其他设备进行串行数据通信。
3、定时器/计数器:用于生成定时、延时或频率计数的功能,常用于时序控制、脉冲调制、定时中断等应用。
4、PWM(脉冲宽度调制)控制器:用于生成可调节脉冲宽度的信号,广泛用于电机控制、LED亮度调节等应用。
5、ADC(模数转换器)和DAC(数模转换器):ADC将模拟信号转换为数字信号,DAC将数字信号转换为模拟信号,用于模拟信号采集和输出。
6、定序电路(Power Sequencer):用于控制芯片电源的开启和关闭顺序,确保电源稳定性和系统安全。
7、接口控制器:包括以太网控制器、USB控制器、CAN控制器等,用于实现与外部设备的高速数据传输和通信。
8、存储器控制器:用于管理片上存储器(如闪存、RAM)的读写操作和访问控制。
9、中断控制器:用于管理和处理系统中断,实现中断优先级和中断向量表等功能。
10、显示控制器:用于控制和驱动液晶显示器(LCD)、有机发光二极管(OLED)等显示设备。

本文简单学习串行通信接口;

一、UART(通用异步收发器)

是一种常见的串行通信接口协议,用于在计算机和外部设备之间的传输数据。是一种简单且可靠的通信方式,UART使用两根信号线进行通信:一根用于数据传输(TX、发送),另一根用于接收数据(RX,接收)

通信方式

1、异步串行通信、收/发

2、半双工通信、可发可收、但不能同时进行

3、全双工通信,可以同时收发

以下是UART的时序详细介绍:
起始位(Start Bit):UART通信的起始位始终为逻辑低电平(0),用于标识数据传输的开始。
数据位(Data Bits):UART通信可以使用5、6、7或8个数据位来传输数据。数据位按照位顺序从最低位到最高位传输。
奇偶校验位(Parity Bit):可选的奇偶校验位用于检测和纠正数据传输中的错误。
校验位可以是奇校验(使得数据位的总数包含奇数个1)或偶校验(使得数据位的总数包含偶数个1)。
停止位(Stop Bit):停止位是UART通信的结束位,始终为逻辑高电平(1)。
它标识数据传输的结束,并允许接收器进行下一次数据接收的准备。
工作原理:
    UART作为一种异步串行通信协议,其工作原理是逐位传输传输数据的每个二进制位。在UART通信协议中,当信号线上的状态为高时,代表“1”,当信号线上的状态为低时,代表“0”。
UART没有时钟信号,无法控制何时发送数据,也无法保证双发按照完全相同的速度接收数据,因此起始位和停止位是比较重要的。互相规定的波特率也很重要。
    例如,当采用UART通信协议传输一字节数据时,信号线上会产生八种高低电平组合。
    串行通信是指利用一根传输线逐位依次传输数据,也可以用两根信号线组成全双工通信,如rs232。特点是通信线路简单,使用简单的电缆即可实现通信,成本降低,适合远距离通信的应用,但传输速度慢。
    异步通信以一个字符为传输单位。通信中两个字符之间的时间间隔不固定,但同一字符中两个相邻位之间的时间间隔是固定的。一般来说,两个UART设备之间的通信不需要时钟线。此时,需要在两个UART设备上指定相同的传输速率,以及空闲位、起始位、奇偶校验位和结束位,即遵循相同的协议。
    数据传输速率以波特率表示,即每秒传输的位数。例如,如果数据传输速率为120个字符/秒,每个字符为10位(1个起始位、7个数据位、1个校验位、1个停止位),则其传输的波特率为10×120 = 1200 个字符/秒 = 1200 波特率。
二、I2C
    I2C总线是一种同步、半双工双向的两线式串口总线。它由两条总线组成:串行时钟线SCL和串行数据线SDA。
SCL线——负责产生同步时钟脉冲。
SDA线——负责在设备间传输串行数据。
该总线可以将多个I2C设备连接到该系统上。连接到I2C总线上的设备既可以用作主设备,也可以用作从设备。 
主设备负责控制通信,通过对数据传输进行初始化,来发送数据并产生所需的同步时钟脉冲。从设备则是等待来自主设备的命令,并响应命令接收。
主设备和从设备都可以作为发送设备或接收设备。无论主设备是作为发送设备还是接收设备,同步时钟信号都只能由主设备产生。
如果用通用IO口模拟I2C总线,并实现双向传输,则需一个输入输出口(SDA),另外还需一个输出口(SCL)。 

 

总结来说,I2C总线具有以下特点:
只需要SDA、SCL两条总线;
没有严格的波特率要求;
所有组件之间都存在简单的主/从关系,连接到总线的每个设备均可通过唯一地址进行软件寻址;
I2C是真正的多主设备总线,可提供仲裁和冲突检测;
传输速度分为四种模式:
标准模式(Standard Mode):100 Kbps
快速模式(Fast Mode):400 Kbps
高速模式(High speed mode):3.4 Mbps
超快速模式(Ultra fast mode):5 Mbps
最大主设备数:无限制;
最大从机数:理论上,1008个从节点,寻址模式的最大节点数为2的7次方或2的10次方,但有16个地址保留用于特殊用途。

起始与终止信号:SCL为高期间,

             SDA : 由高到低,起始信号

             SDA:由低到高,终止信号

起始信号和终止信号都是由主机发送的。在起始信号产生之后,总线就处于被占用的状态,在终止信号产生之后,总线就处于空闲状态

每当发送器传输完一个字节的数据之后,发送端会等待一定的时间,等接收方的应答信号。接收端通过拉低SDA数据线,给发送端发送一个应答信号,以提醒发送端我这边已经接受完成,数据可以继续传输,接下来,发送端就可以继续发送数据了。

三、SPI

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

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

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

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

SPI总线包括4条逻辑线,定义如下:
  • MISO:Master input slave output 主机输入,从机输出(数据来自从机);
  • MOSI:Master output slave input 主机输出,从机输入(数据来自主机);
  • SCLK :Serial Clock 串行时钟信号,由主机产生发送给从机;
  • SS:Slave Select 片选信号,由主机发送,以控制与哪个从机通信,通常是低电平有效信号。

SPI通讯的优势

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

SPI的缺点

  • 没有硬件从机应答信号(主机可能在不知情的情况下无处发送);
  • 通常仅支持一个主设备;
  • 需要更多的引脚(与I2C不同);
  • 没有定义硬件级别的错误检查协议;
  • 与RS-232和CAN总线相比,只能支持非常短的距离;

截取了部分HAL库代码,比较简单,具体如下:

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);

原创文章,作者:guozi,如若转载,请注明出处:https://www.sudun.com/ask/80783.html

Like (0)
guozi的头像guozi
Previous 2024年5月31日 上午10:23
Next 2024年5月31日

相关推荐

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注