首先介绍一下WK2132,这是一款串口拓展芯片,可以使用SPI,IIC或UART输入,最终拓展出2路UART,解决单片机自身UART不足的问题。
电路设计上也比较简单,可参考这个,本次使用的是UART输入方式。
接下来讲解软件控制步骤。
首先芯片需要先复位(低电平复位),然后发送数据0x55,芯片以此来判断当前输入主串口的通信速率以实现波特率自适应,顺便说一下,这个串口就是连接单片机的串口,如下所示:
接下来是子串口的初始化和波特率设置,需要通过主串口操作芯片寄存器实现。寄存器很多,就不列举了,直接粘出代码。
/*子串口初始化*/
void Wk_Init(u8 port)
{
u8 gena,grst,gier,sier,scr;
//使能子串口时钟
gena=WkReadGReg(WK2XXX_GENA);
gena=gena|(1<<(port-1));
WkWriteGReg(WK2XXX_GENA,gena);
//软件复位子串口
grst=WkReadGReg(WK2XXX_GRST);
grst=grst|(1<<(port-1));
WkWriteGReg(WK2XXX_GRST,grst);
//使能子串口总中断
gier=WkReadGReg(WK2XXX_GIER);
gier=gier|(1<<(port-1));
WkWriteGReg(WK2XXX_GIER,gier);
//使能子串口接收触点中断和超时中断
sier=WkReadSReg(port,WK2XXX_SIER);
sier |= WK2XXX_RFTRIG_IEN|WK2XXX_RXOUT_IEN;
WkWriteSReg(port,WK2XXX_SIER,sier);
//初始化FIFO和设置固定中断触点
WkWriteSReg(port,WK2XXX_FCR,0XFF);
//设置任意中断触点,如果下面的设置有效,那么上面FCR寄存器中断的固定中断触点将失效
WkWriteSReg(port,WK2XXX_SPAGE,1);//切换到page1
WkWriteSReg(port,WK2XXX_RFTL,0X40);//设置接收触点为64个字节
WkWriteSReg(port,WK2XXX_TFTL,0X10);//设置发送触点为16个字节
WkWriteSReg(port,WK2XXX_SPAGE,0);//切换到page0
//使能子串口的发送和接收使能
scr=WkReadSReg(port,WK2XXX_SCR);
scr|=WK2XXX_TXEN|WK2XXX_RXEN;
WkWriteSReg(port,WK2XXX_SCR,scr);
}
/*
波特率计算,以115200为例,使用12MHz晶振
reg=12M/(115200*16)=6.51
baud为整数减一,pres为小数乘以16取整
baud1=(6-1)>>8;
baud0=(6-1)>>0;
pres=int(0.51*16);
*/
void Wk_SetBaud(uint8_t port,enum WKBaud baud)
{
unsigned char baud1,baud0,pres,scr;
//如下波特率相应的寄存器值,是在外部时钟为12mhz的情况下计算所得,如果使用其他晶振,需要重新计算
switch (baud)
{
case B9600:
baud1=0x00;
baud0=0x4d;
pres=0x02;
break;
case B115200:
baud1=0x00;
baud0=0x05;
pres=0x08;
break;
default:
baud1=0x00;
baud0=0x00;
pres=0;
}
//关掉子串口收发使能
scr=WkReadSReg(port,WK2XXX_SCR);
WkWriteSReg(port,WK2XXX_SCR,0);
//设置波特率相关寄存器
WkWriteSReg(port,WK2XXX_SPAGE,1);//切换到page1
WkWriteSReg(port,WK2XXX_BAUD1,baud1);
WkWriteSReg(port,WK2XXX_BAUD0,baud0);
WkWriteSReg(port,WK2XXX_PRES,pres);
WkWriteSReg(port,WK2XXX_SPAGE,0);//切换到page0
//使能子串口收发使能
WkWriteSReg(port,WK2XXX_SCR,scr);
}
到这里基本上初始化就结束了,但是因为本身芯片支持中断触发,所以如果要使用中断功能的话,还得再配置一下中断,值得说明一下的是该芯片中断使用的低电平触发,而STM32的中断是边沿触发,所以可能会有漏判断的时刻,需要注意。
接下来就是数据收发了,主串口的收发很好理解,就是单片机串口的常规收发处理。
子串口的发送也比较简单,还是通过主串口去写寄存器或写FIFO,同样的也有字节数的限制,请查看手册。
子串口的接收要麻烦点,首先是检测中断触发后去读中断寄存器,判断是哪个子串口发生的中断,然后可以将数据放入对应的缓存中接收备用,最后可以在主循环中对接收缓存做解析处理。
以下为子串口发送与接收参考代码
void wk_TxChars(u8 port,int len,u8 *sendbuf)
{
#if 1
int slen;
while(len)//发送len长度的数据。
{
slen=len>=16?16:len;
len=len-slen;
WkWriteSFifo(port,sendbuf,slen);//通过fifo方式发送数据
sendbuf=sendbuf+slen;
}
#else
int num=len;
for(num=0;num=rfcnt))
{
rfcnt=rfcnt2;
}
len=(rfcnt==0)?256:rfcnt;
}
num=len;
/*读取接收fifo中的数据*/
#if 1
while(len)
{
if(len>=16)
{
WkReadSFifo(port,recbuf,16);
recbuf=recbuf+16;
len=len-16;
}
else
{
WkReadSFifo(port,recbuf,len);
len=0;
}
}
#else
for(n=0;n
附上基于STM32的参考例程
https://download.csdn.net/download/u011436603/88801223