完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
在中断发送方式中,若主程序要发送一个数据块,它首发送一组数据(≤8个),然后使能ENTX,让数据自动从FIFO中发出去,这时主程序就结束了,CPU可以转去处理其他事情,而不必等待漫长的2.88ms的发送过程。当FIFO中数据发送完毕时,它会引发一个硬件中断,CPU收到该中断后在相应的中断服务程序中发送剩余的数据。显然,这种方式下CPU的利用率较高。由于主程序仅发送一组数据,过程非常简单,可参考查询方式的发送过程,在此不再赘述。笔者仅给出中断服务程序的函数框架:
Void interrupt NewISR(void) {disable();//关中断 intIntStatus=read_IntStatusReg();//读取中断状态寄存器 intIntMask=read_IntMaskReg();//读取中断屏蔽寄存器 if((IntStatus&0x01)&&(IntMask&0x01))sendover();//发送完毕中断分支 if((IntStatus&0x02)&&(IntMask&0x02))not_ empty();//接收FIFO非空分支 if((IntStatus&0x04)&&(IntMask&0x04))thresh old();//接收FIFO超过阈值 EndOfInt(IRQNum);//中断结束 enable();//打开中断 } voidsendover() {disable_ENTX(); if(counter {for(inti=1;i<=8;i++)//8个数据为一组 {write_long(send_data[counter++]);//send_data为发送缓冲区 if(counter>=total)break;//counter为已发送的数据个数 } enable_ENTX();} } |
|
|
|
数据接收
数据的接收也可有查询接收和中断接收两种方式。在查询接收中,主程序每读取一个数据都要查询接收FIFO的状态,只有FIFO非空时才能读取数据。这种方式虽然简单,但是效率较低。查询接收的函数框架如下: Unsigned long Poll_Recv_Msg(unsigned long*Recv_Data_Buff) {int i;intempty=read_fifo_empty();//读取FIFO的空标志 while(empty!=1)//若FIFO非空,则不断读取数据 {*(Recv_Data_Buff++)=read_long();//将数据放入接收缓冲区 empty=read_fifo_empty();//再次查询FIFO状态 i++;//数据计数 } returni;//返回接收的数据个数 } 在中断接收方式中,主程序无需查询FIFO的状态,而是当接收FIFO非空或者超过设定的阈值时引发中断要求CPU来取数,接收数据在中断服务程序中执行。这样,CPU可以腾出大量的时间进行其他操作,而不被查询过程独占。在中断服务程序中维持一个循环队列,每次进入中断,接收的数据进入对列。主程序需要时可直接从队列中取数。对于FIFO非空产生的中断,进入中断服务程序后只要取一个数据即可,而对于FIFO超过阈值产生的中断,中断服务程序可取多个数据,直到产生中断的条件不成立为止。笔者只给出超过阈值的中断服务程序和主程序范例,前者可依次类推。 voidthreshold() {while(cnt)//cnt=阈值/2 {if(queue_threshold.front!=(queue_threshold.rear+1)%QueueSize)//队列不满 {queue_threshold.rear=(queue_threshold.rear+1)%QueueSize;//改变队尾指针 queue_threshold.data[queue_threshold.rear]=read_long();//进队 cnt--; } } } unsignedlongInt_Recv_Msg_threshold(unsignedlong*Recv_Data_Buff) {inti=0; while(queue_threshold.front!=queue_threshold. rear)//队列不空 {queue_threshold.front=(queue_threshold.front+1)%QueueSize;//改变队头指针 *(Recv_Data_Buff++)=queue_threshold.data [queue_threshold.front];//出队 i++;//读取数据个数 } returni; } |
|
|
|
有关中断问题的讨论
(1)在有些接口设计中,接收数据时只要判断DR1或DR2信号有效即触发硬件中断,要求CPU来取数。由于数据的接收具有惯性,即当接收到一个数据时很有可能后面紧跟着很多数据,若使用该方法,则会不停的进出中断,且进入中断之后只取一个数。而进出入中断的过程要进栈(保护现场)和出栈(恢复现场),其开销和进入中断服务程序之后仅取一个数据的时间相比有些“得不偿失”。本设计中,DR1或DR2信号的有效会触发接收逻辑,它自动把数据放入接收FIFO中,只有当FIFO中数据个数达到一定值时才通知CPU处理,因此,该方法可减少对主程序的干预,明显地提高了效率。 (2)中断接收数据时,虽然本设计支持FIFO非空和超过阈值两种中断方式,但实际应用中,前者的效率低下,笔者建议使用后者。在该设计中,中断的引发条件是FIFO超过阈值而不是FIFO满,这是因为若FIFO满时才产生中断,则在中断处理过程中新接收的数据可能会丢失。当然,FIFO的阈值要做适当选择。若阈值太小,则会经常进中断,效率太低;若太大,则会丢失数据。建议将阈值设置成半满或为FIFO深度的60%。 (3)由于PC/104系统的中断不像PCI中那样由系统统一分配,而是由用户根据系统资源使用状态自己设定,为此必须将中断设计成跳线开关形式,使其具有一定的灵活性。 结束语 采用FPGA技术结合高性能的HS-3282/HS-3182芯片组设计并实现了基于PC/104的ARINC429接口模块,该模块支持多种工作方式,使用器件少,可靠性高。软件上采用简捷方便的C语言实现了中断、查询方式的数据收发功能。目前,整套ARINC429模块已成功应用在某直升机中。使用情况表明,该接口模块性能稳定、实用性好。 来源:电子设计信息网 |
|
|
|
只有小组成员才能发言,加入小组>>
2906 浏览 3 评论
27712 浏览 2 评论
3484 浏览 2 评论
3990 浏览 4 评论
基于采用FPGA控制MV-D1024E系列相机的图像采集系统设计
2338 浏览 3 评论
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2024-12-27 19:57 , Processed in 0.682717 second(s), Total 80, Slave 61 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191 工商网监 湘ICP备2023018690号