目录
1 CH432T 芯片的 SPI 通讯协议
1.1 SPI 时钟相位模式和片选
1.2 SPI 通讯协议
2 CH432 关键寄存器表
3 通讯时发生数据丢失
3.1 ch432手册分析
3.2 spi 时钟为 6.25M 时 SPI 总线上发送一个字节所需时间计算
3.3 CH432 的 FIFO 为 16 个字节,计算 115200 波特率如何读取 FIFO 才不会溢出
3.4 实际量测的 SPI 总线和串口接收中的的波形
3.4.1 有问题的信号,中断出现长时间拉低
3.4.2 信号分析
3.5 解决方法
对于硬件 SPI 接口,建议 SPI 设置是 CPOL=CPHA=0(MODE 0) 或者 CPOL=CPHA=1(MODE 3),并且数据位顺序是高位在前 MSB first。
CH432 芯片的 SPI 片选 , 低电平有效
第一个字节为地址码:
用于指定操作地址和读写操作方向。
其位 1 为数据传输方向,为 1 则写操作转,为 0 则读操作 , 位 5~ 位 2 指定当前操作地址。
写操作:
在地址码后发出一个字节的待写数据 ,CH432 收到并保存到指定地址。
读操作:
CH432 从指定地址读出一个字节数据并输出。
RBR |
|
接收缓冲寄存器。 如果 LSR 的 DATARDY 位为 1 则可以从该寄存器读取接收到的数据。 如果 FIFOEN 为 1,则从串口移位寄存器 RSR 接收到的数据首先被存放于接收 FIFO 中,然后通过该寄存器读出。 如果 FIFOEN 为 1,那么一次可以向FIFO中写入最多 16 个字节。 |
THR |
|
发送保持寄存器。 包括发送 FIFO,用于写入准备发送的数据。 如果 FIFOEN 为 1 则写入的数据 首先被存放于发送 FIFO 中,一次写入最多 16 个字节 ,然后通过发送移位寄存器 TSR 逐个输出。 |
FCR |
RECVTG1/RECVTG0 |
设置接收 FIFO 的中断和硬件流控制的触发点 00: 接收 满1个字节产生接收数据可用的中断,并在使能硬件流控制时自动无效 RTS 引脚。 01: 接收 满4个字节产生接收数据可用的中断,并在使能硬件流控制时自动无效 RTS 引脚。 10: 接收 满8个字节产生接收数据可用的中断,并在使能硬件流控制时自动无效 RTS 引脚。 11: 接收 满14个字节产生接收数据可用的中断,并在使能硬件流控制时自动无效 RTS 引脚。 |
TFIFORST |
该位置 1 则清空发送 FIFO 中的数据(不含 TSR) ,该位能够自动清 0,无需软件清 0。 |
|
RFIFORST |
该位置 1 则清空接收 FIFO 中的数据(不含 RSR) ,该位能够自动清 0,无需软件清 0。 |
|
FIFOEN |
该位为 1 则启用 FIFO,该位清 0 则禁用 FIFO,禁用 FIFO 后为 16C450 兼容模式,相当 于 FIFO 只有一个字节。 |
|
LCR |
DLAB |
该位为除数锁存器存取使能,为 1 时才能存取 DLL 和 DLM,为 0 时才能存取 RBR/THR/IER。 |
BREAKEN |
该位为 1 则强制产生 BREAK 线路间隔。 |
|
PARMODE1/PARMODE0 |
当 PAREN 为 1 时设置奇偶校验位的格式: 00: 奇校验 01: 偶校验 10: 标志位(MARK,置 1) , 11: 空白位(SPACE,清 0) 。 |
|
PAREN |
该位为 1 则允许发送时产生和接收时校验奇偶校验位,为 0 则无奇偶校验位。 |
|
STOPBIT |
该位为 1 则两个停止位,为 0 则一个停止位。 |
|
WORDSZ1/WORDSZ0 |
设置字长度 00: 5 个数据位 01: 6 个数据位 10: 7 个数据位 11 : 8 个数据位。 |
|
MCR |
AFE |
该位为 1 则允许 CTS 和 RTS 硬件自动流控制。 |
LOOP |
该位为 1 则使能内部回路的测试模式。 |
|
OUT2 |
该位为 1 则允许该串口的中断请求输出,否则该串口不产生实际中断请求。 |
|
OUT1 |
|
|
RTS |
|
|
DTR |
|
|
LSR |
RFIFOERR |
该位为 1 表示在接收 FIFO 中存在至少一个 PARERR、FRAMEERR 或 BREAKINT 错误。 |
TEMT |
该位为 1 表示发送保持寄存器 THR 和发送移位寄存器 TSR 全空。 |
|
THRE |
该位为 1 表示发送保持寄存器 THR 空。 |
|
BREAKINT |
该位为 1 表示检测到 BREAK 线路间隔。 |
|
FRAMEERR |
该位为 1 表示正在从接收 FIFO 中读取的数据的帧错误,缺少有效的停止位。 |
|
PARERR |
该位为 1 表示正在从接收 FIFO 中读取的数据的奇偶校验错。 |
|
OVERR |
该位为 1 表示接收 FIFO 缓冲区溢出。 |
|
DATARDY |
该位为 1 表示接收 FIFO 中有接收到的数据,读取 FIFO 中所有数据后,该位自动清 0。 |
|
DLL/DLM |
|
波特率除数锁存器。 DLL 是低字节,DLM 是高字节,两者组成的 16 位除数用于由 16 位计 数器构成的串口波特率产生器。 该除数 = 串口内部基准时钟 / 16 / 所需通讯波特率。 如果串口 内部基准时钟为 1.8432MHz,所需波特率为 9600bps,则除数=1843200/16/9600=12。 |
当单片机收到串口发送保持寄存器 THR 空的中断后 , 如果使能 FIFO, 那么可以向 THR 寄存器及 FIFO 一次写入最多 16 个字节 , 由 CH432 按顺序自动发送 ; 如果禁止 FIFO, 那么一次只能写入一个字 节 ; 如果没有数据需要发送 , 那么可以直接退出 ( 之前读取 IIR 时已经自动清除中断 ) 。
在查询方式下 , 单片机可以根据 LSR 寄存器的 THRE 位判断发送 FIFO 是否为空 ,THRE 为 1 则可 以向 THR
寄存器及 FIFO 写入数据 , 如果使能 FIFO, 那么一次可以写入最多 16 个字节。
《CH432DS1.pdf》P7
当单片机收到串口接收数据超时的中断后 , 可以先从 RBR 寄存器读取一个字节 , 然后查询 LSR 寄 存器的DATARDY 位 , 如果 DATARDY 位有效则再读取一个字节 , 直到 DATARDY 位无效。
《CH432DS1.pdf》P8
SPI 总线发送一个 bit 需要的时间是:
1 / 6250000 = 0.000 000 16 秒
SPI 总线发送一个字节,也就是 8 个 bit 需要的时间是:
0.000 000 16 秒 * 8 = 0.00000128 秒
SPI 总线通过 CH432 发送一个字节需要另外至少 3 个字节作为交互,也就是 CH432 串口上发出一个字节, SPI总线上要传输 4 个字节,所需时间至少为:
0.00000128 秒 * 4 = 0.000 00512 秒 = 5.12 微秒
实际示波器量测的 SPI 总线上传输 4 个字节需要 20us ,示波器图片如下:
假设串口设置为 8 位数据位, 2 位停止位,也就是串口上传输 10 个 bit 中包含一个字节。
115200 / 10 = 11520 bytes // 一秒钟可以传输 11520 个字节
传输一个字节所需时间为
1 / 11520 = 0.000086806 秒 = 86.806 微秒
填满 CH432 接收 FIFO ,也就是串口上传输 16 个字节的数据所需的时间为
0.000086806 * 16 = 0.001388889 秒 //约等于 1.39 毫秒
ls2k1000 读取 FIFO 的间隔要低于 1.39 毫秒,才不会导致 FIFO 数据溢出。
实际我们串口使用到是 8 位数据位, 1 位停止位,示波器量测的传输 16 个字节需要 1.38 毫秒,如下图
最上面到绿色信号是串口接收到数据到中断信号。
下面 3 个是 SPI 总线信号,没有 CS 。
在上面波形图里可以看到中断信号长时间拉低,这是由于串口接收 FIFO 中到数据没有被及时读取出来引起的。
再仔细看波形,在中断拉低的同时 SPI 总线一直有信号,这是发送程序在轮询 CH432 的 LSR 寄存器,导致总线一直被占用,进一步导致读取串口 FIFO 到程序获取不到 SPI 总线的使用权,从而出现无法及时读取串口 FIFO 里的数据。
综上考虑,需要优化数据发送部分到程序,禁止数据发送程序长时间占用 SPI 总线。
修改发送数据到程序,在发送完 14 个字节的数据后让出CPU使用权(schedle_timeout())。
修改完后运行,实际量测到的波形如下图所示,中断波形连续均匀,不会出现很大到空档。也不会出现丢数据的情况。
最上面到绿色信号是串口接收到数据到中断信号。
下面 3 个是 SPI 总线信号,没有 CS 。