串口扩展芯片vk3214应用实例解析

接口/总线/驱动

1119人已加入

描述

          产品概述

         VK3214是UARTTM接口的4通道UART器件。VK3214实现UART桥接/扩展4个串口(UART)的功能。扩展的子通道的UART具备如下功能特点:每个子通道UART的波特率、字长、校验格式可以独立设置,最高可以提供1Mbps的通信速率。每个子通道可以独立设置工作在IrDA红外通信。VK3214采用SOP20绿色环保的无铅封装,可以工作在2.5~5.5V的宽工作电压范围,具备可配置自动休眠/唤醒功能。

  应用领域

  车载信息平台/车载GPS定位系统

  远传自动抄表(AMR)系统

  POS/税控POS/金融机具

  串口扩展芯片vk3214应用

  1、VK32XX系列UART产品在税控POS中的应用

  VK32系列产品在嵌入式税控POS平台设计中的应用

  税控POS机是一个控制密集形的嵌入式系统,需要控制大量外设。其基本配置要求的串口打印机,MODEM,RS-485网络接口,以及税控IC卡(异步卡)都工作在基于UART的串行通信方式。同时,大量的外设如密码键盘,条码扫描器,条码称,接触IC卡/非接触IC卡读卡器,磁卡读卡器,串口显示屏等设备都是通过RS-232串口与POS机相连。

  采用VK32XX系列UART器件,可以根据MCU/CPU的接口特性,选择SPI/8位并行总线/UART进行灵活的UART串口扩展。该方案与采用目前GPIO来模拟串口的方案相比,占用CPU的I/O和资源都很少,即使普通的8位MCU也可以胜任。同时,扩展的子串口都是标准的硬件UART,使得数据传输也更加可靠。

扩展芯片

  2、 VK32XX系列UART器件在远程自动抄表系统中的应用

  如图所示,远传自动抄表系统由远传表和集中抄表器以及MODEM等部分组成。在远传表中,应用VK3212双串口扩展IC将单片机的一个UART扩展成两个UART,扩展出来的两个串口UART1和UART2分别接RS-485/M-BUS接口和红外接口。VK3212的UART1设置为RS-485自动收发和RS-485网络模式,可以无需MCU的控制,自动完成RS-485/M-BUS的数据自动收发和自动网络地址识别。VK3212的UART2设置为红外模式,用于连接远传表的红外设置窗口。

  在集中抄表器中,用一片SPI接口的4通道UART器件VK3234将扩展出4个子串口UART,MCU通过SPI总线与VK3234相连。VK3234的子串口UART设置为RS-485自动收发模式,每个子通道UART控制的RS-485/MBUS收发器通过RS-485/M-BUS总线连接最多250个远传表。一个基于VK3234的集中抄表器可以实现最多1000个远传表的数据读取。

  由于是通过SPI接口扩展的串口,集中抄表器单片机自身的串口可以连接PSTN/GSM MODEM将集抄数据传给远程服务器。

扩展芯片

  3 VK3224 SPI接口系列UART器件在嵌入式车载信息平台中的应用

  VK3233主接口有SPI和UART两种接口可以选择。嵌入式平台中的DSP/CPU通过SPI/UART接口与VK3233相连,VK3233扩展出来的三个子串口分别连接GPS模块,倒车雷达模块和GSM/ CDMA模块。MODEM控制线连接GSM/CDMA MOMEM。整个嵌入式系统共用一个显示设备,有效的节省了车内有限的空间。

扩展芯片

     最近一个项目需要用到3个串口,但是用的MCU只有2个串口,选择多串口的单片机成本太高,最后打算用串口扩展芯片VK3214扩展2个串口。

  VK3214可以用单片机的一个串口扩展出4个子串口,每个子串口都可以单独设置波特率。

  脚位图如下:

  扩展芯片

  MRX,MTX分别接单片机一个串口的TX,RX。RXn,TXn 为扩展的4个子串口。

  每个子串口有16字节的发送FIFO,16字节的接收FIFO。当发送FIFO触发点中断使能时,发送FIFO中的数据小于设定的触发点时产生相应的中断。当接收FIFO触发点中断使能时,接收FIFO中的数据大于设定的触发点时产生相应的中断。

  中断脚IRQ低电平有效,注意不是下降沿有效。IRQ接单片机的中断脚,中断脚接单片机的外部中断脚INT,INT要设置为低电平有效。因为是低电平有效,在进入中断程序后,要禁止外部中断,中断处理完后再开外部中断。

  例如当接收FIFO中断使能,触发点设置为1,那么在接收FIFO中的数据大于1时,IRQ变低,产生中断,此时进入中断程序,在中断程序中要读完FIFO中的全部数据,接收FIFO的数据变为0时,IRQ才变为高。如果没读完FIFO退出中断,IRQ仍会为低,退出中断后,马上又进入中断程序,导致其它程序不能执行。

  初始化VK3214时,要初始化完后再使能单片机的外部中断,否则会因为IRQ一直为低,导致程序一直运行外部中断程序,其它程序无法运行。

  初始化程序如下:

  void Vk3214_Init(void){

  uchar i;

  FREEDOG;

  VK3214_RST=1;

  delay(10);

  VK3214_RST=0;

  delay(10);

  VK3214_RST=1;

  delay(10);

  write_reg(1,SCTLR,0x38); //串口1波特率设置为9600,使能串口1

  write_reg(2,SCTLR,0x38);//串口2ㄌ芈噬柚梦?600,使能串口1

  //write_reg(3,SCTLR,0x30);//禁止串口3

  //write_reg(4,SCTLR,0x30);//禁止串口4

  //write_reg(0,SCONR,0x00);

  //write_reg(1,SCONR,0x00);

  //write_reg(2,SCONR,0x00);

  //write_reg(3,SCONR,0x00);

  //write_reg(0,SFWCR,0x00);

  //write_reg(1,SFWCR,0x00);

  //write_reg(2,SFWCR,0x00);

  //write_reg(3,SFWCR,0x00);

  write_reg(1,SFOCR,0xcf);//接收FIFO触点控制1BYTE

  //i = read_reg(1, SFOCR);

  //SENDCOM1(&i,1);

  write_reg(2,SFOCR,0xcf);

  //write_reg(2,SFOCR,0xcc);

  write_reg(1,SIER,0x01);//使能接收FIFO触点中断,禁止发送FIFO触点中断

  write_reg(2,SIER,0x01);

  //write_reg(2,SIER,0x00);

  //write_reg(3,SIER,0x00);

  //write_reg(0,SIFR,0x00);

  //write_reg(1,SIFR,0x00);

  //write_reg(2,SIFR,0x00);

  //write_reg(3,SIFR,0x00);

  write_reg(1,GIR,0X30);//使能串口1, 2中断

  while(read_reg(1,SFSR))//读完串口1,2接收FIFO中的数据

  read_reg(1,SFDR);

  while(read_reg(2,SFSR))

  read_reg(2,SFDR);

  write_reg(1,GUCR,0X10);//主串口波特率设为38400

  AUXR=0x14;///S2使用独立波特率发生器,S2波特率不加倍BRTX12设为1

  BRT=0xf7;//0xee;//0xf7;//设置波特率38400

  delay(10);

  }

  为保证及时接收到扩展串口的数据,接收FIFO触发点中断设置为1,即接收到1个字节就产生中断,发送因为是单片机控制,不用设置触发点中断。

  void uart_sendByte(unsigned char dat)

  {

  S2BUF=dat;

  while(!(S2CON & 0x02)); //waite for data to transmit completely

  S2CON &= 0xFD;

  }

  //通过串口发送1个字节的数据,dat为发送的数据

  unsigned char uart_recByte(void)

  {

  unsigned char rec=0;

  while(!(S2CON & 0x01)); //waite to recieve data in SBUF0

  rec=S2BUF;

  S2CON &= 0xFE;

  return rec;

  }

  //接收一个字节的数据,函数返回读取到的数据

  unsigned char read_reg(unsigned char port,unsigned char reg)

  {

  uchar i;

  EX1 = 0; //此处关外部1中断,避免在读写寄存器时,串口芯片接收到数据引起外部中断,在外部中断调用相同的寄存器会导致死机

  uart_sendByte(((port-1)《《4)+reg);

  i = uart_recByte();

  EX1 = 1;

  return i;

  }

  //读取寄存器的值,port为子串口的路数,reg为寄存器的地址,返回值是寄存器的值

  void write_reg(unsigned char port,unsigned char reg,unsigned char dat)

  {

  EX1 = 0;

  uart_sendByte(0x80+((port-1)《《4)+reg);

  uart_sendByte(dat);

  EX1 = 1;

  }

  从上面的函数可以看出,单片机的串口控制VK3214的串口,读写都是先发送VK3214的寄存器地址,然后再读写数据,所以如果单片机的串口和扩展的子串口的波特率设置成一样,会导致子串口接收FIFO溢出,再考虑到用单片机的一个串口控制2-4个子串口,所以单片机的串口波特率一定要是子串口波特率的倍数,我现在扩展2个串口,子串口的波特率为9600,所以我把单片机串口的波特率设置为38400,是子串口的4倍。倍数要考虑好,太慢会导致接收FIFO溢出,太快会导致发送FIFO的数据还没发出去,有送进来新的数据,发送FIFO溢出。

  VK3214复位后根据外接的晶振,主,子串口都有默认的波特率,单片机上电后先把波特率设为和VK3214主串口波特率一样,初始化VK3214完成后,在改变VK3214的主串口波特率和单片机串口的波特率。见初始化程序的最后部分。

  接下来关键的部分是外部中断程序的处理。程序如下:

  void Int1Init(void) interrupt 2

  {

  uchar x,i,j,z;

  EX1 = 0;

  uart_sendByte(GIR);

  i=uart_recByte();

  FREEDOG;

  if(i&0x01)

  {

  uart_sendByte((0《《4)+SSR);

  z=uart_recByte();

  z&=0x01;

  while(z==0)

  {

  uart_sendByte((0《《4)+SFDR);

  com2rev[com2revidx++] = uart_recByte();

  FREEDOG;

  if(com2revidx》=COM2_MAX)com2revidx=0;

  uart_sendByte((0《《4)+SSR);

  z=uart_recByte();

  z&=0x01;

  }

  }

  if(i&0x02)

  {

  uart_sendByte((1《《4)+SSR);

  z=uart_recByte();

  z&=0x01;

  while(z==0)

  {

  uart_sendByte((1《《4)+SFDR);

  com3rev[com3revidx++] = uart_recByte();

  FREEDOG;

  if(com3revidx》=COM3_MAX)com3revidx=0;

  uart_sendByte((1《《4)+SSR);

  z=uart_recByte();

  z&=0x01;

  }

  }

  EX1 = 1;

  }

  进入中断后先判断是哪个子串口产生的中断,如果是子串口1产生的接收中断,那么读子串口1的寄存器SSR,看接收FIFO是否为空,不为空就一直读子串口1的接收FIFO,直到FIFO为空。中断程序中一定要把接收FIFO的数据读完,因为我设置的接收FIFO触发点数据为1。如果不读完退出中断,IRQ仍然会为低,还会继续进入中断程序。读完后,IRQ才变为高。

打开APP阅读更多精彩内容
声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉

全部0条评论

快来发表一下你的评论吧 !

×
20
完善资料,
赚取积分