基于 EPM7128 设计的数据合并转换器_EDAPLD论文
关键词:cpld 数据合并转换器 串行口 pcm流
数据交换机的传送速率很高,当其和串行口通信时,在发送前把数据分为两部分分别发送到串行口,然后经过数据合并转换器把各个串行口的数据合并在一起并转换成pcm流。本文介绍了基于cpld芯片epm7128设计的数据合并转换器。
1 数据合并转换器硬件电路
epm7128是可编程的大规模逻辑器件,为altera公司的max7000系列产品,具有高阻抗、电可擦等特点,可用门单元为2500个,管脚间最大延迟为5ns,工作电压为+5v。
idt7205为fifo型异步读写的存储器芯片,容量为8192×9比特,存取时间为12ns,有空、半满、满三个标志位,最大功耗为660mw,工作电压为+5v。
msm4860dx属于pc104嵌入式系统的5x86系旬,为amd-133mhz cpu,具有com1、com2两个串口,一个lpt并口,一个eloppy接口,一个ide接口,一个vga/lcd接口,一个at-keyboard接口,16个中断,额定功率为8w,工作电压为+5v。
1.2 数据合并转换器电路框图
可编程的数据合并转换器电路框图如图1所示。图中,db为数据总线,ab为地址总线,r和w分别为读写信号线,int5、int7、int10 int11为四个中断,cs1、cs2和cs3是在cpld内部生成的地址译码器addr-encoder分别送给分频器、两个串行口的片选信号,org是晶振送给分频器的振荡脉冲,clk是分频器输出的脉冲frameclk和pcmclk,wfifo、rfifo是由cpld生成的包含地址的访问fifo的读写脉冲,data_in1和data_in2为串行口输入数据,pcm_data是数据合并转换器输出的pcm流,pcmclka为输出的码同步时钟,worldclka为输出的字同步时钟。
1.3 电路工作分析
晶振把时钟脉冲送给分频器,分频器含有两个可编程的定时器。分频器把可控的frameclk和pcmclk送给cpld,在cpld内部经过逻辑组合形成三路脉冲信号,一路控制计数器形成int5、int7两个帧频中断触发脉冲,cpu接到中断后立即写fifo;另一路控制移位寄存器把并行数据转换成串行数据pcm流;第三路形成rfifo去连续读fifo。两个串行口通过中断方式(int10、int11)接收到外部数据后,暂存缓冲区内,按一定格式由中断int5控制写给fifo。
2 cpld内部逻辑电路
cpld内部逻辑电路如图2所示。图中,虚线框内为cpld内部电路,虚线框外为cpld的i/o口。
2.1 地址译码器
地址译码器addr-encoder用vhdl语言生成。addr-encoder的输出有总线驱动器芯片74245的使能脉冲enb,总线传输方向的使能脉冲dir,写fifo操作脉冲wfifo,分频器和串行口的片选cs1、cs2和cs3,fifo数据空满标志脉冲rfifoflag,fifo复位时钟脉冲wctrl。
2.2 数据移位部分
frameclk周期是pcmclk的8位,它们都是分频送来的脉冲。frameclk反相后作为fifo的读信号,两次反相后作为字同步时钟。pcmclk直接作为移位寄存器74165的时钟触发脉冲,两者与非后的输出低电平作为74165重数据的触发电平。它们的信号时序如图3所示。
从三者的时序图可知,每当一个字节的最后一位完成移位后,在frameclk脉冲反相的下降沿触发下读取fifo数据,这时74165的装载使能74165std恰好为低电平(与非结果),完成部数据装载,然后在pcmclk脉冲的上升沿作用下开始新一软次的数据移位。
2.3 帧长计数器的部分
两个74161设计长1/64的分频器,也叫帧长计数器,此计数器的时钟为frameclk,计数器的输出最高两位逻辑与为中断int7,把与门输出与次高位逻辑异或为中断int5。这样,int7比int5在时序上早半个周期。开始复位后,int7脉冲首先产生,触发中断,cou中断后在服务程序中把64个字节数据写到fifo,然后屏蔽中断int7,半个周期后,fifo中还剩32个字节数据(因此fifo的读脉冲和frameclk反相同频)。然后中断int5到来,cpu响应后,再写64个字节数据给fifo,使fifo中一直保持有数据的状态(可避免读fifo正好落在两个写fifo之间,fifo因无数据而读死)。这样,每当中断int5到来,都写64字节给fifo,周而复始,所以把64字节定为帧长。
设pcmclk的频率为f(mhz),则frameclk的频率为f/8,由于帧长为64,所以有:帧频=f/(8×64),pcm流速率=f(bit/s)。分频器的分频比是通过软件设定的,所以pcm流的速率可编程。
3 软件设计
outp(0x303,0x36);//方式3,方波。//
outp(0x300,0x50);//timer0,分频比为80。//
outp(0x300,0x00);
outp(0x303,0x74);//方式2,脉冲。//
outp(0x301,0x08);//timer1,分频比为8。//
outp(0x301,0x00);
数据合并:
if((com1_count%24)= =0) ;//串行口1的24字节数据放在数组frame的4~27的位置。//
{
com_buf1[com1_count++]=db1; //串行口1接收数据//
int original_counter;
original_counter=com1_count/24;
memcpy(frame[original_counter-1]+4,&com_buf1[com1_count-24],24);
}
if((com2_count%24)= =0); //串行口2的24字节数据放在数组frame的28~51的位置。//
{
com_buf2[com2_count++]=db2 ;//串行口2接收数据//
int original_counter;
original_counter=com2_count/24;
memcpy(frame[original_counter-1]+28,&com_buf2[com2_count-24],24) ;//合并后的数据放在frame数组中。//
写fifo:
void send_to_fifo(int number); //send_to_fifo函数为中断服务程序的一部分。//
{
for(int i=0;i<64;i++)
outp(wfifo,frame[number][i]); //数组送给fifo,实现数据合并//