简介:SC16IS752 是 Microchip 推出的 I2C 转双 UART 桥接芯片,适用于嵌入式系统、物联网设备及工业自动化等串行通信场景。这份参考代码围绕芯片提供完整驱动实现,面向需要快速集成 I2C 转串口功能的单片机开发者,重点解决底层寄存器配置、数据收发、FIFO 管理与中断响应等实际问题。资源为 RAR 压缩包,共计 5 个文件,包含 3 个头文件和 2 个 C 源文件,压缩包整体仅 7KB,结构清晰简洁;头文件定义寄存器映射和对外接口,C 文件实现初始化、波特率设置、FIFO 读写及中断服务等核心逻辑,注释直观,便于二次开发与直接移植。已有 1763 人学习下载,内容适合作为驱动开发参考或嵌入到实际项目中。通过学习这份代码,可以快速掌握 SC16IS752 的寄存器操作和 I2C 时序控制,同时理解低功耗模式、错误处理及缓冲管理细节,从而有效缩短串行通信模块的调试周期。
1. 项目概述
1.1 这块芯片到底是干什么的
之前做项目时遇到过一次比较头疼的情况:主控MCU的UART不够用了,板子上要接一个4G模组、一个GPS、还有一个调试串口,总共要三个串口,但手上那颗MCU只有两个。换更大封装的芯片不现实,改板子周期又长,最后方案定下来用SPI转UART的桥接芯片,选的正是SC16IS752。这个芯片可以一路SPI或者I2C扩展出两路UART,两个串口的问题直接就解决了。
SC16IS752属于NXP的SC16IS7xx系列,这个系列里740是单通道、750/752是双通道、760是四通道(不过760实际是I2C/SPI转四路UART)。我们常用的752就是双通道版本,内部集成256字节的发送FIFO和256字节的接收FIFO,支持硬件流控(RTS/CTS)、软件流控(XON/XOFF)、IrDA红外协议,还有8个可编程GPIO口,工作电压从2.3V到3.6V。它挂在SPI或I2C总线上,对主控来说就是一组寄存器,读写操作和操作普通SPI设备没什么区别。
这个芯片的应用场景很集中:MCU串口不够用时的扩展方案、嵌入式Linux系统里通过SPI扩展串口、需要隔离的工业场景(SPI侧隔离比UART侧隔离成本低很多)、还有FPGA项目中需要额外串口的情况。对嵌入式工程师来说,SCIS752是一块性价比很高的芯片,单价也不高,而且驱动代码成熟,网上参考很多,上手难度不大。
1.2 为什么我决定把参考代码整理出来
网络上关于SCIS752的资料不少,数据手册(DS100W)写得很详细,但说实话,手册是给查寄存器用的,不是给入门用的。我最初调这块芯片时,光是把初始化流程理顺就花了大半天,各种寄存器之间的依赖关系(比如波特率分频和FIFO触发电平的关系、FIFO使能和中断使能的先后顺序)手册里分散在不同章节,没有一条主线串起来。
这篇博文我打算沿着“硬件设计 -> 寄存器配置 -> 实际代码 -> 问题排查”这条路径来梳理,把我实际调试中验证过的参考代码直接放出来。如果你是第一次用这个芯片,按着这套代码走,很快就能让串口跑起来;如果你已经调通了,也可以看看后面“常见问题”部分,有一些不太容易发现的坑,我自己就踩过,比如FIFO触发电平的配置时机、波特率误差的计算方法,这些细节一旦忽略,调起来会非常痛苦。
2. 芯片选型与整体设计思路
2.1 系列型号差异:740/750/752/760怎么选
SC16IS7xx系列从后缀就能大概判断通道数:40结尾是单通道,50/52结尾是双通道,60结尾是四通道。更具体的差异点我整理成了一张表:
| 型号 | 通道数 | 接口 | FIFO大小 | 备注 |
|---|---|---|---|---|
| SC16IS740 | 1 | SPI/I2C | 64字节 | 入门级,管脚少 |
| SC16IS750 | 1 | SPI/I2C | 128字节 | 带时钟输出 |
| SC16IS752 | 2 | SPI/I2C | 256字节 | 双通道,最常用 |
| SC16IS760 | 2 | SPI/I2C | 256字节 | 752的改进版,功耗略低 |
我选芯片时主要看三点:通道数够不够、FIFO够不够深、封装能否手工焊接。752的256字节FIFO在115200波特率下可以缓冲大约22ms的数据,对大多数MCU来说完全够用,即使主控偶尔被中断占用,也不容易丢数据。封装上752有TSSOP和HVQFN两种,TSSOP引脚间距0.65mm,手工焊接没问题,HVQFN就需要热风枪或者回流焊了,打样验证阶段尽量选TSSOP。
2.2 硬件电路设计的几个细节
把SC16IS752接入系统,SPI接口一般只需要四根线:SCLK、MOSI、MISO、CS,外加一根中断输出引脚(IRQ)。IRQ这个脚建议一定要接到主控的外部中断输入上,不要为了省引脚而忽略,因为后面讲到的接收FIFO中断、发送FIFO空中断、错误中断都要靠这根线来通知主控。如果不接IRQ,就得靠轮询状态寄存器来判断是否有数据,浪费CPU时间不说,在高速率下还可能丢数据。
复位引脚(RESET)需要拉低至少几百纳秒才能完成复位,上电后建议由主控主动拉低再释放,不要让它悬空。复位释放后,芯片还需要一小段时间内部振荡器才能稳定,我个人习惯在释放复位后再延时1ms左右才开始访问寄存器,实测这样最稳妥。
还有一个容易忽略的点是SPI的时钟极性(CPOL)和相位(CPHA)配置。SC16IS752的SPI接口支持模式0(CPOL=0,CPHA=0),也可以通过SPI配置寄存器改成模式1/2/3,但默认推荐用法是模式0。如果SPI总线上还挂了其他设备,注意确认每个设备的SPI模式,不能为了迁就某一个设备而把总线模式改了,不然另一个设备就会工作异常。
I2C接口方面,SC16IS752有一个硬件地址引脚(A0/A1),通过上下拉电阻组合出四个不同的I2C地址,所以一条I2C总线上最多可以挂四片752,扩展出8路串口。这个能力在实际项目中很有用,比如做串口服务器或者多路采集设备时,一块主控加上两片752就能轻松扩展出4路串口。
3.3V供电和电平匹配也要留意。芯片供电范围2.3~3.6V,IO引脚耐压最高到5V(数据手册上标注了5V tolerant),所以可以直接和5V的SPI主控相连,不需要额外电平转换。但如果是开漏I2C接口,上拉电阻需要接到3.3V而不是5V,否则I2C高电平会是5V,长时间运行有风险。
3. 软件框架与寄存器体系
3.1 寄存器地图和访问方式
SC16IS752内部寄存器分为两类:一类是通用寄存器(THR/RHR、IER、FCR、LCR、MCR、LSR、MSR、SPR等),一类是额外扩展寄存器(通过LCR[7]=1切换到扩展页访问)。寄存器映射非常类似经典的16550 UART,如果你以前写过PC串口驱动或者用过其他UART控制器,看这个芯片的寄存器会觉得非常亲切。
对752来说,A0/A1引脚或寄存器SPR的bit7/bit6用来选择当前访问的是通道A还是通道B。用SPI接口时,通过地址字节的最高两位来判断,比如SPI地址字节格式是0xXX,其中bit1=0/1选择通道A/B,bit0表示读(1)或写(0)。I2C接口则是通过I2C从地址的低两位来区分通道。这个细节务必注意,很多刚上手的读者第一次写代码发现两个通道都不工作,就是因为地址字节最高位带错了,导致实际访问的寄存器不对。
寄存器操作还有一个特点:部分寄存器在读取时有副作用。比如读取RHR(接收保持寄存器)会把接收FIFO中当前字节弹出,读取LSR状态寄存器时某些错误标志位会被清零。所以在写驱动时,要非常小心读寄存器的顺序,否则可能把错误状态意外清掉,导致问题定位困难。
3.2 波特率如何计算和配置
UART通信最重要的参数就是波特率,SC16IS752的波特率发生器是一个可编程分频器,内部有一个16位分频寄存器(DLL/DLM),参考时钟要么是芯片内部振荡器(默认约14.7456MHz),也可以从XTA/XTB引脚外接晶振,或者由外部输入时钟。
波特率计算公式如下:
波特率 = 参考时钟频率 / (16 × 分频值)这里的分频值是一个16位整数,可以表示为DLL + 256 × DLM。以内部默认的14.7456MHz时钟、目标波特率115200为例:
分频值 = 14.7456e6 / (16 × 115200) = 14.7456e6 / 1843200 = 8DLL=0x08,DLM=0x00,很简单。但如果目标波特率是9600:
分频值 = 14.7456e6 / (16 × 9600) = 14.7456e6 / 153600 = 96DLL=0x60,DLM=0x00,依然是一个整数。
不过实际项目中经常会遇到参考时钟和目标波特率不能整除的情况,比如外部接了12MHz晶振,目标波特率还是115200:
分频值 = 12e6 / (16 × 115200) = 12e6 / 1843200 ≈ 6.51取整后DLL=6或DLL=7,实际波特率会偏大或偏小。分频值取6时实际波特率 = 12e6 / (16×6) = 125000,误差约8.5%,实测这个误差在UART通信中是不可接受的,误码率很高。所以选晶振时要尽量选能被目标波特率整数倍整除的频率,14.7456MHz、18.432MHz、22.1184MHz这类“UART专用晶振”就是为了让绝大多数常用波特率都能整除而设计的。
如果必须使用非标晶振,SC16IS752还有一个MCR[7]=1的增强波特率模式(实际上是通过MCR的bit7使能),它把分频基数从16降到8,这样能覆盖更多波特率组合,但代价是接收采样率降低,抗干扰能力变差。实践中我一般不推荐这么做,能用标准晶振就尽量用标准晶振。
4. 参考代码实现与驱动解析
4.1 SPI初始化:第一步是把通信打通
写任何驱动之前,首先要确保主控能通过SPI正确读写752的寄存器。我一般先写一个最简单的寄存器回读测试:向SPR(ScratchPad寄存器,地址0x07)写入0x5A,再读出来,如果读回0x5A,说明SPI通信链路没问题。这一步虽然简单,但能隔离问题,如果是SPI模式配置错误、接线错误、还是芯片本身有问题,通过这个测试就能快速定位。
下面是我整理的SPI初始化参考代码,基于STM32标准库风格,但逻辑可以很方便地移植到其他平台:
/* SC16IS752 SPI操作相关宏定义 */ #define SC16IS752_CS_LOW() GPIO_ResetBits(GPIOB, GPIO_Pin_12) #define SC16IS752_CS_HIGH() GPIO_SetBits(GPIOB, GPIO_Pin_12) /* SPI读一个寄存器 */ uint8_t SC16IS752_ReadReg(uint8_t channel, uint8_t reg) { uint8_t addr = (channel << 1) | 0x01; /* bit1=通道, bit0=读标志 */ uint8_t val = 0; SC16IS752_CS_LOW(); SPI_SendByte(addr); SPI_SendByte(reg); val = SPI_SendByte(0xFF); /* 发送dummy字节,同时读取 */ SC16IS752_CS_HIGH(); return val; } /* SPI写一个寄存器 */ void SC16IS752_WriteReg(uint8_t channel, uint8_t reg, uint8_t val) { uint8_t addr = (channel << 1) | 0x00; /* bit0=写标志 */ SC16IS752_CS_LOW(); SPI_SendByte(addr); SPI_SendByte(reg); SPI_SendByte(val); SC16IS752_CS_HIGH(); }注意读操作时,SPI协议要求先发送地址字节和寄存器字节,然后发送一个dummy字节同时接收数据。752的SPI时序要求一次传输中CS必须一直拉低,不能中间拉高,这与一些SPI从设备的操作方式不同,写驱动时不要分多次传输。
我碰到过一次比较奇怪的故障,就是SPI读数据一直返回0xFF,排查了很久,最后发现是MISO引脚上拉了10K电阻,把读数据线钳位在高电平了。排查思路其实很简单:用示波器看MISO波形,如果SCLK有输出但MISO一直是稳定的高点,基本就是硬件问题而不是软件问题。
4.2 初始化序列:寄存器的正确打开方式
SC16IS752上电后默认处于普通模式,还不能直接收发数据。完整初始化步骤我总结如下:
- 复位芯片:拉低RESET引脚至少几百纳秒,再释放,延时1ms等待内部稳定。
- 通过SPR寄存器回读测试确认SPI通信正常。
- 配置LCR(Line Control Register,地址0x03):LCR=0xBF,使能访问扩展寄存器。
- 访问EFR(Enhanced Feature Register,地址0x02):填写EFR=0x00,关闭增强功能(后面需要硬件流控时再设置)。
- 配置LCR=0x80,使能访问波特率分频寄存器DLL/DLM(地址0x00/0x01)。
- 写入DLL和DLM,设定目标波特率分频值。
- 配置LCR为最终值:数据位、停止位、校验位。比如8N1就是LCR=0x03。
- 配置FCR(FIFO Control Register,地址0x02):使能FIFO,设置触发电平。一般我设为FCR=0x01(使能FIFO,8字节触发)或FCR=0x41(使能FIFO,16字节触发,注意bit6是接收FIFO触发选择之一)。
- 配置IER(Interrupt Enable Register,地址0x01):使能接收数据可用中断、接收字符超时中断。一般发送用轮询方式时,IER可以不使能发送保持寄存器空中断。
- 配置MCR(Modem Control Register,地址0x04):MCR=0x08(使能自动RTS流控,如果想用硬件流控的话)。
初始化代码示例:
void SC16IS752_Init(SC16IS752_TypeDef *dev) { /* 1. 复位芯片 */ SC16IS752_Reset(dev); /* 2. 回读测试 */ SC16IS752_WriteReg(dev->channel, SC16IS752_REG_SPR, 0x5A); if (SC16IS752_ReadReg(dev->channel, SC16IS752_REG_SPR) != 0x5A) { /* 通信异常,可以在这里打印错误或死循环 */ while(1); } /* 3. 配置LCR=0xBF,使能访问扩展寄存器 */ SC16IS752_WriteReg(dev->channel, SC16IS752_REG_LCR, 0xBF); /* 4. 关闭增强功能 */ SC16IS752_WriteReg(dev->channel, SC16IS752_REG_EFR, 0x00); /* 5. 使能波特率分频寄存器访问 */ SC16IS752_WriteReg(dev->channel, SC16IS752_REG_LCR, 0x80); /* 6. 设置波特率分频值:以14.7456MHz、115200为例,分频值=8 */ SC16IS752_WriteReg(dev->channel, SC16IS752_REG_DLL, 0x08); SC16IS752_WriteReg(dev->channel, SC16IS752_REG_DLM, 0x00); /* 7. 设置LCR=8N1 */ SC16IS752_WriteReg(dev->channel, SC16IS752_REG_LCR, 0x03); /* 8. 使能FIFO,设置接收触发为8字节 */ SC16IS752_WriteReg(dev->channel, SC16IS752_REG_FCR, 0x01); /* 9. 使能接收数据可用中断和字符超时中断 */ SC16IS752_WriteReg(dev->channel, SC16IS752_REG_IER, 0x05); /* 10. 如果需要自动RTS硬件流控,打开MCR的bit3 */ SC16IS752_WriteReg(dev->channel, SC16IS752_REG_MCR, 0x08); }初始化顺序里有一个地方要特别注意:IER(中断使能)一定要在FIFO使能之后再设置。如果先使能了接收中断但FIFO还没打开,芯片可能在内部状态未就绪时产生误中断,导致进入中断服务程序后读到的数据是无效的。我这个习惯是在一次调试中发现的,当时总是随机收到一个0x00字节,排查了好久才意识到是初始化顺序的问题。
4.3 数据收发:轮询和中断两种方式的参考代码
初始化完成之后,收发数据就简单了。轮询方式适合不关心CPU占用率的场景,代码最直接:
/* 发送单字节:轮询等待THR空 */ void SC16IS752_SendByte(SC16IS752_TypeDef *dev, uint8_t data) { /* 等待发送FIFO不满,LSR的bit5是THR空标志 */ while (!(SC16IS752_ReadReg(dev->channel, SC16IS752_REG_LSR) & 0x20)); SC16IS752_WriteReg(dev->channel, SC16IS752_REG_THR, data); } /* 接收单字节:非阻塞方式,返回是否读到数据 */ uint8_t SC16IS752_ReceiveByte(SC16IS752_TypeDef *dev, uint8_t *data) { if (SC16IS752_ReadReg(dev->channel, SC16IS752_REG_LSR) & 0x01) { *data = SC16IS752_ReadReg(dev->channel, SC16IS752_REG_RHR); return 1; } return 0; }这里需要注意LSR寄存器各bit的含义:bit0表示接收FIFO中有数据,bit5表示发送保持寄存器空(实际上反映的是发送FIFO不满),bit6表示发送FIFO空且移位寄存器空闲,bit7表示FIFO有数据错误(parity error、framing error等)。判断发送是否完成,要用bit6而不是bit5。
中断方式会复杂一些,但效率高很多。IRQ引脚输出低电平有效,当芯片内部有中断事件时IRQ拉低,主控进入外部中断服务程序后,先读IIR(中断标识寄存器,地址0x02)判断中断类型,再分别处理:
void EXTI15_10_IRQHandler(void) { if (EXTI_GetITStatus(EXTI_Line_12) != RESET) { uint8_t iir; while (1) { iir = SC16IS752_ReadReg(dev->channel, SC16IS752_REG_IIR); if (iir & 0x01) { /* 无中断待处理,退出循环 */ break; } switch ((iir >> 1) & 0x07) { case 0x04: /* 接收数据可用 */ while (SC16IS752_ReceiveByte(dev, &ch)) { /* 将ch放入自己的环形缓冲区 */ ringbuf_push(&dev->rx_ring, ch); } break; case 0x0C: /* 接收字符超时 */ while (SC16IS752_ReceiveByte(dev, &ch)) { ringbuf_push(&dev->rx_ring, ch); } break; case 0x02: /* 发送保持寄存器空 */ /* 如果发送缓冲区有数据则继续发送 */ if (ringbuf_pop(&dev->tx_ring, &ch)) { SC16IS752_SendByte(dev, ch); } break; default: /* 错误类型,读LSR清标志 */ SC16IS752_ReadReg(dev->channel, SC16IS752_REG_LSR); break; } } EXTI_ClearITPendingBit(EXTI_Line_12); } }要特别说明一点:IIR读取后会自动清除当前中断标志,所以读取IIR之前一定要先把数据从FIFO中读完,否则先清标志再读数据,数据可能还在FIFO里但中断已经丢了。我的处理方式是先循环读RHR、再回头读IIR确认没有其他待处理中断,避免漏数据。
4.4 GPIO扩展功能:顺带把IO也省了
SC16IS752还有一个很实用的功能:8个GPIO口(GPIO0~GPIO7),这些引脚既可以用作普通输入输出,也可以复用为特殊功能。通过IORCFG寄存器(地址0x0E)配置引脚模式,通过IOState寄存器(地址0x0F)读写IO状态。
GPIO配置的参考代码如下:
/* 将GPIO0~GPIO7全部配置为输出 */ void SC16IS752_GpioConfig(void) { /* 配置IORCFG寄存器,使能GPIO功能 */ SC16IS752_WriteReg(SC16IS752_CH_A, SC16IS752_REG_IORCFG, 0x00); /* 设置IOState,输出高电平 */ SC16IS752_WriteReg(SC16IS752_CH_A, SC16IS752_REG_IOSTATE, 0xFF); } /* 读取GPIO输入状态 */ uint8_t SC16IS752_GpioRead(void) { return SC16IS752_ReadReg(SC16IS752_CH_A, SC16IS752_REG_IOSTATE); }GPIO的实际作用比想象中大。我在一个项目里用752的GPIO控制外设的电源开关和复位信号,省了一颗IO扩展芯片,板子也简化了不少。GPIO的驱动能力是mA级别,直接驱动LED没问题,但驱动继电器这类大电流负载必须加三极管或MOS管。
5. 常见问题与排查技巧实录
5.1 收不到数据或数据乱码
这是使用752时最容易遇到的问题,现象分两类:一类是完全收不到数据,另一类是收到数据但内容不对。
完全收不到数据,先查SPI通信链路(用SPR回读测试),再查IRQ是否触发。如果IRQ一直不拉低,说明中断配置有问题,把IER寄存器读出来看看bit0和bit2是否为1。如果是轮询模式,检查LSR的bit0是否为1,如果bit0一直是0,说明接收FIFO里根本没数据,问题多半出在对端发送或芯片波特率配置上。
收到乱码就要算波特率误差。前面提过的分频值计算误差在这个场景下会直接表现为乱码,尤其是两边波特率不一致时。还有一个常见原因是LCR配置错误,比如对端是8N1,但芯片配成了7E1,自然会出乱码。
5.2 FIFO触发电平设置不当导致丢数据
FCR寄存器里可以设置接收FIFO的触发电平,可选值有1、4、8、14字节(对应FCR的bit6/bit7组合,但bit6在FCR寄存器里是保留位,真正控制触发值的是bit6/bit7,所以配置时要小心)。如果触发电平设得太高,比如14字节,而主控中断响应不及时,FIFO满了之后新数据就会覆盖旧数据,造成丢包。
我的经验是:在不确定主控负荷的情况下,把FIFO触发电平设为8字节(FCR=0x01)是比较保守可靠的方案。如果能确保中断及时处理,可以把触发电平设到14字节来减少中断频率,降低CPU占用。
5.3 硬件流控不好用
752的硬件流控有两种模式:自动RTS/CTS(通过EFR和MCR配置)和手动RTS/CTS(通过MCR控制RTS引脚)。自动模式比较常用,配置方法如下:
/* 使能自动RTS/CTS流控 */ SC16IS752_WriteReg(ch, SC16IS752_REG_LCR, 0xBF); /* 进入扩展寄存器 */ SC16IS752_WriteReg(ch, SC16IS752_REG_EFR, 0x10 | 0x20); /* 使能自动RTS+CTS */ SC16IS752_WriteReg(ch, SC16IS752_REG_LCR, 0x80); /* 回到波特率配置 */ SC16IS752_WriteReg(ch, SC16IS752_REG_MCR, 0x08); /* 使能自动RTS */ SC16IS752_WriteReg(ch, SC16IS752_REG_LCR, 0x03); /* 最终LCR */自动流控的坑在于:对端设备必须正确连接RTS/CTS信号线,不能只连TX/RX。很多调试时连着连着就只留三根线(TX、RX、GND),流控自然不起作用。另外,如果对端不支持流控信号,必须把EFR的流控位清零,否则芯片会一直等待CTS信号,发送超时,看起来就像死了一样。
5.4 中断服务程序里读FIFO陷入死循环
有一次调试时发现主控进了中断出不来,在线调试发现是在中断服务程序里死循环了。原因是我用了一个while循环去读FIFO,但接收FIFO读空之后LSR的bit0仍然为1,导致循环条件不成立,卡死在循环里。细看手册后发现,752的接收FIFO读空后,LSR的bit0需要额外的时钟周期才会清零,如果读得太快,FIFO空标志没有及时更新,就会出现这种问题。
解决方法是中断里最多读一次FIFO中所有的数据(通过LSR的bit0判断),如果一次没读完,退出中断让芯片再次拉低IRQ,主控再次进入中断。不要用一次中断把FIFO读空,尤其是高速数据流场景下,这个习惯能避免很多莫名其妙的死循环。
5.5 用示波器抓波形定位问题
如果以上排查都无效,那就上示波器。我调试752时通常会抓三个信号:SPI的SCLK和CS、UART侧的TX/RX、IRQ。SPI侧看CS拉低后SCLK是否有正确的时钟输出,地址字节和数据字节是否按预期发送;UART侧看TX输出波形是否正常,波特率是否匹配;IRQ看是否有中断脉冲产生。
有一次调试发送乱码的问题,用示波器抓了TX波形,发现一个字节的位宽明显不对,用光标量了一下,实际波特率和配置值差了十几个百分点。查下来是外部晶振型号选错了,实际频率和标称值差了很大。这种问题单纯看代码是看不出来的,经验就是:乱码问题优先查时钟,时钟没问题再查配置。
6. 写在最后的小结
调SC16IS752这块芯片,我个人最大的体会是:它是一个非常“经典”的外设,寄存器逻辑和PC时代的16550 UART几乎一脉相承,所以一旦熟悉了它的套路,以后看其他类似芯片的驱动都很快。它又一个“啰嗦”的地方,初始化步骤比较多,而且每一步之间有依赖关系,不能随意调整顺序。
如果你是用在嵌入式Linux系统里,内核自带的8250驱动其实已经支持SC16IS752,可以通过设备树直接配置,不需要自己写驱动。但对于裸机或RTOS环境,自己写一套驱动不仅能加深对芯片的理解,也更容易针对实际项目定制功能——比如把GPIO口和串口绑定在一起做电源控制,或者扩展出多路带流控的串口。
最后再分享一个小经验:如果项目量产,建议在PCBA测试阶段加一个自动检测程序,上电后依次向每个通道的SPR寄存器写入随机值再读回校验,这样能快速筛出焊接不良或贴错料的板子。这个小功能不复杂,但在产线上能省大量排查时间。
希望这篇博文能帮你快速上手SC16IS752。如果你在实际调试中遇到其他奇怪的问题,欢迎在评论区交流,我看到了会尽量回复。
本文还有配套的精品资源,点击获取