通信

简介 

随着现代电子领域的不断发展,嵌入式系统变得越来越复杂。现如今,嵌入式系统在各 类应用中加入了大量传感器和元件,其中包括物联网(IoT)、可穿戴设备、医疗和数据中心等 应用。为了满足这些市场的需求,I2C 现在面临着其继任者 I3C®的挑战。在本篇博文中,我们将 探讨各类应用如何从 I3C 协议中受益,并介绍作为嵌入式系统解决方案而全新推出的 PIC18-Q20 单片机(MCU)。 

嵌入式系统迎来爆炸式增长与挑战 

在当今世界中,电子设备可谓无处不在,嵌入式系统也因此变得越来越复杂。为了增强 功能并收集有价值的数据,嵌入式系统配备了越来越多的传感器。从智能家居设备和可穿戴设 备到工业 IoT 解决方案和数据中心应用,传感器已然成为支柱一般的存在。 

传感器的数据传播带来了一系列挑战。传感器依赖不同的通信接口(如 UART、SPI 或 I2C),这可能会增加集成的复杂度。此外,随着传感器数量的增加,通信速度、电源效率和可 靠性也成为了至关重要的问题。 

I2C 协议使用起来相对简单,但也存在一定的局限性和挑战。一个明显的缺点是其数据吞 吐量有限,在传感器发送大量数据时会造成瓶颈。此外,在设计阶段需要单独处理各个器件, 这对于嵌入式设计工程师来说可能会很繁琐。此外,I2C 需要单独的引脚用于中断,这会增加接 口的复杂度。 I3C 的向后兼容性 在认识到 I2C 面临的挑战和问题之后,I3C 协议应需而生。I3C 向后兼容 I2C,因此可与现 有的 I2C 器件共存。

I3C 的这种向后兼容性

可帮助工程师和设计人员实现平滑切换,并且在处理 大量传感器数据方面尤为轻松。I3C 带来了更高的通信速率和更低的功耗,并且使用的接口引脚 数更少。

I3C 与 I2C 对比

I2C 与 I3C 之间的根本区别在于两者的性能。I2C 最高支持 1 Mbps 的数据传输速率,I3C 最 高支持 12.5 Mbps 的数据传输速率。数据吞吐率的显著提升使得 I3C 成为了注重快速数据交换的 应用的绝佳之选。 

全新推出集成 I3C 的 PIC18-Q20 MCU 

对于想要开发可靠且节能的嵌入式应用的设计工程师来说,PIC18-Q20 MCU 是一个极具 吸引力的解决方案。该 MCU 在片上集成了 I3C,以便设计工程师可以构建强大的连接并满足现 代嵌入式系统的要求。 通过集成 I3C 的 PIC18-Q20 MCU,设计工程师可以充分利用以下几个主要特性: 

1. 通用命令代码(CCC)——简化通信并促进设备间互操作性的标准化命令 

2. 热加入——消除设备加入或离开网络时的网络重启,增强系统的稳健性 

3. 带内中断(IBI)——支持实时通信和事件处理,确保在各种场景下平稳运行 

4. 最高支持 12.5 MHz 的时钟频率(与 I2C 相比提升显著),可实现高速数据交换 

5. 目标复位模式——根据需要帮助快速重新配置网络 

精简开发设计 

MPLAB® X 集成开发环境(IDE)和用户友好的 MPLAB 代码配置器(MCC)Melody 有助于 简化外设配置并针对具体应用定制功能,以便将创新的想法无缝转化为市场就绪的解决方案。 此外,还可以借助预制驱动程序和应用程序代码示例(可免费使用)简化基于 PIC18-Q20 MCU 的开发。 

着手开发 

立即使用 PIC18-Q20 Curiosity Nano 开发板开始评估 I3C。将该开发板与 MPLAB X IDE 和 MCC 配合使用可以简化设计流程,使您能够快速有效地将创新解决方案推向市场。

来源:Microchip微芯

免责声明:本文为转载文章,转载此文目的在于传递更多信息,版权归原作者所有。本文所用视频、图片、文字如涉及作品版权问题,请联系小编进行处理(联系邮箱:cathy@eetrend.com)。

围观 12

智能视觉与通信产业正在以前所未有的速度革新我们的生活和工作方式,这一领域的快速发展不仅推动了技术的进步,同时也催生了一系列创新应用。在这一变革过程中,Flash产品的应用日益广泛,因其高速读写能力和非易失性存储特性而找到了理想的用武之地。无论是支持高清视频流传输,还是实时图像处理,抑或大数据分析,Flash都能提供稳定且高效的数据存储与检索服务。特别是在边缘计算场景中,Flash能够帮助设备快速响应,减少延迟,保证了数据的安全性和可靠性。

在由电子发烧友网和elexcon2024深圳国际电子展联合举办的存储技术论坛中,兆易创新存储事业部市场经理刘耕辰带来了“存储产品赋能智能视觉以及通信产业发展”的主题演讲,分享了兆易创新最新的存储技术和解决方案。

1725531942956231.png

Flash家族大阅兵

兆易创新SPI NOR Flash累计出货已超237亿颗,2023年在SPI NOR Flash领域全球市场排名提升至第二位。这个数据的背后是兆易创新完整的产品家族,以5大发展方向组合出击:全容量、高性能、高可靠、低功耗和小封装,能够实现更广泛的应用覆盖。

首先,兆易创新存储产品的容量覆盖全面。比如,GD25/55系列SPI NOR Flash容量范围从512Kb到2Gb,全容量覆盖市场需求。GD5F系列SPI NAND和GD9F系列Parallel NAND则都实现了全线量产,前者为1Gb至4Gb全容量覆盖,后者为1Gb至8Gb全容量覆盖。容量2Mb至4Gb的车规产品也已全线量产。

在高性能产品方面,GD25T/LT和GD25X/LX系列是公司的两款明星产品,分别支持4口和8口SPI,吞吐量分别可达200MB/s和400MB/s,是众多电子系统的优先之选。以新能源汽车为例,其车载电子系统需要与激光雷达、智能驾驶舱、摄像头等众多设备连接,并要求在100ms内迅速启动,这对Flash的数据传输速率提出了极为严苛的要求,成为兆易创新高性能Flash的重要应用领域。

在高可靠性产品方面,SPI NOR Flash产品可以满足20年数据保持能力和延长产品寿命的10万次擦写,以及最高温度可支持到125℃,广泛适用于汽车电子、通讯及基站等应用领域。

在低功耗方面,GD25LE系列提供业界领先的低功耗参数,有效延长产品待机时间,在可穿戴市场广泛应用。GD25WD/WQ系列产品,覆盖1.65V~3.6V宽电压范围,是可穿戴设备、IoT、电池供电应用的理想之选。

发力两大核心市场

兆易创新正在积极拓展智能视觉市场和通信市场。

智能门锁行业是智能视觉市场一个重要增长点,随着高端产品开始配备摄像头和大屏幕,对存储空间提出了更高要求。有些产品方案已经采用双Flash的配置:一个驱动摄像头,另一个支持大屏应用。此外,高精度结构光模块和掌静脉识别技术的兴起,也为Flash需求带来新的增长点。相比于日韩和欧美市场的饱和,中国智能门锁市场的前景更为广阔,预计到2024年底,中国智能门锁市场的增长率有望超过20%。

此外,千米级以下的民用无人机市场正在快速发展。通用航空产业发展白皮书预计2025年全球市场规模将达到5000亿元。随着技术的发展,民用无人机的多种配件,包括遥控器、高精度定位GPS模块、用于拍摄的稳定云台等已经开始采用Flash产品。随着民用无人机对飞行时长和电池性能要求的提高,精确的电流、电压控制以及电池健康监控变得至关重要,在电池管理系统(BMS)中,Flash产品的需求也日益凸显。

通信也是兆易创新重点关注的领域之一,而光模块作为通信设备的关键组件,是Flash产品应用的重要舞台。随着NVIDIA NVLink、Intel CXL等实现片间互联低延迟技术的出现,光模块市场规模在持续扩大,预计200G/400G/800G等高速光模块将显著增长。

由于高速光模块对于信号质量的要求非常高,为减少噪声影响,必须要在TOSA和ROSA组件中加入高精度DSP,并且DSP需要单独的Flash进行存储。同时,考虑到绝大部分光模块都是QSFP+封装,要内置TOSA和ROSA、模拟器件、监控用MCU、高速DSP等多个组件,对电路板的空间要求非常严苛。因此,采用小封装的Flash产品成为必然选择,而这正是兆易创新的优势所在。同时,由于光模块在光电转换过程中需要Flash能长时间在高温环境下稳定工作,而兆易创新的Flash产品最高温度规格可以支持到125℃,完全能够应对此类挑战。此外,兆易创新还可提供适用于光模块的MCU、模拟等不同产品线,在产品协同方面也具备显著优势。

与光模块相关的5G市场也将给Flash产品提供更多的机会。虽然宏基站在城市中的覆盖率已达80%左右,但要实现更好的信号覆盖,还需要小基站和皮基站的支撑。兆易创新大容量的NOR Flash,如256Mb、512Mb都非常受欢迎,很多客户实现了方案的量产。

不断创新、推动产业持续升级

在Flash封装方面,兆易创新不断寻求突破,以应对不同的应用需求。小型化的USON6 1.2×1.2mm封装非常适合可穿戴类设备,比起SOP8 150mil或WSON8 6×5mm封装,其在体积上大为缩小。在3x2x0.4mm和3x3x0.4mm FO-USON8 封装中,兆易创新做到了容量分别提升至64Mb和128Mb。以云台相机为例,本身空间有限,但又需要较大的存储,所以非常适合大容量、小封装的Flash产品。

为应对芯片工艺节点不断缩小所带来的电压降低的趋势,兆易创新也推出了低电压的产品。其1.2V SPI NOR Flash产品有两大系列,如果要追求极致的低功耗,可选择VCC和VIO都是1.2V的产品,即GD25UF系列;如果要兼顾低功耗和性能,就可以选择1.8V VCC、1.2V VIO的GD25/55NF系列。

除上述提及的市场外,兆易创新还在不断寻找新的市场契机。未来,公司还将持续提高产品性能,为推动技术创新与产业升级而不断努力。

来源:兆易创新GigaDevice

免责声明:本文为转载文章,转载此文目的在于传递更多信息,版权归原作者所有。本文所用视频、图片、文字如涉及作品版权问题,请联系小编进行处理(联系邮箱:cathy@eetrend.com)。

围观 14

2024年,AI圈陆续传出王炸级新闻。先是OpenAI推新款大模型Sora,该模型只需输入文字,便可生成惟妙惟肖高清视频,再次让世界感受到了人工智能的强大。2月19日,国务院国资委召开“AI赋能 产业焕新”中央企业人工智能专题推进会。会议强调,要推动中央企业在人工智能领域实现更好发展、发挥更大作用。

随着AI商业化以及配套政策的落地,2024年将是AI产业爆发的元年。然而,目前AI行业建设仍面临诸多挑战。随着AI技术的发展,大模型、大数据、大算力日益成为AIGC应用的核心。大模型和数据集是AIGC发展的软件基础,而算力是最为重要的基础设施。AI服务器以并行计算为主,核心处理器主要依靠GPU,但除了GPU性能外,通信因素也会成为制约超算的短板,只要有一条链路出现网络阻塞,就会产生数据延迟。因此,AI服务器对于底层数据传输速率和延时的要求非常苛刻,需要高速率的光模块与之匹配。而光模块作为实现高速、稳定数据传输的关键器件,也随之开启新一轮的产品迭代。其中,800G光模块(传输速率达到800Gbps)作为数据中心以太网中的必要光电转换设备,可完美匹配AI服务器激增的算力和数据交互,在数据中心、云计算、网络通信等领域中被广泛应用。

STM32H5 助力高速光模块应用

2023年,ST推出STM32H5系列,该系列作为新标杆服务于工业应用市场。用于高性能设计的STM32H5系列基于强大的Arm® Cortex®-M33内核 ,运行频率高达250MHz,从最基本的安全构建模块到ST维护的安全认证服务,提供可扩展的安全性,满足所有应用需求。

STM32H5系列基于ST先进的40nm工艺,实现更优化的性价比平衡,提供丰富的内存,外设和封装选择,将给用户带来更强劲的性能和安全性,提供更多设计自由,加快产品上市。

作为新一代高性能MCU系列,STM32H5延续STM32现有的生态系统,有助于开发者轻松实现各类开发应用,还新增了一些特有的新功能,例如I3C通信接口,Secure manager,器件生命周期管理,适合各种智能化应用,尤其是高速通信应用。

引入I3C接口

ST在STM32H5中引入了一个新的通信接口I3C,它是对I2C通信接口的升级,同样基于两根总线SDA和SCL,但性能更高,且可以兼容I2C。

I3C可以在同一根总线上支持更多节点,而不会因为要支持中断或是休眠模式而增加额外的逻辑信号。下图是I3C通信的典型连接方式,支持多种设备类型,当前主设备,辅助主设备,I3C从设备,I2C从设备, I3C设备和I2C设备同时工作。

1.png

更紧凑的封装

随着AI算力不断提升,数据量呈海量增长,传输带宽不断提高,光模块需要具备更高的传输速率和更小的尺寸以适应不同的使用场景。其封装方式也在不断优化,更小封装和更低功耗可以带来更高的端口密度,使得在同样的功率下可以驱动更多的光模块。STM32H5基于ST优化的40nm工艺,采用超小封装-WLCSP80(3.5✖3.27mm), 2M flash,很好满足了高速光模块对于小尺寸的要求。

2.png

更安全的架构

光模块配置和交换机级别的安全是网络架构中至关重要的一环,需要确保只有授权用户才可以访问和配置光模块和交换机,这就要求系统具备强大的身份验证机制。

为减轻客户安全应用的开发成本,ST帮助客户通过安全认证,缩短产品上市时间,推出了交钥匙的安全解决方案,即STM32H5 Secure Manager安全管理器。

Secure Manager提供完整的安全启动与安全升级功能以及安全服务,可以支持多方软件代码IP保护,支持多种配置,并且符合PSA API标准。另外,用户也可以根据需要进行扩展,加入更多的安全模块。

Secure Manager由ST长期维护和支持,使用二进制文件交付,即使客户的产品需要进一步的安全认证,也不需要进行复杂的代码开发。

随着AI应用不断深入,对光模块的性能要求也越来越高。AI系统希望光模块具有更高的速率、更小尺寸和更高的安全性。而作为光模块中的核心芯片,STM32H5将凭借强劲的性能,强大的安全性,依托成熟的STM32生态,助力打造创新的光模块设备,满足AI产业的发展需求。

来源:STM32

免责声明:本文为转载文章,转载此文目的在于传递更多信息,版权归原作者所有。本文所用视频、图片、文字如涉及作品版权问题,请联系小编进行处理(联系邮箱:cathy@eetrend.com)。

围观 49

前提

Mini_F0140原理图上I2C连接着24C02:

1.png

一.IIC介绍

I2C(Inter-Integrated Circuit)是一种通用的总线协议,实现I2C需要两根信号线完成信息交换,SCL时钟作为信号线,SDA作为数据输入/输出线。I2C属于同步通信,由于输入输出数据均使用一根线,因此通信方向为半双工。

主要特征有:

1. I2C 总线协议转换器/并行总线

2. 半双工同步操作

3. 支持主从模式

4. 支持 7 位和 10 位地址格式

5. 支持起始(START)、停止(STOP)、重新起始(RESTART)以及应答(ACK)信号的生成和检测

6. 支持标准模式(最大 100Kbps)、快速模式(最大 400Kbps)

7. 分别有 2 字节的发送和接收缓冲

8. 支持过滤毛刺功能

9. 支持 DMA 操作

10. 支持中断和查询操作

11. 支持多个从地址(详细见用户手册)

下图为信号变化及其特定含义:

2.png

当主发送器如下图所示传输数据时,从接收器在接收到的每个字节后产生一个 ACK 来响应主发送器。

3.png

二.24C02

24C02是低工作电压的2K位串行电可擦除只读存储器,内部组织为256个字节,每个字节8位,该芯片被广泛应用于低电压及低功耗的工商业领域。

主器件通过发送一个起始信号启动发送过程,然后发送它所要寻址的从器件的地址。8位从器件地址的高4位固定为1010。接下来的3位(A2、A1、A0)为器件的地址位。当接收数据时,与I2C连接的从器件名为0xA0。

三.例程

向从机写数据后,再读取数据。

1. I2C配置

RCC_APB1PeriphClockCmd(RCC_APB1ENR_I2C1, ENABLE);
I2C_StructInit(&I2C_InitStruct);    
//Configure I2C as master mode    
I2C_InitStruct.Mode = I2C_CR_MASTER;    
I2C_InitStruct.OwnAddress = 0;    
I2C_InitStruct.Speed = I2C_CR_STD;    
I2C_InitStruct.ClockSpeed = 100000;    
I2C_Init(I2Cx, &I2C_InitStruct);    
I2C_Send7bitAddress(I2Cx, 0xA0, I2C_Direction_Transmitter);    
I2C_Cmd(I2Cx, ENABLE);

2. 定义24C02结构体

typedef struct {
    u8 busy;
    u8 ack;
    u8 fault;
    u8 opt;
    u8 sub;
    u8 cnt;
    u8* ptr;
    u8 sadd;
} gEepromTypeDef;

3. 写数据

EEPROM_WriteByte(sub);
while (cnt --) {
        EEPROM_WriteByte(*ptr);
        ptr++;
}
I2C_GenerateSTOP(I2C1, ENABLE);
while((I2C_GetITStatus(I2C1, I2C_IT_STOP_DET)) == 0);    
gEeprom.ack = true;    
gEeprom.busy = false;    
EEPROM_WaitEEready();    
return true;

4. 读数据

u8 i, flag = 0, _cnt = 0;
for (i = 0; i < gEeprom.cnt; i++) {
    while(1) {
        //Write command is sent when RX FIFO is not full
        if ((I2C_GetFlagStatus(I2C1, I2C_STATUS_FLAG_TFNF)) && (flag == 0)) {
            I2C_ReadCmd(I2C1);
            _cnt++;
            if (_cnt == gEeprom.cnt)
                flag = 1;
        }
        //Check receive FIFO not empty
        if (I2C_GetFlagStatus(I2C1, I2C_STATUS_FLAG_RFNE)) {
            gEeprom.ptr[i] = I2C_ReceiveData(I2C1);
            break;
        }
    }
}

5. 结果

4.png

来源:灵动MM32MCU

免责声明:本文为转载文章,转载此文目的在于传递更多信息,版权归原作者所有。本文所用视频、图片、文字如涉及作品版权问题,请联系小编进行处理(联系邮箱:cathy@eetrend.com)。

围观 27

SPI协议是由摩托罗拉公司提出的通讯协议(Serial Peripheral Interface),即串行外围设备接口,是一种高速全双工的通信总线。它在芯片的管脚上只占用四根线,节约了芯片的管脚,同时为PCB在布局上节省了空间,提供方便,正是出于这种简单易用的特性,现在越来越多的芯片集成了这种通信协议,它被广泛地使用在ADC、LCD、FLASH等设备与MCU之间的通信。

CKS32F4xx系列产品SPI介绍

CKS32F4xx系列的SPI外设可用作通讯的主机及从机,支持最高的SCK时钟频率为fpclk/2(CKS32F407型号的芯片默认fpclk为142MHz,fpclk2为84MHz),完全支持SPI协议的4种模式。SPI协议根据CPOL及CPHA的不同状态分成的四种工作模式如下表所示:

1.jpg

CKS32F4xx系列的SPI架构如下图所示:

2.png

图中的1处是SPI的引脚MOSI、MISO、SCK、NSS。CKS32F4xx芯片有多个 SPI外设,它们的SPI通讯信号引出到不同GPIO引脚上,使用时必须配置到这些指定的引脚。关于GPIO引脚的复用功能可以查阅芯片数据手册。各个引脚的作用介绍如下:

(1)NSS:从设备选择信号线,常称为片选信号线。当有多个SPI从设备与 SPI主机相连时,设备的其它信号线SCK、MOSI及MISO同时并联到相同的SPI 总线上,即无论有多少个从设备,都共同只使用这3条总线;而每个从设备都有独立的一条NSS信号线,当主机要选择从设备时,把该从设备的NSS信号线设置为低电平,该从设备即被选中,即片选有效,接着主机开始与被选中的从设备进行SPI通讯。所以SPI通讯以NSS线置低电平为开始信号,以NSS线被拉高作为结束信号。

(2)SCK:时钟信号线,用于通讯数据同步。它由通讯主机产生,决定了通讯的速率,不同的设备支持的最高时钟频率不一样,两个设备之间通讯时,通讯速率受限于低速设备。

(3)MOSI:主设备输出/从设备输入引脚。主机的数据从这条信号线输出,从机由这条信号线读入主机发送的数据,即这条线上数据的方向为主机到从机。

(4)MISO:主设备输入/从设备输出引脚。主机从这条信号线读入数据,从机的数据由这条信号线输出到主机,即在这条线上数据的方向为从机到主机。

图中的2处是SCK线的时钟信号,由波特率发生器根据“控制寄存器CR1”中的BR[0:2]位控制,该位是对fpclk时钟的分频因子,对fpclk的分频结果就是SCK引脚的输出时钟频率。

图中的3处是SPI的数据控制逻辑。SPI的MOSI及MISO都连接到数据移位寄存器上,数据移位寄存器的内容来源于接收缓冲区及发送缓冲区以及MISO、MOSI线。当向外发送数据的时候,数据移位寄存器以“发送缓冲区”为数据源,把数据一位一位地通过数据线发送出去;当从外部接收数据的时候,数据移位寄存器把数据线采样到的数据一位一位地存储到“接收缓冲区”中。通过写SPI 的“数据寄存器DR”把数据填充到发送缓冲区中,通过“数据寄存器DR”,可以获取接收缓冲区中的内容。其中数据帧的长度可以通过“控制寄存器CR1”的“DFF位”配置成8位及16位模式;配置“LSBFIRST位”可选择MSB先行还是 LSB先行。

图中的4处是SPI的整体控制逻辑。整体控制逻辑负责协调整个SPI外设,控制逻辑的工作模式根据我们配置的“控制寄存器(CR1/CR2)”的参数而改变,基本的控制参数包括SPI模式、波特率、LSB先行、主从模式、单双向模式等等。在外设工作时,控制逻辑会根据外设的工作状态修改“状态寄存器(SR)”,我们只要读取状态寄存器相关的寄存器位,就可以了解SPI的工作状态了。除此之外,控制逻辑还根据要求,负责控制产生SPI中断信号、DMA请求及控制NSS信号线。实际应用中,我们一般不使用CKS32 SPI外设的标准NSS信号线,而是更简单地使用普通的GPIO,软件控制它的电平输出,从而产生通讯起始和停止信号。

CKS32F4xx系列的SPI作为通讯主机端时收发数据的过程如下:

(1) 控制NSS信号线,产生起始信号;

(2) 把要发送的数据写入到“数据寄存器DR”中,该数据会被存储到发送缓冲区;

(3) 通讯开始,SCK时钟开始运行。MOSI把发送缓冲区中的数据一位一位地传输出去;MISO则把数据一位一位地存储进接收缓冲区中;

(4) 当发送完一帧数据的时候,“状态寄存器SR”中的“TXE标志位”会被置1,表示传输完一帧,发送缓冲区已空;类似地,当接收完一帧数据的时候,“RXNE标志位”会被置1,表示传输完一帧,接收缓冲区非空;

(5) 等待到“TXE标志位”为1时,若还要继续发送数据,则再次往“数据寄存器DR”写入数据即可;等待到“RXNE标志位”为1时,通过读取“数据寄存器DR”可以获取接收缓冲区中的内容。

假如我们使能了TXE或RXNE中断,TXE或RXNE置1时会产生SPI中断信号,进入同一个中断服务函数,到SPI中断服务程序后,可通过检查寄存器位来了解是哪一个事件,再分别进行处理。也可以使用DMA方式来收发“数据寄存器 DR”中的数据。

CKS32F4xx系列产品SPI的配置

接下来我们讲解如何利用CKS32F4xx系列固件库来完成对SPI的配置使用。跟其它外设一样,CKS32标准库提供了SPI初始化结构体及初始化函数来配置 SPI外设。了解初始化结构体后我们就能对SPI外设运用自如了,代码如下:

typedef struct
{  
    uint16_t SPI_Direction;            
    uint16_t SPI_Mode;                
    uint16_t SPI_DataSize;            
    uint16_t SPI_CPOL;               
    uint16_t SPI_CPHA;                 
    uint16_t SPI_NSS;                 
    uint16_t SPI_BaudRatePrescaler;    
    uint16_t SPI_FirstBit;             
    uint16_t SPI_CRCPolynomial;       
}SPI_InitTypeDef;

结构体中各个成员变量的介绍及初始化时可被赋的值如下:

1) SPI_Direction:本成员设置SPI的通讯方向,可设置为双线全双工 (SPI_Direction_2Lines_FullDuplex),双线只接收 (SPI_Direction_2Lines_RxOnly),单线只接收(SPI_Direction_1Line_Rx)、单线只发送模式(SPI_Direction_1Line_Tx)。

2) SPI_Mode:本成员设置SPI工作在主机模式(SPI_Mode_Master)或从机模式(SPI_Mode_Slave ),这两个模式的最大区别为SPI的SCK信号线的时序,SCK的时序是由通讯中的主机产生的。若被配置为从机模式,CKS32的SPI外设将接受外来的SCK信号:

3) SPI_DataSize: 本成员可以选择SPI通讯的数据帧大小是为8位 (SPI_DataSize_8b)还是16位(SPI_DataSize_16b)。

4) SPI_CPOL和SPI_CPHA: 这两个成员配置SPI的时钟极性CPOL和时钟相位CPHA,前面讲过这两个配置影响到SPI的通讯模式。时钟极性CPOL成员可设置为高电平(SPI_CPOL_High)或低电平(SPI_CPOL_Low )。时钟相位CPHA则 可以设置为SPI_CPHA_1Edge(在SCK的奇数边沿采集数据)或 SPI_CPHA_2Edge(在SCK的偶数边沿采集数据)。

5) SPI_NSS: 本成员配置NSS引脚的使用模式,可以选择为硬件模式 (SPI_NSS_Hard )与软件模式(SPI_NSS_Soft ),在硬件模式中的SPI片选信号由 SPI硬件自动产生,而软件模式则需要我们自己把相应的GPIO端口拉高或置低产生非片选和片选信号。实际中软件模式应用比较多。

6) SPI_BaudRatePrescaler: 本成员设置波特率分频因子,分频后的时钟即为SPI的SCK信号线的时钟频率。这个成员参数可设置为fpclk的2、4、6、8、16、32、64、128、256分频。可选的值如下所示:

SPI_BaudRatePrescaler_2    //2分频
SPI_BaudRatePrescaler_4    //4分频
SPI_BaudRatePrescaler_6    //6分频
SPI_BaudRatePrescaler_8    //8分频
SPI_BaudRatePrescaler_16   //16分频
SPI_BaudRatePrescaler_32   //32分频
SPI_BaudRatePrescaler_64   //64分频
SPI_BaudRatePrescaler_128  //128分频
SPI_BaudRatePrescaler_256  //256分频

7) SPI_FirstBit: 所有串行的通讯协议都会有MSB先行(高位数据在前)还是 LSB先行(低位数据在前)的问题,而CKS32F4xx系列的SPI模块可以通过这个结构体成员,对这个特性编程控制。

SPI_FirstBit_MSB    //高位数据在前
SPI_FirstBit_LSB     //低位数据在前

8) SPI_CRCPolynomial: 这是SPI的CRC校验中的多项式,若我们使用CRC 校验时,就使用这个成员的参数(多项式),来计算CRC的值。

配置完这些结构体成员的值,调用库函数SPI_Init即可把结构体的配置写入到寄存器中。

CKS32F4xx读写SPI FLASH实验

串口的DMA接发通信实验是存储器到外设和外设到存储器的数据传输。在第24

本小节以一种使用SPI通讯的串行FLASH存储芯片的读写实验为大家讲解 CKS32F4xx系列的SPI使用方法。实验中的FLASH芯片(型号:W25Q32)是一种使用SPI通讯协议的NORFLASH存储器,它的CS/CLK/DIO/DO引脚分别连接到了CKS32F4xx对应的SPI引脚NSS/SCK/MOSI/MISO上,其中CKS32F4xx的NSS引脚是一个普通的GPIO,不是SPI的专用NSS引脚,所以程序中我们要使用软件控制的方式。

1.编程要点

(1) 初始化通讯使用的目标引脚及端口时钟;  

(2) 使能SPI外设的时钟;

(3) 配置SPI外设的模式、地址、速率等参数并使能SPI外设;

(4) 编写基本SPI按字节收发的函数; 

(5) 编写对FLASH擦除及读写操作的的函数; 

(6) 编写测试程序,对读写数据进行校验。 

2.代码分析

代码清单1:W25Q32初始化配置

void W25QXX_Init(void)
{   
    GPIO_InitTypeDef  GPIO_InitStructure;  
    RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOD, ENABLE);   
    RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOG, ENABLE);   
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6;  
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;  
    GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;  
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz; 
    GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;   
    GPIO_Init(GPIOD, &GPIO_InitStructure); 
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3;  
    GPIO_Init(GPIOG, &GPIO_InitStructure);
    GPIO_SetBits(GPIOG,GPIO_Pin_3);   
    W25QXX_CS=1;                        //SPI FLASH不选中  
    SPI1_Init();                 //初始化SPI  
    SPI1_SetSpeed(SPI_BaudRatePrescaler_4);    //设置为21M时钟  
    W25QXX_TYPE=W25QXX_ReadID();         //读取FLASH ID.
}

上面的代码主要是完成对W25Q32片选引脚的初始化,SPI初始化。SPI通信速率设置和读取W25Q32的ID。

代码清单2:SPI初始化函数

void SPI1_Init(void)
{     
    GPIO_InitTypeDef  GPIO_InitStructure;  
    SPI_InitTypeDef  SPI_InitStructure;  
    RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB, ENABLE);  
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_SPI1, ENABLE);  
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3|GPIO_Pin_4|GPIO_Pin_5;  
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;  
    GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;  
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;  
    GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;   
    GPIO_Init(GPIOB, &GPIO_InitStructure); 
    GPIO_PinAFConfig(GPIOB,GPIO_PinSource3,GPIO_AF_SPI1);
    GPIO_PinAFConfig(GPIOB,GPIO_PinSource4,GPIO_AF_SPI1); 
    GPIO_PinAFConfig(GPIOB,GPIO_PinSource5,GPIO_AF_SPI1);   
    RCC_APB2PeriphResetCmd(RCC_APB2Periph_SPI1,ENABLE);  
    RCC_APB2PeriphResetCmd(RCC_APB2Periph_SPI1,DISABLE);  
    SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex;   
    SPI_InitStructure.SPI_Mode = SPI_Mode_Master;      
    SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b;    
    SPI_InitStructure.SPI_CPOL = SPI_CPOL_High;      
    SPI_InitStructure.SPI_CPHA = SPI_CPHA_2Edge;   
    SPI_InitStructure.SPI_NSS = SPI_NSS_Soft;      
    SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_256;    
    SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB;    
    SPI_InitStructure.SPI_CRCPolynomial = 7;    
    SPI_Init(SPI1, &SPI_InitStructure);    
    SPI_Cmd(SPI1, ENABLE);   
    SPI1_ReadWriteByte(0xff);   
}

上面这段代码主要是完成对SPI1的初始化,首先是配置了SPI1使用的引脚SPI1_SCK、SPI1_MOSI和SPI1_MISO。然后是根据第2小节的内容完成对SPI1外设模式的配置。根据FLASH芯片W25Q32的说明,它支持SPI模式0及模式3,支持双线全双工,使用MSB先行模式,支持最高通讯时钟为104MHz,数据帧长度为8位。我们要把CKS32F4的SPI外设中的这些参数配置一致。

代码清单3:SPI1单字节收发函数

u8 SPI1_ReadWriteByte(u8 TxData)
{              
    while (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_TXE) == RESET){}   
    SPI_I2S_SendData(SPI1, TxData);   
    while (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_RXNE) == RESET){}   
    return SPI_I2S_ReceiveData(SPI1); 
}

本函数中不包含SPI起始和停止信号,只是收发的主要过程,所以在调用本函数前后要做好起始和停止信号的操作。通过检测TXE标志,获取发送缓冲区的状态,若发送缓冲区为空,则表示可能存在的上一个数据已经发送完毕;等待至发送缓冲区为空后,调用库函数SPI_I2S_SendData把要发送的数据“TxData”写入到SPI的数据寄存器DR,写入SPI数据寄存器的数据会存储到发送缓冲区,由SPI外设发送出去;写入完毕后等待RXNE事件,即接收缓冲区非空事件。由于SPI双线全双工模式下MOSI与MISO数据传输是同步的,当接收缓冲区非空时,表示上面的数据发送完毕,且接收缓冲区也收到新的数据;等待至接收缓冲区非空时,通过调用库函数SPI_I2S_ReceiveData读取SPI的数据寄存器DR,就可以获取接收缓冲区中的新数据了。代码中使用关键字“return”把接收到的这个数据作为SPI1_ReadWriteByte函数的返回值。

搞定了SPI的基本收发单元后,还需要了解如何对FLASH芯片进行读写。FLASH 芯片自定义了很多指令,我们通过控制CKS32F4利用SPI总线向FLASH 芯片发送指令,FLASH芯片收到后就会执行相应的操作。具体的指令代码可以查看W25Q32芯片的数据手册。

代码清单4:读取FLASH芯片ID函数

u16 W25QXX_ReadID(void)
{  
    u16 Temp = 0;      
    W25QXX_CS=0;              
    SPI1_ReadWriteByte(0x90);        
    SPI1_ReadWriteByte(0x00);         
    SPI1_ReadWriteByte(0x00);         
    SPI1_ReadWriteByte(0x00);               
    Temp|=SPI1_ReadWriteByte(0xFF)<<8;    
    Temp|=SPI1_ReadWriteByte(0xFF);     
    W25QXX_CS=1;              
    return Temp;
}

这段代码利用控制CS引脚电平的宏“W25QXX_CS”以及前面编写的单字节收发函数SPI1_ReadWriteByte,很清晰地实现了读ID指令的时序,最后把读 取到的这3个数据合并到一个变量Temp中,然后作为函数返回值,把该返回值与我们定义的芯片ID对比,即可知道FLASH芯片是否正常。

代码清单5:W25Q32写使能和写禁止函数

void W25QXX_Write_Enable(void)   
{  
    W25QXX_CS=0;                                
    SPI1_ReadWriteByte(W25X_WriteEnable);      
    W25QXX_CS=1;                                    
}
void W25QXX_Write_Disable(void)   
{    
    W25QXX_CS=0;                              
    SPI1_ReadWriteByte(W25X_WriteDisable);          
    W25QXX_CS=1;                                      
}

由于FLASH存储器的特性决定了它只能把原来为“1”的数据位改写成“0”,而原来为“0”的数据位不能直接改写为“1”。所以在写入前,必须要对目标存储矩阵进行擦除操作,把矩阵中的数据位擦除为“1”,在数据写入的时候,如果要存储数据“1”, 那就不修改存储矩阵,在要存储数据“0”时,需要更改该位。W25Q32支持“扇区擦除”、“块擦除”以及“整片擦除”。 扇区擦除指令的第一个字节为指令编码,紧接着发送的3个字节用于表示要擦除的存储矩阵地址。要注意的是在扇区擦除指令前,还需要先发送“写使能”指令,发送扇区擦除指令后,通过读取寄存器状态等待扇区擦除操作完毕。

代码清单6:W25Q32扇区擦除函数

void W25QXX_Erase_Sector(u32 Dst_Addr)   
{         
    Dst_Addr*=4096;    
    W25QXX_Write_Enable();                        
    W25QXX_Wait_Busy();       
    W25QXX_CS=0;                                  
    SPI1_ReadWriteByte(W25X_SectorErase);          
    SPI1_ReadWriteByte((u8)((Dst_Addr)>>16));         
    SPI1_ReadWriteByte((u8)((Dst_Addr)>>8));       
    SPI1_ReadWriteByte((u8)Dst_Addr);    
    W25QXX_CS=1;                                       
    W25QXX_Wait_Busy();             
}

目标扇区被擦除完毕后,就可以向它写入数据了。与EEPROM类似,FLASH芯片也有页写入命令,使用页写入命令最多可以一次向FLASH传输256个字节的数据,我们把这个单位称为页大小。在进行页写入时第1个字节为“页写入指令”编码,2-4字节为要写入的“地址A”,接着的是要写入的内容,最多可以发送 256字节数据,这些数据将会从“地址A”开始,按顺序写入到FLASH的存储矩阵。若发送的数据超出256个,则会覆盖前面发送的数据。

代码清单7:W25Q32页写入函数

void W25QXX_Write_Page(u8* pBuffer,u32 WriteAddr,u16 NumByteToWrite)
{   
    u16 i;      
    W25QXX_Write_Enable();                   
    W25QXX_CS=0;                                   
    SPI1_ReadWriteByte(W25X_PageProgram);             
    SPI1_ReadWriteByte((u8)((WriteAddr)>>16));       
    SPI1_ReadWriteByte((u8)((WriteAddr)>>8));       
    SPI1_ReadWriteByte((u8)WriteAddr);       
    for(i=0;i<NumByteToWrite;i++)SPI1_ReadWriteByte(pBuffer[i]);   
    W25QXX_CS=1;                              
    W25QXX_Wait_Busy();            
}

应用的时候我们常常要写入不定量的数据,直接调用“页写入”函数并不是特别方便,所以我们页写入函数的基础上编写了“不定量数据写入”的函数。在实际调用这个“不定量数据写入”函数时,还要注意确保目标扇区处于擦除状态

代码清单8:W25Q32不定量数据写入函数

void W25QXX_Write(u8* pBuffer,u32 WriteAddr,u16 NumByteToWrite)   
{   
    u32 secpos;  
    u16 secoff;  
    u16 secremain;        
    u16 i;      
    u8 * W25QXX_BUF;         
    W25QXX_BUF=W25QXX_BUFFER;          
    secpos=WriteAddr/4096;   
    secoff=WriteAddr%4096;   
    secremain=4096-secoff;     
    if(NumByteToWrite<=secremain)secremain=NumByteToWrite;  
    while(1)   
    {      
        W25QXX_Read(W25QXX_BUF,secpos*4096,4096);    
        for(i=0;i<secremain;i++)     
        {      
            if(W25QXX_BUF[secoff+i]!=0XFF)break;         
        }    
        if(i<secremain)     
        {      
            W25QXX_Erase_Sector(secpos);       
            for(i=0;i<secremain;i++)         
            {    
                W25QXX_BUF[i+secoff]=pBuffer[i];          
            }      
            W25QXX_Write_NoCheck(W25QXX_BUF,secpos*4096,4096);     
        }else W25QXX_Write_NoCheck(pBuffer,WriteAddr,secremain);     
        if(NumByteToWrite==secremain)break;     
        else     
        {      
            secpos++;      
            secoff=0;            
            pBuffer+=secremain;        
            WriteAddr+=secremain;              
            NumByteToWrite-=secremain;              
            if(NumByteToWrite>4096)secremain=4096;        
            else secremain=NumByteToWrite;          
        }     
    };   
}

函数的入口参数pBuffer是数据存储区、WriteAd是开始写入的地址(24bit)、NumByteToWrite是要写入的字节数(最大65535)gaojp。

相对于写入,FLASH芯片W25Q32的数据读取要简单的多,发送了指令编码及要读的起始地址和要读取的字节数之后,FLASH 芯片W25Q32就会按地址递增的方式返回存储矩阵中一定字节数量的数据。

代码清单9:W25Q32读取数据函数

void W25QXX_Read(u8* pBuffer,u32 ReadAddr,u16 NumByteToRead)   
{    
    u16 i;                             
    W25QXX_CS=0;                                  
    SPI1_ReadWriteByte(W25X_ReadData);              
    SPI1_ReadWriteByte((u8)((ReadAddr)>>16));         
    SPI1_ReadWriteByte((u8)((ReadAddr)>>8));       
    SPI1_ReadWriteByte((u8)ReadAddr);       
    for(i=0;i<NumByteToRead;i++)  
    {         
        pBuffer[i]=SPI1_ReadWriteByte(0XFF);   //循环读数      
    }  
    W25QXX_CS=1;                      
}

函数的入口参数pBuffer是数据存储区、ReadAddr是开始读取的地址(24bit)、NumByteToRead是要读取的字节数(最大65535)。

完成基本的读写函数后,接下来我们编写一个读写测试函数来检验驱动程。

代码清单10:W25Q32读写测试函数

uint8_t w25q32_Test(void)
{  
    u16 i;   
    printf("写入的数据:\r\n");  
    for ( i=0; i<=10; i++ )   
    {       
        spi_Buf_Write[i] = i;    
        printf("0x%02X ", spi_Buf_Write[i]);   
    }   
    W25QXX_Write((u8*)spi_Buf_Write,FLASH_SIZE-100,11);          
    printf("写成功,");     
    printf("读出的数据:\r\n");    
    W25QXX_Read(datatemp,FLASH_SIZE-100,11);            
    for (i=0; i<11; i++)  
    {      
        if(datatemp[i] != spi_Buf_Write[i])    
        {      
            printf("0x%02X ", datatemp[i]);      
            printf("错误:I2C EEPROM写入与读出的数据不一致");     
            return 0;    
        }    
        printf("0x%02X ", datatemp[i]);  
    }  
    printf("\r\n");    
    printf("spi(w25q32)读写测试成功");  
    return 1;
}

代码中先填充一个数组,数组的内容为0,1至10,接着把这个数组的内容写入到SPI FLASH中,并将写入的数据打印输出到串口调试助手。写入完毕后再从SPI FLASH的地址中读取数据,把读取到的数据与写入的数据进行校验,若一致说明读写正常,否则读写过程有问题或者SPI FLASH芯片不正常,然后再将读取到的数据打印输出到串口调试助手。

代码清单11:主函数

int main(void)
{     
    u16 id = 0;    
    NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);  
    delay_init(168);       
    USART_Configuration();  
    W25QXX_Init();        
    while(1)  
    {    
        id = W25QXX_ReadID();    
        if (id == W25Q32 || id == NM25Q32)      
            break;     
            printf("W25Q32 init failed\r\n");    
        delay_ms(500);    
        delay_ms(500);  
    }   
    printf("W25Q32 init success\r\n");   
    w25q32_Test(); 
     while(1)  
     {   
     }       
 }

主函数代码比较简单,主要是完成串口初始化和W25Q32的初始化,初始化完成之后会执行W25QXX_ReadID函数,读取W25Q32的ID,同时对ID进行判断,并将结果通过串口调试助手打印输出。然后会执行一次W25Q32测试函数,并将一些测试结果通过串口调试助手打印输出。

来源:中科芯MCU

免责声明:本文为转载文章,转载此文目的在于传递更多信息,版权归原作者所有。本文所用视频、图片、文字如涉及作品版权问题,请联系小编进行处理(联系邮箱:cathy@eetrend.com)。

围观 36

概述

使用TCP执行通讯时,会有Server与Client的差别。Server是经由开启特定的Port来等待来自Client端的连线需求;而Client端则是向Server端提出连线需求,此例程使用LwIP作为协议栈,可以使用tcp_bind(), tcp_listen()与tcp_accept()这三种系统呼叫来使Server端接受Client的连线要求。

本使用指南会分别说明TCP client与TCP server该如何与PC端通信。

硬件资源

1) AT-START-F407 V1.0实验板
2) DM9162以太网模块
3) 以太网线

软件资源

tcp_client, TCP client源程序,运行TCP客户端程序

tcp_server, TCP server源程序,运行TCP服务端程序

AT32 TCP client/server程序设置

管脚配置

表1. 管脚配置

“AT32

LwIP设置

硬件资源只提供从PHY到MAC的信号处理,若要进行开发,则需要实作TCP/IP协议栈,在本应用中使用LwIP协议栈,该协议栈主要关注的是怎样减少减少内存的使用和程序代码的大小,这样就可以让LwIP适用于资源有限的小型平台例如嵌入式系统,更详细的内容可以访问官方网站。

由于整个协议栈已经整合到代码中,大部分的内容都无须修改,使用者只要根据自己的网段去设定IP地址及闸口地址即可,这两个全局变量宣告在netconf.c的上头。

“图1.
图1. 配置芯片的IP地址

TCP client project设置

在初始化LwIP协议栈之后,就可以配置TCP client的应用了,芯片作为客户端是发出请求的一方,所以必须要配置往哪里发送数据,也就是说要知道服务端的socket。所谓的socket就是IP地址加上端口,在代码中我们宣告了几个宏定义代表服务端的socket,可以在tcp_client.h中找到TCP_SERVER_IP跟TCP_SERVER_PORT这两个宏定义,用户可以根据网段跟应用修改这两个宏。

“图2.
图2. 配置服务端的socket

确认网段与服务端一致后,下载代码到芯片上,服务器端会一秒打印一次”tcp client experiment!”,同时LED2, 3, 4也会跟着闪烁。

上位机服务端设置

1) 设定上位机的IP地址、网路屏蔽及闸口,IP地址与闸口需要跟芯片设置在同一个网段下。

2) 打开上位机端的服务器软件,这里使用网路调适助手为例。协议类型选择TCP server,本地IP地址为代码中的TCP_SERVER_IP,本地端口号为代码中的TCP_SERVER_PORT,按下连线即建立连线。

3) 连线建立后,会出现以下画面,不断打印来自TCP client的数据。

“图3.
图3. 设置PC端的IP、网路屏蔽与闸口

“图4.
图4. 设置服务器软件

“图5.
图5. 接收TCP client的数据

TCP server project设置

在初始化LwIP协议栈之后,就可以配置TCP server的应用了,芯片作为客户端是接受请求的一方,所以必须要配置在哪里接受数据,也就是说要开个端口给客户端丢数据进来。在代码中我们宣告了一个宏定义代表服务端的端口,可以在tcp_server.h中找到TCP_LOCAL_PORT这个宏定义,用户可以根据应用修改这个宏。

“图6.
图6. 服务器端口的宏定义

上位机客户端设置

1) 设定上位机的IP地址、网路屏蔽及闸口,IP地址与闸口需要跟芯片设置在同一个网段下,请参考图3。

2) 打开上位机端的服务器软件,这里使用网路调适助手为例。协议类型选择TCP client,服务器IP地址为芯片的IP地址,本地端口号为代码中的TCP_LOCAL_PORT,按下连线即建立连线。

3) 此时会出现讯息在视窗中,可以透过调试助手下方的区块输入字符串发送给服务器,服务器会响应输入的字符串到视窗中。

“图7.
图7. 设置上位机的客户端软件

图8.
图8. 显示讯息到视窗中并响应发送的字符串

关于雅特力

雅特力科技于2016年成立,是一家致力于推动全球市场32位微控制器(MCU)创新趋势的芯片设计公司,专注于ARM ®Cortex®-M4/M0+的32位微控制器研发与创新,全系列采用55nm先进工艺及ARM® Cortex®-M4高效能或M0+低功耗内核,缔造M4业界最高主频288MHz运算效能,并支持工业级别芯片工作温度范围(-40°~105°)。
雅特力目前已累积相当多元的终端产品成功案例:如微型打印机、扫地机、光流无人机、热成像仪、激光雷达、工业缝纫机、伺服驱控、电竞周边市场、断路器、ADAS、T-BOX、数字电源、电动工具等终端设备应用,广泛地覆盖5G、物联网、消费、商务及工控等领域。

来源:AT32 MCU 雅特力科技
免责声明:本文为转载文章,转载此文目的在于传递更多信息,版权归原作者所有。本文所用视频、图片、文字如涉及作品版权问题,请联系小编进行处理(联系邮箱:cathy@eetrend.com)。

围观 158

今天我们来讲讲,下面这个“电平转换”电路,理解后令人心情愉快。电路设计其实也可以很有趣。先说一说这个电路的用途:当两个MCU在不同的工作电压下工作(如MCU1 工作电压5V;MCU2 工作电压3.3V),那么MCU1 与MCU2之间怎样进行串口通信呢?很明显是不能将对应的TX、RX引脚直接相连的,否测可能造成较低工作电压的MCU烧毁!下面的“电平双向转换电路”就可以实现不同VDD(芯片工作电压)的MCU之间进行串口通信。

“不同的电平信号的MCU怎么通信?"

该电路的核心在于电路中的MOS场效应管(2N7002)。他和三极管的功能很相似,可做开关使用,即可控制电路的通和断。不过比起三极管,MOS管有挺多优势,后面将会详细讲起。下图是MOS管实物3D图和电路图。简单的讲,要让他当做开关,只要让Vgs(导通电压)达到一定值,引脚D、S就会导通,Vgs没有达到这个值就截止。

“不同的电平信号的MCU怎么通信?"

那么如何将2N7002应用到上面电路中呢,又起着什么作用呢?下面我们来分析一下。

“不同的电平信号的MCU怎么通信?"

如果沿着a、b两条线,将电路切断。那么MCU1的TX引脚被上拉为5V,MCU2的RX引脚也被上拉为3.3V。2N7002的S、D引脚(对应图中的2、3引脚)截止就相当于a、b两条线,将电路切断。也就是说,此电路在2N7002截止的时候是可以做到,给两个MCU引脚输送对应的工作电压。

下面进一步分析:

数据传输方向MCU1-->MCU2。

“不同的电平信号的MCU怎么通信?"

1. MCU1 TX发送高电平(5V),MCU2 RX配置为串口接收引脚,此时2N7002的S、D引脚(对应图中的2、3引脚)截止,2N7002里面的二极管3-->2方向不通。那么MCU2 RX被VCC2上拉为3.3V。

2. MCU1 TX发送低电平(0V),此时2N7002的S、D引脚依然截止,但是2N7002里面的二极管2-->3方向通,即VCC2、R2、2N7002里的二极管、MCU1 TX组成一个回路。2N7002的2引脚被拉低,此时MCU2 RX为0V。该电路从MCU1到MCU2方向,数据传输,达到了电平转换的效果。

接下来分析

数据传输方向MCU2-->MCU1

“不同的电平信号的MCU怎么通信?"

1. MCU2 TX发送高电平(3.3V),此时Vgs(图中1、2引脚电压差)电压差约等于0,2N7002截止,2N7002里面的二极管3-->2方向不通,此时MCU1 RX引脚被VCC1上拉为5V。

2. MCU2 TX发送低电平(0V),此时Vgs(图中1、2引脚电压差)电压差约等于3.3V,2N7002导通,2N7002里面的二极管3-->2方向不通,VCC1、R1、2N7002里的二极管、MCU2 TX组成一个回路。2N7002的3引脚被拉低,此时MCU1 RX为0V。

该电路从MCU2到MCU1方向,数据传输,达到了电平转换的效果。

到此,该电路就分析完了,这是一个双向的串口电平转换电路。

MOS的优势:

1、场效应管的源极S、栅极G、漏极D分别对应于三极管的发射极e、基极b、集电极c,它们的作用相似,图一所示是N沟道MOS管和NPN型晶体三极管引脚,图二所示是P沟道MOS管和PNP型晶体三极管引脚对应图。

“不同的电平信号的MCU怎么通信?"

2、场效应管是电压控制电流器件,由VGS控制ID,普通的晶体三极管是电流控制电流器件,由IB控制IC。MOS管道放大系数是(跨导gm)当栅极电压改变一伏时能引起漏极电流变化多少安培。晶体三极管是电流放大系数(贝塔β)当基极电流改变一毫安时能引起集电极电流变化多少。

3、场效应管栅极和其它电极是绝缘的,不产生电流;而三极管工作时基极电流IB决定集电极电流IC。因此场效应管的输入电阻比三极管的输入电阻高的多。

4、场效应管只有多数载流子参与导电;三极管有多数载流子和少数载流子两种载流子参与导电,因少数载流子浓度受温度、辐射等因素影响较大,所以场效应管比三极管的温度稳定性好。

5、场效应管在源极未与衬底连在一起时,源极和漏极可以互换使用,且特性变化不大,而三极管的集电极与发射极互换使用时,其特性差异很大,b 值将减小很多。

6、场效应管的噪声系数很小,在低噪声放大电路的输入级及要求信噪比较高的电路中要选用场效应管。

7、场效应管和普通晶体三极管均可组成各种放大电路和开关电路,但是场效应管制造工艺简单,并且又具有普通晶体三极管不能比拟的优秀特性,在各种电路及应用中正逐步的取代普通晶体三极管,目前的大规模和超大规模集成电路中,已经广泛的采用场效应管。

8、输入阻抗高,驱动功率小:由于栅源之间是二氧化硅(SiO2)绝缘层,栅源之间的直流电阻基本上就是SiO2绝缘电阻,一般达100MΩ左右,交流输入阻抗基本上就是输入电容的容抗。由于输入阻抗高,对激励信号不会产生压降,有电压就可以驱动,所以驱动功率极小(灵敏度高)。一般的晶体三极管必需有基极电压Vb,再产生基极电流Ib,才能驱动集电极电流的产生。晶体三极管的驱动是需要功率的(Vb×Ib)。

9、开关速度快:MOSFET的开关速度和输入的容性特性的有很大关系,由于输入容性特性的存在,使开关的速度变慢,但是在作为开关运用时,可降低驱动电路内阻,加快开关速度(输入采用了后述的“灌流电路”驱动,加快了容性的充放电的时间)。MOSFET只靠多子导电,不存在少子储存效应,因而关断过程非常迅速,开关时间在10—100ns之间,工作频率可达100kHz以上,普通的晶体三极管由于少数载流子的存储效应,使开关总有滞后现象,影响开关速度的提高(目前采用MOS管的开关电源其工作频率可以轻易的做到100K/S~150K/S,这对于普通的大功率晶体三极管来说是难以想象的)。

10、无二次击穿:由于普通的功率晶体三极管具有当温度上升就会导致集电极电流上升(正的温度~电流特性)的现象,而集电极电流的上升又会导致温度进一步的上升,温度进一步的上升,更进一步的导致集电极电流的上升这一恶性循环。而晶体三极管的耐压VCEO随管温度升高是逐步下降,这就形成了管温继续上升、耐压继续下降最终导致晶体三极管的击穿,这是一种导致电视机开关电源管和行输出管损坏率占95%的破环性的热电击穿现象,也称为二次击穿现象。MOS管具有和普通晶体三极管相反的温度~电流特性,即当管温度(或环境温度)上升时,沟道电流IDS反而下降。例如;一只IDS=10A的MOS FET开关管,当VGS控制电压不变时,在250C温度下IDS=3A,当芯片温度升高为1000C时,IDS降低到2A,这种因温度上升而导致沟道电流IDS下降的负温度电流特性,使之不会产生恶性循环而热击穿。也就是MOS管没有二次击穿现象,可见采用MOS管作为开关管,其开关管的损坏率大幅度的降低,近两年电视机开关电源采用MOS管代替过去的普通晶体三极管后,开关管损坏率大大降低也是一个极好的证明。

11、MOS管导通后其导通特性呈纯阻性:普通晶体三极管在饱和导通是,几乎是直通,有一个极低的压降,称为饱和压降,既然有一个压降,那么也就是;普通晶体三极管在饱和导通后等效是一个阻值极小的电阻,但是这个等效的电阻是一个非线性的电阻(电阻上的电压和流过的电流不能符合欧姆定律),而MOS管作为开关管应用,在饱和导通后也存在一个阻值极小的电阻,但是这个电阻等效一个线性电阻,其电阻的阻值和两端的电压降和流过的电流符合欧姆定律的关系,电流大压降就大,电流小压降就小,导通后既然等效是一个线性元件,线性元件就可以并联应用,当这样两个电阻并联在一起,就有一个自动电流平衡的作用,所以MOS管在一个管子功率不够的时候,可以多管并联应用,且不必另外增加平衡措施(非线性器件是不能直接并联应用的)。

来源:STM32嵌入式开发
免责声明:本文为转载文章,转载此文目的在于传递更多信息,版权归原作者所有。本文所用视频、图片、文字如涉及作品版权问题,请联系小编进行处理(联系邮箱:cathy@eetrend.com)。

围观 311

全球半导体解决方案供应商瑞萨电子集团(TSE:6723)今日宣布,面向数据中心、服务器和网络基础设施领域推出抖动低于100fs的全新“使用点”时钟解决方案,以扩展瑞萨时钟解决方案。全新FemtoClock2产品家族包括超低抖动时钟发生器和抖动衰减器,采用4mm x 4mm小型封装,可为新一代高速互连设计配置经济且简单的时钟树。

“”

FemtoClock2可提供达64fs RMS的超低抖动性能,使客户能够轻松满足新交换机或路由器设计对新一代PAM4的要求。FemtoClock2产品家族为4mm x 4mm封装,不足市场同类解决方案尺寸的三分之一。这使得设计人员可将时钟源放置于使用点(即非常靠近接收时钟信号的器件),以简化PCB布局、减少串扰,获得更干净的信号。优异的灵活性使该系列产品适用于诸多应用。FemtoClock2可配置为DCO、时钟发生器或抖动衰减器,从而提供极具价值的设计灵活性和复用性。

瑞萨电子数据中心事业部时钟产品副总裁Bobby Matinpour表示:“PAM4技术正在推动通信和数据中心领域数据传输速率的重大飞跃,由此也对该类系统中的时钟提出严苛要求。此次我们扩展广受欢迎的FemtoClock产品阵容,推出全新高性能产品家族,以小尺寸提供超低抖动和低功耗,让时钟可放置于板上任何便于使用的位置。通过消除与电路板上时钟走线相关的附加抖动,大幅简化设计。”

FemtoClock2产品家族的关键特性

  • 抖动低至64fs(典型值)RMS
  • 600mW低功耗
  • 采用24和28引脚,4mm x 4mm QFN封装
  • 具有四个差分输出的单、双输入选项
  • 电源噪声抑制优于-80dB
  • 输出到输出隔离为-80dBc
  • 符合ITU-T G.8262和G.8262.1标准,用于增强型同步以太网/OTN
  • 集成晶体选件,可节省更多空间

用户可将全新FemtoClock2解决方案与瑞萨小型、单输出、高性能振荡器,或更广泛的ClockMatrixTM系列时钟解决方案相结合,以满足高性能服务器和网络基础设施设计中对时钟产品的严苛要求。FemtoClock2也可与新近推出的基于IEEE1588协议的PTP Clock Manager无缝结合, 亦可与瑞萨丰富的电源、微控制器相结合, 开发多种应用, 如IEEE1588成功产品组合等。FemtoClock2作为下游时钟,能够在不中断同步的情况下在引脚上实现100fs低抖动。

瑞萨电子作为先进供应商,提供“一站式”时钟解决方案,涵盖从全功能系统解决方案到简单的时钟树构建模块的专业技术及产品。

供货信息

RC32504A和RC22504A FemtoClock解决方案及评估板现已上市。更多信息,请访问:renesas.com/femtoclock2。

关于瑞萨电子集团

瑞萨电子集团 (TSE: 6723) ,提供专业可信的创新嵌入式设计和完整的半导体解决方案,旨在通过使用其产品的数十亿联网智能设备改善人们的工作和生活方式。作为全球微控制器、模拟、电源和SoC产品供应商,瑞萨电子为汽车、工业、家居、基础设施及物联网等各种应用提供综合解决方案,期待与您携手共创无限未来。更多信息,敬请访问renesas.com。

围观 18

所谓“时序”从字面意义上来理解,一是“时间问题”;二是“顺序问题”。

先说一下“顺序问题”,这个相对简单一些。我们在学UART串口通信的时候,先1位起始位,再8位数据位,最后1位停止位,这个先后顺序不能错。我们在学1602液晶的时候,比如写指令,RS=L,R/W=L,D0~D7=指令码,这三者的顺序是无所谓的,但是最终的E=高脉冲,必须是在这三条程序之后,这个顺序一旦错误,写的数据也可会出错。

而“时间问题”内容相对复杂,比如UART通信,每一位的时间宽度是1/baud。我们初中就学过一个概念,世界上没有绝对的准确。那么每一位的时间宽度1/baud要求精确到什么范围内呢?

单片机读取UART的RXD引脚数据的时候,一位数据,单片机平均分成了16份,取其中的7、8、9三次读到的结果,这三次中有2次是高电平那这一位就是1,有2次是低电平,那这一次就是0。如果我们的波特率稍微有些偏差,只要累计下来到最后一位停止位,这7、8、9还在范围内即可。如下图所示:

“UART信号采集时序图"
UART信号采集时序图

我们用三个箭头来表示7、8、9这三次的采集位置,大家可以看到,当采集到 D7的时候,已经有一次采集偏出去了,但我们采集到的数据还是不会错,因为有2次采集正确。至于这个偏差允许多大,大家自己可以详细算一下。实际上UART通信的波特率是允许一定范围内误差存在的,但不能过大,否则就会采集错误。

大家在计算波特率的时候,发现没有整除,有小数部分的时候,就要特别小心了,因为小数部分是一概被舍掉的,于是计算误差就产生了。我们用11.0592M晶振计算的过程中,11059200/12/32/9600得到的是一个整数,如果用12M晶振计算12000000/12/32/9600就会得到一个小数,大家可以算一下误差多少,是否在误差范围内。

1602的时序问题,大家要学会通过LCD1602的数据手册提供的时序图和时序参数表格来进行研究,而且看懂时序图是学习单片机所必须掌握的一项技能,如下图所示:

“1602时序图"
1602时序图

大家看到这种图的时候不要感觉害怕,说句不过分的话,单片机这些逻辑上的问题,只要小学毕业就可以理解的,很多时候是因为大家把问题想象的太难才学不下去的。

我们先来看一下读操作时序的RS引脚和R/W引脚,这两个引脚先进行变化,因为是读操作,所以R/W引脚首先要置为高电平,而不管它原来是什么。读指令还是读数据,都是读操作,而且都有可能,所以RS引脚既有可能是置为高电平,也有可能是置为低电平,大家注意上图的画法。而RS和R/W变化了经过Tsp1这么长时间后,使能引脚E才能从低电平到高电平发生变化。

而使能引脚E拉高经过了tD这么长时间后,LCD1602输出DB的数据就是有效数据了,我们就可以来读取DB的数据了。读完了之后,我们要先把使能E拉低,经过一段时间后RS、R/W和DB才可以变化继续为下一次读写做准备了。

而写操作时序和读操作时序的差别,就是写操作时序中,DB的改变是由单片机来完成的,因此要放到使能引脚E的变化之前进行操作,其它区别大家可以自行对比一下。

细心的话就会发现,这个时序图上还有很多时间标签。比如E的上升时间tR,下降时间时间tF,使能引脚E从一个上升沿到下一个上升沿之间的长度周期tC,使能E下降沿后,R/W和RS变化时间间隔tHD1等等很多时间要求,这些要求怎么看呢?放心,只要是正规的数据手册,都会把这些时间要求给大家标记出来的。

“”

大家要善于把手册中的这个表格和时序图结合起来看,上面表中的数据都是时序参数,大家务必要学会自己看时序图,这个很重要。此外,看以下解释也需要结合时序图来看。

tC:指的是使能引脚E从本次上升沿到下次上升沿的最短时间是400ns,而我们单片机因为速度较慢,一个机器周期就是1us多,而一条C语言指令肯定是一个或者几个机器周期的,所以这个条件完全满足。

tPW:指的是使能引脚E高电平的持续时间最短是150ns,同样由于我们的单片机比较慢,这个条件也完全满足。

tR,tF:指的是使能引脚E的上升沿时间和下降沿时间,不能超过25ns,别看这个数很小,其实这个时间限值是很宽裕的,我们实际用示波器测了一下开发板的这个引脚上升沿和下降沿时间大概是10ns到15ns之间,完全满足。

tSP1:指的是RS和R/W引脚使能后至少保持30ns,使能引脚E才可以变成高电平,这个条件同样也完全满足。

tHD1:指的是使能引脚E变成低电平后,至少保持10ns之后,RS和R/W才能进行变化,这个条件也完全满足。

tD:指的是使能引脚E变成高电平后,最多100ns后,1602就把数据送出来了,那么我们就可以正常去读取状态或者数据了。

tHD2:指的是读操作过程中,使能引脚E变成低电平后,至少保持20ns,DB数据总线才可以进行变化,这个条件也完全满足。

tSP2:指的是DB数据总线准备好后,至少保持40ns,使能引脚E才可以从低到高进行使能变化,这个条件也完全满足。

tHD2:指的是写操作过程中,要引脚E变成低电平后,至少保持10ns,DB数据总线才可以变化,这个条件也完全满足。

好了,LCD1602的时序参数表已经解析完成了,看完之后,是不是感觉比你想象的要简单,没有你想的那么困难。大家自己也得慢慢学会看这种时序图和表格,在今后的学习中,这方面的能力尤为重要。如果以后换用了其它型号的单片机,那么就根据单片机的执行速度来评估你的程序是否满足时序要求。整体来说,器件都是有一个最快速度的限制,而没有最慢限制,所以当换用高速的单片机后,通常都是靠在各步骤间插入软件延时来满足较慢的时序要求。

本文转载自:网络
免责声明:本文为转载文章,转载此文目的在于传递更多信息,版权归原作者所有。本文所用视频、图片、文字如涉及作品版权问题,请联系小编进行处理(联系邮箱:
cathy@eetrend.com)。

围观 28

页面

订阅 RSS - 通信