基于ADSP2106x系列DSP的各种应用系统,常常需要与PC机进行异步串行通信。尽管ADSP2106x有两个串行接口,然而,其串口为同步串口,不能直接与外设进行异步串行通信。若要与PC机进行串行数据传输,就要求对ADSP2106x进行一定的软﹑硬件扩展,以使ADSP2106x具有UART接口能力。在DSP应用系统中扩展异步串行接口,可利用ADSP2106x本来已有的同步串口与DMA,用软件方法实现异步数据传输格式。但是这种方法往往会使本来已经较复杂的应用系统处理软件更加复杂。故在很多场合下常采用在DSP的并行总线上扩展异步串行接口的方法。本文采用在ADSP2106x的并行总线上挂接ST16c2550异步串行收发器,来实现DSP应用系统的异步串行接口能力。这种方法的最大优点是软件实现简单。
1.ST16c2550通用异步收发器
ST16C2550是双通道的通用异步收发器。其主要特点是接收﹑发送各有16字节的FIFO(先入先出) 缓冲区,独立的波特率产生器可提供50bps到4Mbps的收发时钟。用户可方便地通过板上的状态寄存器来进行错误定位和对操作状态进行判断。除了字长(5,6,7,8)和奇偶校验均可编程外,ST16C2550还具有4个可选择的FIFO中断触发。关于ST16C2550的结构框图可以查看相应的Data Sheet。
对异步收发器进行操作需要对其控制寄存器进行编程控制,表1介绍了ST16c255的重要寄存器。
表1 ST16c2550内部寄存器
地址
寄存器
描述
0 0 0
RHR
接收保持寄存器,当LCR[7]=0时,读有效。
THR
发送保持寄存器,当LCR[7]=0时,写有效。
0 0 1
DLL
波特率产生器除法因子低8位,当LCR[7]=1时,读写有效。
DLM
波特率产生器除法因子高8位,当LCR[7]=1时,读写有效。
0 0 1
IER
中断使能寄存器,当LCR[7]=0时,读写有效。
0 1 0
ISR
中断状态寄存器,只读。
FCR
FIFO控制寄存器,只写。
0 1 1
LCR
线控寄存器,读写。
1 0 1
LSR
线状态寄存器,只读。
2.ADSP2106x与ST16c2550硬件接口电路设计
在ADSP2106x的并行总线上扩展UART。用到8根数据总线D23~D16,还有6根地址
总线A23~A21、 A2~A0, 此外还有I/O读写信号线RD﹑WR,外部中断输入线IRQ2。在下面的方法中仅以ST16c2250的通道A来说明其应用,采用最简单的三线制接法,即地,接收数据,发送数据三脚相连。图2给出了接口设计的原理框图。
图2中,ADSP2106x的D23~D16这8根数据线与ST16c2550的8-bit数据接口线连接,之所以在ADSP2106x的D47~D0这48根数据线中选择D23~D16这8根数据线,是因为这样才能与ADSP2106x内部32-bit寄存器在低端对准。在连接的6根地址线中,A23~A21这3根高端地址线用于译码产生异步串行收发器的片选信号/CSA,A2~A0这3根低端地址线与ST16c2550的A2~A0相连,用来选择ST16c2550的内部寄存器。读写控制线号/RD和/WR经门电路驱动后直接与ST16c2550的读写信号相连。ST16c2550的中断信号INTA经反相后与IRQ2相连,因为IRQ2是低电平有效。对于ST16c2550来说,外接1.8432MHz的晶振为可编程波特率发生器提供时钟源。此外,由于ST16c2550是TTL电平,而PC机的串口是RS232电平,为了能使计算机串口和ST16c2550相连,必须在两者电路之间进行电平和逻辑关系的转换。可用MAX232来实现电平转换。
从ADSP2106x角度来看,对PC机进行读操作和写操作过程如下:
1.写操作:使能ST16c2550的发送FIFO缓冲区,然后直接将数据写入THR,值得注意的是由于FIFO缓冲区仅有16字节,故ADSP2106x一次连续写不要超过16字节。
2.读操作:由于ADSP2106x速度很快,可采用单字节中断读的方法。当ST16c2550经过RxA收到数据时,在INTA上产生中断信号,通知DSP将数据取走。
1.DSP与PC的异步串行通信软件的设计
在异步串行通信软件的设计中,就ADSP2106x来说,其软件设计包括异步串行收发器
的初始化,接收数据的中断服务程序和发送数据程序。对PC机,本文采用Windows API编程实现控制串口。下面首先介绍ADSP2106x的编程。
1. ADSP21060对通用异步收发器ST16C2550的A通道进行初始化:
#include //reg_def.h中定义了ST16C2550的寄存器地址
…
uartinit: //串口初始化子程序
r0=0x03; //清空接收FIFOs,清空发送FIFOs
dm(fcr_a)=r0;
nop;nop;
r0=0x01; //FIFOs使能
dm(fcr_a)=r0;
nop;nop;
r0=0x80; //设置Line Control Register的最高位LCR[7]=1
dm(lcr_a)=r0; //当LCR[7]=1时,可设置波特率产生器的除法因子
nop;nop;
r0=0x0c; //本例中外部晶振频率为1.8432MHz
dm(dll_a)=r0; //通过设置DLL和DML,可设置波特率为9600bps
nop;nop;
r0=0x00;
dm(dml_a)=r0;
nop;nop;
r0=0x03; //字长为8,1位停止位,无奇偶校验
dm(lcr_a)=r0; //通过设置LCR[7]=0,禁止设置除法因子DLL和DML
nop;nop;
r0=0x08; //设置中断允许
dm(mcr_a)=r0;
nop;nop;
r0=0x01; //设置RHR中断允许
dm(ier_a)=r0;
nop;nop;
rts;
对通用异步收发器ST16C2550进行初始化之后,便可进行数据的发送与接收。发送时,由于ADSP21060速度快,而ST16C2550仅有16 bytes的FIFOs,故发送时不应一次发送太多数据。接收时可采用中断接收。
2.发送数据程序:
sendData:
b0=send_buffer; //取发送缓冲区地址,send_buffer为发送数据缓冲区
m0=1;
l0=0;
lcntr=0x10,do send_data_to_uart until lce;
r0=dm(i0,m0);
dm(thr_a)=r0;
send_data_to_uart:nop;
3. 接收数据程序:
receivedata:
bit set mode1 SRRFH|SRRFL; //使用备用寄存器堆
nop;
r0=dm(lsr_a); //读LSR(Line Status Register)
nop;nop; //以便清除相应的标志位
r0=dm(rhr_a); //读RHR,完成取数
nop;nop;
dm(i7,m7)=r0; //接收到的数据存入接收缓冲区
//b7假定指向接收缓冲区首址
rti(db); //由于是在中断中接收数据,切换到主寄存器
bit clr mode1 SRRFH|SRRFL; //后中断返回
nop;
而PC机对串口进行编程的方法多种多样,可采用MSComm控件进行串口编程和应用
Windos API编程控制串口。前者通过在工程Project中插入MSComm控件,然后对该控件进行控件编程来完成对串口的控制。后者则通过用Windows API来直接控制串口。本例中介绍用Windows API编程控制串口。在对串口操作中,可创建一个工作者线程来监控串口的接收,而对于发送来说则采用在主线程直接发送。下面简单地说说用Windows API编程来实现对串口的控制。
…
//打开串口
HANDLE m_hCom = CreateFile(“COM1”,GENERIC_READ|GENERIC_WRITE,0,NULL,
OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL|FILE_FLAG_OVERLAPPED,NULL);
//分配发送、接收缓冲区
SetupComm(m_hCom,MAXBLOCK,MAXBLOCK);
//让Windows进程监视通信中的事件
SetCommMask(m_hCom,EV_RXCHAR);
DCB dcb;
dcb.fBinary = TRUE;
dcb.BaudRate=9600;
…
SetCommState(m_hCom,&dcb); //配置串口
//创建工作者线程,负责监视串行口
CWinThread* m_pThread = AfxBeginThread(CommProc,this,THREAD_PRIORITY_NORMAL,
0,CREATE_SUSPENDED,NULL); …
4.结束语
由于数字信号处理器ADSP2106x上只有同步串行接口,而没有异步串行收发器(UART)接口。本文采用在DSP的并行总线上扩展UART来实现异步数据传输。这种方法的最大优点在于软件实现简单。因而对于软件较为复杂的应用系统来说,该方案是可行的。