教育资源为主的文档平台

当前位置: 查字典文档网> 所有文档分类> 论文> 其他论文> C语言实现串行通信接口程序

C语言实现串行通信接口程序

上传者:网友
|
翻新时间:2023-02-22

C语言实现串行通信接口程序

C语言实现串行通信接口程序 C语言实现串行通信接口程序 C语言实现串行通信接口程序 摘 要 本文说明了异步串行通信(RS-2

3

2)的工作方式,探讨了查询和中断两种软件接口利弊,并给出两种方式的C语言源程序。

的I/O通道之一,以最简单方式组成的串行双工线路只需两条信号线和一条公共地线,因此串行通信既有线路简单的优点同时也有它的缺点,即通信速率无法同并行通信相比,实际上EIA RS-232C在标准条件下的最大通信速率仅为20Kb/S。

尽管如此,大多数外设都提供了串行口接口,尤其在工业现场RS-232C的应用更为常见。IBM PC及兼容机系列都有RS-232的适配器,操作系统也提供了编程接口,系统接口分为DOS功能调用和BIOS功能调用两种:DOS INT 21H的03h和04h号功能调用为异步串行通信的接收和发送功能;而BIOS INT 14H有4组功能调用为串行通信服务,但DOS和BIOS功能调用都需握手信号,需数根信号线连接或彼此间互相短接,最为不便的是两者均为查询方式,不提供中断功能,难以实现高效率的通信程序,为此本文采用直接访问串行口硬件端口地址的方式,用C语言编写了串行通信查询和中断两种方式的接口程序。

1.串行口工作原理@@T8S12300.GIF;图1@@

串行通信的工作相当复杂,一般采用专用芯片来协调处理串行数据的发送接收,称为通用异步发送/接收器(UART),以节省CPU的时间,提高程序运行效率,IBM PC系列采用8250 UART来处理串行通信。COM1(COM

2) 寄存器

端口地址 功能 DLAB状态

3F8H(2F8H) 发送寄存器(写) 0

3F8H(2F8H) 接收寄存器(读) 0

3F8H(2F8H) 波特率因子低字节 1

3F9H(2F9H) 波特率因子高字节 1

3F9H(2F9H) 中断允许寄存器 0

3FAH(2FAH) 中断标志寄存器

3FBH(2FBH) 线路控制寄存器

3FCH(2FCH) MODEM控制寄存器

3FDH(2FDH) 线路状态寄存器

3FEH(2FEH) MODEM状态寄存器UART可向CPU发出一个硬件中断申请,此中断信号接到中断控制器8259,其中COM1接IRQ4(中断OCH),COM2接IRQ3(中断OBH)。用软件访问8259的中断允许寄存器(地址21H)来设置或屏蔽串行口的中断,需特别指出的是,设置中断方式串行通信时,MODEM控制寄存器的第三位必须置1,此时CPU才能响应UART中断允许寄存器许可的任何通信中断。

2.编程原理

程序1为查询通信方式接口程序,为一典型的数据采集例程。其中bioscom()函数初始化COM1(此函数实际调用BIOS INT 14H中断0号功能)。这样在程序中就避免了具体设置波特率因子等繁琐工作,只需直接访问发送/接收寄存器(3F8H)和线路状态寄存器(3FDH)来控制UART的工作。线路状态寄存器的标志内容如下:

第0位 1=收到一字节数据

第1位 1=所收数据溢出

第2位 1=奇偶校验错

第3位 1=接收数据结构出错

第4位 1=断路检测

第5位 1=发送保存寄存器空

第6位 1=发送移位寄存器空

第7位 1=超时

当第0位为1时,标志UART已收到一完整字节,此时应及时将之读出,以免后续字符重叠,发生溢出错误,UART有发送保持寄存器和发送移位寄存器。发送数据时,程序将数据送入保持寄存器(当此寄存器为空时),UART自动等移位寄存器为空时将之写入,然后把数据转换成串行形式发送出去。

本程序先发送命令,然后循环检测,等待接收数据,当超过一定时间后视为数据串接收完毕。若接收到数据后返回0,否则返回1。

若以传送一个ASCII字符为例,用波特率9600 b/s,7个数据位,一个起始位,一个停止位来初始化UART,则计算机1秒可发送/接收的最大数据量仅为9600/9=1074字节,同计算机所具有的高速度是无法相比的,CPU的绝大部分时间耗费在循环检测标志位上。在一个有大量数据串行输入/输出的应用程序中,这种消耗是无法容忍的,也不是一种高效率通信方式,而且可以看到,在接收一个长度未知的数据串时,有可能发生遗漏。MOV AL, 20H

OUT 20H, AL用以将当前中断服务寄存器清零,避免中断重复响应。

每路UART有4组中断,程序可通过中断允许寄存器(3F9H)来设置开放那路中断。这4组中断的位标志如下:

第0位 1=接收到数据

第1位 1=发送保持寄存器为空

第2位 1=接收数据出错

第3位 1=MODEM状态寄存器改变

第4~7位为0

在中断例程中检查UART的中断标志寄存器(3FAH),确定是哪一组事件申请中断。该寄存器第0位为0时表示有中断申请,响应该中断并采取相应措施后,UART自动复位中断标志;第2,1位标志中断类型,其位组合格式如下:代码 中断类型 复位措施11接收出错读线路状态寄存器10接收到数据读接收寄存器01发送寄存器空输出字符至发送寄存器00MODEM状态改变读MODEM状态寄存器这4组中断的优先级为0号最低,3号最高。3.结论

上述程序采用C语言编写,在BORLAND C++2.0集成环境中调试通过,为简单起见,只考虑了使用发送/接收两条信号线的情况,并未考虑使用握手信号线。

在实际应用中这两组程序尚有一些可修改之处。比如,中断接收程序中的缓冲区可改为循环表,以防数据溢出,尽可能保留最新数据。由于笔者水平所限,文中不足疏漏之处尚希行家指正。

程序1:

static int receive_delay=10000;

int may(unsigned par,char *comm,char *ss)

{int cs=0,j=0;

char *p;

bioscom(0,par,0); //com1

loop:p=comm;

inportb(0x3f

8); //reset

do{ while((inportb(0x3f8+

5)&0x

20)==0); outportb(0x3f8,*p++);

}while(*p); //send command

os=0;j=0;

do{ if((inportb(0x3fd)&0x0

1)==0)

if(os〉receive_delay) break;

else { cs++;

continue; } ss[j++]=inportb(0x3f

8); cs=0;

}while(l);

ss[j]='0';

if(j) return 0;

else return 1;

程序2:

#include <stdio.h>

#include <stdlib.h>

#include <string.h>

#include <bios.h>

#inolude <dos.h>

#define maxsize 4096

#define SEND 2

#define RECEIVE 1

#define COM1 0

#define COM2 1

static unsigned char Hardinterrupt=0;

struct ComInterrupt

{int portadd;

int intbit;

char buf[maxsize],*comm;

int bufh,recount,sendcount;

}com[2]={{0x3f8,0x0c,"","",0,0,0},

{0x2f8,0x0b,"","",0,0,0} };

void static interrupt (*old_com[2])(void);

vold interrupt coml(vold);

void interrupt com2(void);

void fax2(int comnum);

void setinterrupt(int comnum);

void clearinterrupt(int comnum);

void cominit(int comnum, int para, int interruptmark);

void sendcomdata (int comnum,char *command);

int getcomdata (int comnum, char *buf);

void interrupt com1(void)

{fax2(0);}

void interrupt com2(void)

{fax2

(1);}

// set cominterrupt, comnum 0=com1, 1=com2

void setinterrupt (int comnum)

{

old_com[comnum]=getvect(com[comnum].intbit);

if (!oomnum)

setvect(com[comnum].intbit,coml); //com1

else

setvect(com[comnum].intbit,com

2); //com2

//set hard int

Hardinterrupt = inportb(0x

2

1);

if(comnum)else

outportb(0x21,Hardinterrupt&0xef); //com1 0,

}

void clear interrupt(int comnum)

{

if(comnum)

outportb(0x21,Hardinterrupt | 0x0

8); //COM2

else

outportb(0x21,Hardinterrupt|0x

10); //COM1

setvect(com[comnum].intbit,old_com[comnum]);

for( i=0;i<maxsize;i++) com[comnum].buf[i]='0';

com[comnum].sendcount=com[comnum].recount=com[comnum].bufh=0;

outportb(com[comnum].portadd+1,0);

outportb(com[comnum].por tadd+4,0x0);

}

void fax2(int i)//i=o,com1; i=1, com2

{ unsigned char mark;

mark=inport(com[i].portadd+

2);

do

{

if(mark&0x

4)// receive data

{ if (com[i].bufh==maxsize)

com[i].bufh=0; com[i].buf[com[i].bufh++]=inportb(com[i].portadd); com[

i].recount++;}

else if(mark&0x

2)// send command

{ if(*com[i].comm)

outportb(com[i].p

ortadd,*com[i].comm++);

com[i],sendcount++;}

else

outportb(com[i].portadd+1,

1);

}outportb(ox20,0x

20); //hard int return

}void comint(int com, char para, int interruptmark)

{

bioscom(0, par, com);

//open com interrupt

outportbv (com[comnum]. portadd+4,0x8;

outportb (com[comnum].portadd+1,interruptmark);

}

void sendcomdata(int comnum,char * command)

{ unsigned char interruptmark;

com[comnum],comm=command;

com[comnum],sendcount=0;

//set send interrupt

interruptmark=inportb (com[comnum].portadd_

1);}

//get com_receivedate and clear com_receivebuf,

int getcomdata (int comnum, char * buf)

{ int result=com[comnum]. recount,i:

if(buf)

strncpy(buf,com[comnum].buf,com

[comnum].bufh);

buf[com[comnum].bufh]='0';

com[comnum].recount=com [comnum].bufh=0;

retun(result);

}

下载文档

版权声明:此文档由查字典文档网用户提供,如用于商业用途请与作者联系,查字典文档网保持最终解释权!

网友最新关注

我的“冬训”生活
压岁钱
优点和缺点一样
我眼中的“C罗”
醉人春意
我敬佩的一个人
春节这几天
晚霞
无敌三剑客
寒假计划
秋天的花园
今年喝茶去哪里
我的哥哥
挖冬笋
越野梦
中小学弘扬和培育民族精神月活动总结
2011班主任学年工作总结
水利水电专业技术工程实践总结
暑期实习准备工作总结
小学班主任工作总结
收费系统展示总结
小学教科室工作总结
机房收费系统工作总结
学生会迎新工作总结
暑期总结
淀粉糖生产工艺讲座总结
大学生就业创业促进论坛协会工作总结
校本研修成果在课堂教学中应用总结
迎接新生工作总结
小学第二学期德育工作总结
体育外语翻译人才的培养体系探究
农业高校科技日语翻译文化复合型人才培养模式探微
行政诉讼中的证明责任(4)行政法论文(1)
论从跨文化视角解读法语谚语的翻译策略
英语习语中的动物意象与其中文翻译简析
论英文报刊标题中暗喻的翻译策略
我国财政对农业投入的问题及对策思考
试论外语教学中的翻译教学
大学外语专业翻译教学的问题和教学策略研究
试论行政合理性原则对行政自由裁量权的控制行政法论文(1)
财政职能进一步调整的思路
现代汉语中日语借词的传入
控权
控权
财政赤字中的道德风险
《猴王出世》教学案例
《猴王出世》教学设计
《猴王出世》教学设计1
《景阳冈》教学设计2
《景阳冈》教学设计2
《猴王出世》教学设计7
《猴王出世》教学设计2
《猴王出世》教学札记
《猴王出世》A、B案
《景阳冈》教学设计4
《猴王出世》综合资料
《人物描写一组》教学设计1
《猴王出世》教学设计5
《猴王出世》教学设计4
《猴王出世》教学设计6