完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
很多单片机,比如51单片机,只有一个或两个串口。所以,有时会遇到串口不够用的情况,这时候可以换一款串口更多的单片机。而有时你又不想换一款单片机,那可以使用本文要介绍的通过IIC来扩展串口的芯片。
成都为开微电子,在串口扩展芯片上有很多选择,有2个串口、4个串口等。本文以2串口的WK2132为例进行介绍。二话不说,先上简介。 WK串口芯片的特色,在于每个串口有256级FIFO,这可以节省你的单片机的RAM,同时,不容易因为没读取WK接收缓冲里的数据而使缓冲区溢出。 在我的串口扩展模块中,使用IIC来操作WK,它的好处是有应答信号,可以知道WK芯片是否正常工作。上威廉希尔官方网站 图 SCL、SDA接到单片机就可以了,IRQ是中断信号,可不接,单片机采用查询方式来检测是否有接收到数据。R7~R10用来选择IIC地址,这样可以用同一个IIC线最多接4个扩展模块,8个串口。 我的模块中,还可以选择TTL输出还是232输出。 现在来上代码 main() { //P1.6為IIC SDA引腳,配置成開漏,輸出高電平 //P1.7為IIC SCL引腳,配置成開漏,輸出高電平 P1M0 |= (1<<6) | (1<<7); P1M1 |= (1<<6) | (1<<7); P1 |= (1<<6) | (1<<7); WK21xx_Init(); while(1) { //测试自收自发 WK21xx_UARTxRcv(0, a, &RcvNum); if (RcvNum) { WK21xx_UARTxSend(0, a, RcvNum); } WK21xx_UARTxRcv(1, a, &RcvNum); if (RcvNum) { WK21xx_UARTxSend(1, a, RcvNum); } } } 先配置一下I2C的IO口,然后调用一下WK21xx_Init(),接下来就可以用WK21xx_UARTxRcv读取接收缓存里的数据,以及用WK21xx_UARTxSendByte和WK21xx_UARTxSend发送数据了。 WK的驱动如下 /********************************************************************************************************* ** Func: WK21xx串口初始化 ** Input: UARTx: 串口号, 0~15 ** Return: 成功返回1,失败返回0 ** Remarks: WK21xx串口初始化 *********************************************************************************************************/ unsigned char WK21xx_UARTxInit(unsigned char UARTx, unsigned long Baud) { unsigned long BaudReg = WK21xx_CLK / 16 * 100 / Baud; unsigned short BaudReg_IntPart = BaudReg / 100 - 1; unsigned short BaudRegB = BaudReg % 100 << 4; unsigned char BaudReg_DecPart = BaudRegB / 100; if (BaudRegB%100 >= 50) { BaudReg_DecPart += 1; } if (!WK21xx_WriteSubReg(UARTx, REG_SPAGE_ADDR, 1)) return 0; //选择寄存器页 if (!WK21xx_WriteSubReg(UARTx, REG_BAUD1_ADDR, BaudReg_IntPart>>8)) return 0; //设置波特率 if (!WK21xx_WriteSubReg(UARTx, REG_BAUD0_ADDR, BaudReg_IntPart)) return 0; //设置波特率 if (!WK21xx_WriteSubReg(UARTx, REG_PRES_ADDR, BaudReg_DecPart)) return 0; //设置波特率 if (!WK21xx_WriteSubReg(UARTx, REG_SPAGE_ADDR, 0)) return 0; //选择寄存器页 if (!WK21xx_WriteSubReg(UARTx, REG_SCR_ADDR, 0x03)) return 0; //使能串口发送和接收 if (!WK21xx_WriteSubReg(UARTx, REG_LCR_ADDR, (0 << 3) //0 No parity; 1 Enable parity | (0 << 1) //0 Force 0 parity; 1 Odd parity; 2 Even parity; 3 Force 1 parity | 0)) return 0; //0 1 stop bit; 1 2 stop bit if (!WK21xx_WriteSubReg(UARTx, REG_FCR_ADDR, 0x0f)) return 0; //使能并重置FIFO if (!WK21xx_WriteSubReg(UARTx, REG_SIER_ADDR, 0)) return 0; //禁止所有子串口中断 return 1; } /********************************************************************************************************* ** Func: WK21xx初始化 ** Input: 无 ** Return: 成功返回1,失败返回0 ** Remarks: WK21xx初始化 *********************************************************************************************************/ unsigned char WK21xx_Init(void) { I2C_PinInit(); //全局初始化 if (!WK21xx_WriteGlobalReg(0, REG_GENA_ADDR, 0x03)) return 0; //使能子串口时钟 if (!WK21xx_WriteGlobalReg(0, REG_GMUT_ADDR, (0 << 3) //0 No parity; 1 Enable parity | (0 << 1) //0 Force 0 parity; 1 Odd parity; 2 Even parity; 3 Force 1 parity | 0)) return 0; //0 1 stop bit; 1 2 stop bit if (!WK21xx_WriteGlobalReg(0, REG_GIER_ADDR, 0)) return 0; //禁止全局串口中断 //子串口初始化 if (!WK21xx_UARTxInit(0, WK21xx_UART0_BAUD)) return 0; if (!WK21xx_UARTxInit(1, WK21xx_UART1_BAUD)) return 0; return 1; } /********************************************************************************************************* ** Func: WK21xx UARTx发送一个字节 ** Input: UARTx: 串口号, 0~15 ** Input: Data: 要发送的字节 ** Output: 无 ** Return: 成功返回1,失败返回0 ** Remarks: 同步模式,发送完毕函数才返回 *********************************************************************************************************/ unsigned char WK21xx_UARTxSendByte(unsigned char UARTx, unsigned char Data) { unsigned char FsrReg; if (!WK21xx_WriteFIFO(UARTx, &Data, 1)) return 0; while (1) { if (!WK21xx_ReadSubReg(UARTx, REG_FSR_ADDR, &FsrReg)) { return 0; } if ((FsrReg & 0x05) == 0) { return 1; } } } /********************************************************************************************************* ** Func: WK21xx UARTx发送数据 ** Input: UARTx: 串口号, 0~15 ** Input: pData: 要发送的数据 ** Input: Num: 要发送的字节数 ** Output: None ** Return: 成功返回1,失败返回0 ** Remarks: 同步模式,发送完毕函数才返回 *********************************************************************************************************/ unsigned char WK21xx_UARTxSend(unsigned char UARTx, unsigned char *pData, unsigned char Num) { unsigned char FsrReg; if (!WK21xx_WriteFIFO(UARTx, pData, Num)) return 0; while (1) { if (!WK21xx_ReadSubReg(UARTx, REG_FSR_ADDR, &FsrReg)) { return 0; } if ((FsrReg & 0x05) == 0) { return 1; } } } /********************************************************************************************************* ** Func: WK21xx UARTx读取数据 ** Input: UARTx: 串口号, 0~15 ** Output: pData: 存放读取到的数据的指针 ** Output: pRcvNum: 读取到的字节数 ** Return: 成功返回1,失败返回0 ** Remarks: 数据最多256个 *********************************************************************************************************/ unsigned char WK21xx_UARTxRcv(unsigned char UARTx, unsigned char *pData, unsigned char *pRcvNum) { unsigned char RcvNum; if (!WK21xx_ReadSubReg(UARTx, REG_RFCNT_ADDR, &RcvNum)) { *pRcvNum = 0; return 0; } if (RcvNum == 0) { *pRcvNum = 0; return 1; } if (!WK21xx_ReadFIFO(UARTx, pData, RcvNum)) { *pRcvNum = 0; return 0; } *pRcvNum = RcvNum; return 1; } |
|
|
|
只有小组成员才能发言,加入小组>>
3329 浏览 9 评论
3007 浏览 16 评论
3503 浏览 1 评论
9085 浏览 16 评论
4099 浏览 18 评论
1209浏览 3评论
620浏览 2评论
const uint16_t Tab[10]={0}; const uint16_t *p; p = Tab;//报错是怎么回事?
607浏览 2评论
用NUC131单片机UART3作为打印口,但printf没有输出东西是什么原因?
2349浏览 2评论
NUC980DK61YC启动随机性出现Err-DDR是为什么?
1913浏览 2评论
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2025-1-4 07:20 , Processed in 1.134136 second(s), Total 79, Slave 60 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (威廉希尔官方网站 图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191 工商网监 湘ICP备2023018690号