目前WCH有三款串口扩展芯片CH432,CH438以及CH9434。
型号 | CH432 | CH438 | CH9434 |
扩展串口数量 | 2 | 8 | 4 |
通讯接口 | 并口/SPI(具体需要看芯片封装) | 并口 | SPI |
接口速度 | 支持最高 10MB的并口 24MHz的SPI | 10MB的8位并口 | 最高16Mbit/s 注1:见表格底 |
是否支持级联 | 是 | 是 | 是 |
FIFO大小 | 内置 16 字节的 FIFO 先进先出缓冲器,支持 4 个 FIFO 触发级 | 内置 128 字节的 FIFO 先进先出缓冲器,支持 4 个 FIFO 触发级 | 串口每个方向独立 FIFO 缓存,发送 1536 字节,接收 2048 字节 |
封装 | CH432Q(LQFP44) CH432T(SSOP20) | CH438L(LQFP128) CH438Q(LQFP44) | QFN48_5X5 |
电源 | 3.3V-5.3V (5V典型值) | 3.3V-5.3V (5V典型值) | 2.4V-3.6V (3.3V典型值) |
注1:CH9434的SPI最快时钟速度与CH9434的系统时钟有关系。最快速度(稳定)约为系统时钟的1/3。Eg:如果使用内部32M,倍频15,分频15.那么sys_clk还是32M,那么SPI_Clk不能超过10Mbit/s。
常见问题解决
1. CH432/8/CH9434的LSR寄存器进入break。
解答:这个是因为串口的RXD脚一直处于低电平导致的,只需要硬件接上拉等方式即可解决。
2. 如何判断CH432/CH438/CH9434芯片是否正常工作
解答:(1)检查硬件,检查芯片的VCC引脚的电压是否为手册里面要求的典型值。看一下VCC的纹波是否过大。
(2)在上电的情况,使用示波器去检查芯片的XI,看一下晶振是否有波形。
(3)检查硬件的连接线是否有问题(主控芯片与串口扩展芯片通讯接口的连接)
(4)通过接口发送对应的数据,往SCR寄存器写数据,再读出来看是否为刚刚写入的数据,如果是的,则表示芯片工作正常并且硬件基础的通讯连接没有问题。
注:这三个串口扩展芯片的SCR寄存器为用户自定义的寄存器,断电复位是会保持。
3. 主控芯片与芯片通讯不正常
解答:(1)首先检查硬件的连接。
(2)如果是SPI,检查一下SPI的CLK速度是否超过了芯片要求的最大值
(3)部分芯片对于命令与数据,命令与命令之间是由最小时间的间隔要求,具体需要看芯片手册。可以用逻辑分析仪查看是否有这些时间间隔。
(4)所有的SPI转串口(扩展)的芯片的时序,CS是在发送完addr和数据后,才会重新拉高的。具体可以看芯片手册的时序图。
4.有关串口扩展芯片的FIFO的问题
解答:三款串口扩展芯片的接收fifo触发点都是控制FCR寄存器的RECVTG1 和 RECVTG0位(3个芯片的大部分寄存器都是一样的)。
(1)CH432:RECVTG1 和 RECVTG0:设置接收 FIFO 的中断和硬件流控制的触发点,00 对应 1 个字节,即接收
满 1 个字节产生接收数据可用的中断,并在使能硬件流控制时自动无效 RTS 引脚,01 对应 4
个字节,10 对应 8 个字节,11 对应 14 个字节。(FIFO16字节)。
(2)CH438:RECVTG1 和 RECVTG0:设置接收 FIFO 的中断和硬件流控制的触发点,00 对应 1 个字节,即接收
满 1 个字节产生接收数据可用的中断,并在使能硬件流控制时自动无效 RTS 引脚,01 对应 16
个字节,10 对应 64 个字节,11 对应 112 个字节((FIFO128字节)
(3)CH9434M:RECVTG1 和 RECVTG0:设置接收 FIFO 的中断和硬件流控制的触发点,00 对应 256 个字节,即
接收满 256 个字节产生接收数据可用的中断,并在使能硬件流控制时自动无效 RTS 引脚,
01 对应 512 个字节,10 对应 1024 个字节,11 对应 1280 个字节。
当接收数据达到触发值时,就会触发recv_rdy(接收字节数达到fifo触发点)中断。
5. 对于CH43x芯片读取的问题
解答:有些新上手的工程师,在使用fifo接收的时候,会发现随着波特率的提高,当触发RECV_RDY中断的时候,去读取RBR寄存器(注1)的数据。最后读出来的数据长度会超过FIFO接收触发的长度。这个是因为目前43xEVT的代码里面,是一个do--while循环,判断的条件是看BIT_LSR_DATARDY,也就是LSR的DATARDY位是否为1(注2),为1则表示fifo里面有数据,那么如果通讯接口的速度与较慢,串口的波特率较高,并且对方串口的发送速度也较快,那么就会出现,触发fifo_recv_rdy中断后,主控芯片通过接口去读取缓冲区的数据,但如果在读取的时候来了新的数据,那么就会继续停留在这个do-while循环语句当中。最后导致的情况就是读出的数据长度明显大于fifo触发的长度,如果fifo触发值设置的较大,那么很有可能会出现fifo溢出的问题。
u8 CH432Seril1Rcv( u8 *buf ) /* 禁用FIFO,CH432串口1接收多字节子程序*/
{
u8 RcvNum = 0;
if( !( ReadCH432Data( CH432_LSR1_PORT ) & ( BIT_LSR_BREAKINT | BIT_LSR_FRAMEERR | BIT_LSR_PARERR | BIT_LSR_OVERR ) ) ) /* b1-b4无错误 */
{
while( ( ReadCH432Data( CH432_LSR1_PORT ) & BIT_LSR_DATARDY ) == 0 ); /* 等待数据准备好 */
do
{
*buf++ = ReadCH432Data( CH432_RBR1_PORT ); /* 从接收缓冲寄存器读出数据 */
RcvNum++;
}
while( ( ReadCH432Data( CH432_LSR1_PORT ) & BIT_LSR_DATARDY ) == 0x01 );
}
else ReadCH432Data( CH432_RBR1_PORT );
return( RcvNum );
}
解决办法就是在这个接收函数里面,如果是fifo触发的中断,则强制只读一个触发值长度的数据,如果是超时中断则调用原来的dowhile的那个方式。其次,若选择的是CH432这样的fifo较小的串口扩展芯片,那么fifo触发值最好选择一半。还有就是提高spi接口的通信的速率。
6. 有关串口波特率的问题
解答:串口波特率的计算和DLM以及DLL两个寄存器有关。具体的计算公式:除数(DLL和DLM的值)=芯片主时钟/16or8(具体看芯片手册)/波特率。
注1:RBR:接收缓冲寄存器,如果 LSR 的 DATARDY 位为 1 则可以从该寄存器读取接收到的数据。如果 FIFOEN
为 1 则从串口移位寄存器 RSR 接收到的数据首先被存放于接收 FIFO 中,然后通过该寄存器读出
注2:DATARDY:该位为 1 表示接收 FIFO 中有接收到的数据,读取 FIFO 中所有数据后,该位自动清 0。
驱动代码工程
可以去个人Gitee,里面有STM32F103单片机控制CH423/CH438的驱动代码。
个人Gitee:https://gitee.com/maji19971221/wch_-per/tree/master/WCH_Per/STM32F103
CH9434的驱动代码可以去WCH官网,官方留的就是stm32驱动的。