24小时热门版块排行榜    

Znn3bq.jpeg
查看: 284  |  回复: 2
当前主题已经存档。

yaojinling

金虫 (正式写手)

[交流] 用C语言编写串口程序

用C语言编写串口程序
在当今,流行的编程软件种类繁多,它们编程方便、易于维护,但是在与硬件直接打交道和编制系统软件时却束手无策,于是C语言就有了用武之地。C语言作为汇编语言与高级语言之间的一种过渡语言,兼有汇编语言的高效和高级语言的方便。
  在通讯中,为了保证行运安全可靠,标准的串行口必须具有许多握手信号和状态信息。这是因为通讯的各个计算机CPU速度不一样(这会导致“错帧”)以及发送机发送数据速度比接收机接收速度快(这会导致“过冲”)。为解决这个问题,我们采用一个简单的握手信号,即发送机每次仅发送半个字节(低4位)的数据,而另外半个字节(高4位)则用来传送信息。我们可以对信息位(高4位)进行如下简单的编码:
0H:发送的是新的半个字节数据
1H:重新发送上次传送错误的数据
2H:文件名结束
3H:文件结束
这样,每当发送机发送一个字节以后,就等待接受机发回送信号,这回送信号就是发送机发送过来的那个字节。发送机接收到回送信号后,把它与刚发送的字节相比较,如果相同,就发送新的半个字节,否则就重新发送。新数据与旧数据通过信息位来区分。下面就是用C语言编写控制串行口的程序。
#include "dos.h"
#include "stdlib.h"
#include "stdio.h"
#define PORT 0
void SendFile(char *fname); /* 发送文件*/
void Send(int s); /*发送一个字节*/
void SendFileName(char *fname); /*发送文件名*/
void ReceiveFile(); /*接收文件*/
void GetFileName(char *f); /*接收文件名*/
void InitPort(int port,unsigned char para); /*初始化端口*/
void SendPort(int port,char c); /*端口发送*/
int ReadPort(int port); /*读端口字节*/
int CheckState(int port); /*检查端口状态*/
int Receive(int port,int *G); /*接收一个字节*/
main(int argc,char *argv[])
{
  if(argc<2){
           printf("Please input R(receive) or S(sent) parametre:";
           exit(1);
           }
  InitPort(PORT,231);
  if(*argv[1]==''''S'''') /*检查选择的有效性*/
  SendFile(argv[2]);
   else if(*argv[1]==''''R'''')
    ReceiveFile();
   else{
       printf("Error parament.Please input again.";
       exit(1);
      }
}
void SendFile(char *fname)
{
  FILE *fp;
  int ch,s;
  if((fp=fopen(fname,"rb")==NULL)
                      {
                         printf("Can''''t open the file.\n";
                         exit(1);
                       }
  SendFileName(fname);
  do{
      ch=(int)getc(fp);
      if(ferror(fp)){
                   printf("Error reading file.\n";
                   break;
                }
      s=ch%16; /*取文件中一个字节的低4位*/
      Send(s);
      s=ch/16; /*取文件中一个字节的高4位*/
      Send(s);
     }while(!feof(fp));
  s=46; /*发送文件结束信息*/
  Send(s);
  Send(s);
  fclose(fp);
}
void Send(s)
int s;
{
  int G;
  SendPort(PORT,s);
  G=ReadPort(PORT); /*等待握手信号*/
  if(s!=G)
  s=s+16;
  do{
      SendPort(PORT,s);
      G=ReadPort(PORT);/*等待握手信号*/
  }while(s!=G);
}
void SendFileName(fname)
char *fname;
{
  int s,ch;
  printf("Now transmit the file.Please wait...";
  while(*fname){
                ch=(int)fname++;
                s=ch%16; /*取文件名中一个字节的低4位*/
                Send(s);
                s=ch/16;
                Send(s); /*取文件名中一个字节的低4位*/
               }
  s=32; /*发送文件名结束标志*/
  Send(s);
  Send(s);
}
void ReceiveFile(){
                 FILE *fp;
                 char ch;
                 int G1,G2,G3;
                 char fname[15];
                 GetFileName(fname);
                 printf("Receiving file %s.\n",fname);
                 remove(fname);
                 if((fp=fopen(fname,"wb")==NULL)
                     {
                        printf("Can''''t open output file.\n";
                        exit(1);
                     }
/*循环为检测每次接受的数据是否为新数据,如果不是,*/
/*则用此次接收的数据覆盖上次接收的数据*/
G1=ReadPort(PORT);
G2=Receive(PORT,&G1);
do{
     G3=Receive(PORT,&G2);
     ch=(char)(G1%16+G2*16);/*恢复分开的数据,组合高4位和低4位*/
     putc(ch,fp);
     if(ferror(fp)){
                  printf("\nError writing file.";
                  exit(1);
                }
G2=Receive(PORT,&G3);
  G1=G3;
  }while(G1/16!=48);
  printf("\nTransmit finished.";
  fclose(fp);
}
int Receive(port,G)
int port,*G;
{
    int GM;
    SendPort(port,*G);
    GM=ReadPort(port);
    if(GM/16==0)
    return GM;
    else if(GM/16==1){
                      do{
                          *G=GM;
                          SendPort(port,GM);
                          GM=ReadPort(port);
                         }while(GM/16==1);
                    }
     return GM;
}
void GetFileName(char *f)
{
   int G1,G2,G3;
   char ch;
   G1=ReadPort(PORT);
   G2=ReadPort(PORT);
   do{
       G3=Receive(PORT,&G3);
       ch=(char)(G1%16+G2/16);
       *f=ch;
       *f++;
       G2=Receive(PORT,&G3);
       G1=G3;
     }while(G1/16!=32);
    printf("File name transmit finished.\n";
}
void InitPort(port,para)
int port;
unsigned char para;
{
   union REGS reg;
   reg.x.dx=port;
   reg.h.ah=0;
   reg.h.al=para;
   int86(0x14,®,®;
}
void SendPort(port,c)
int port;
char c;
{
   union REGS reg;
   reg.x.dx=port;
   reg.h.al=c;
   reg.h.ah=1;
   int86(0x14,®,®;
   if(reg.h.ah&128){
                   printf("\nSend mistakes!";
                   exit(1);
                 }
}
int ReadPort(port)
int port;
{
   union REGS reg;
   while(!(CheckState(port)&256)){
   if(kbhit()){/*如端口长期无数据可人为终止等待*/
             printf("Press any key to exit.";
             getch();
             exit(1);
           }
}
   reg.x.dx=port;
   reg.h.ah=2;
   int86(0x14,®,®;
   if(reg.h.ah&128){
                   printf("\nRead mistake!";
                   exit(1);
                 }
  return reg.h.al;
}
int CheckState(port)
int port;
{
   union REGS reg;
   reg.x.dx=port;
   reg.h.ah=3;
   int86(0x14,®,®;
   return reg.x.ax;
}

以上程序可传送各种格式的文件,也有一定的自动纠错能力,但对于异常情况的
处理能力比较弱,读者可以自己改进。由于篇幅限制,对于中断14H的功能、入
口参数及返回参数的意义请读者自己查有关资料。

[ Last edited by sdlwwxb on 2005-12-16 at 17:58 ]
回复此楼

» 猜你喜欢

已阅   回复此楼   关注TA 给TA发消息 送TA红花 TA的回帖

yaojinling01

0.5

谢谢!!!!!!111
2楼2005-11-18 18:33:26
已阅   回复此楼   关注TA 给TA发消息 送TA红花 TA的回帖

imrking

荣誉版主 (著名写手)

????????????????????
下雨了,别忘了打伞,湿身是小,淋病就麻烦啦~~~:)
3楼2005-11-18 19:48:12
已阅   回复此楼   关注TA 给TA发消息 送TA红花 TA的回帖
相关版块跳转 我要订阅楼主 yaojinling 的主题更新
普通表情 高级回复 (可上传附件)
最具人气热帖推荐 [查看全部] 作者 回/看 最后发表
[考研] 0854求调剂 +21 门路摸摸 2026-04-15 25/1250 2026-04-17 15:45 by qzxyhcsy
[考研] 一志愿中科大材料与化工,353分还有调剂学校吗 +9 否极泰来2026 2026-04-15 11/550 2026-04-17 11:08 by liuzhexuan12
[考研] 335求调剂 +20 想上岸呀!! 2026-04-12 23/1150 2026-04-17 10:50 by cuisz
[考研] 300求调剂 +11 橙a777 2026-04-15 11/550 2026-04-16 22:43 by cfdbai
[考研] 22408 312求调剂 +23 门路摸摸 2026-04-14 25/1250 2026-04-16 21:21 by Art1977
[考研] 297,工科调剂?河南农业大学本科 +14 河南农业大学-能 2026-04-14 14/700 2026-04-16 14:41 by dingyanbo1
[考研] 279学硕食品专业求调剂院校 20+7 孤独的狼爱吃羊 2026-04-12 29/1450 2026-04-16 09:00 by screening
[考研] 297,工科调剂? +10 河南农业大学-能 2026-04-14 10/500 2026-04-15 21:50 by noqvsozv
[考研] 310求调剂 +16 666真好 2026-04-11 18/900 2026-04-15 13:28 by 黑科技矿业
[考研] 366求调剂 +11 不知名的小卅 2026-04-11 11/550 2026-04-14 15:50 by zs92450
[考研] 调剂 +12 月@163.com 2026-04-11 12/600 2026-04-14 15:37 by zs92450
[考研] 考研求调剂 +6 ban班小七 2026-04-11 6/300 2026-04-14 14:06 by 哆啦A梦只是个梦
[考研] 105500药学求调剂 +4 x_skys 2026-04-12 4/200 2026-04-14 13:37 by rndfc
[考研] 085600材料与化工329分求调剂 +24 叶zilin 2026-04-13 25/1250 2026-04-14 09:20 by 试管破裂
[考研] 求调剂,985材料与化工348分 +9 涵竹刘 2026-04-11 14/700 2026-04-13 22:26 by 涵竹刘
[考研] 331求调剂 +5 王国帅 2026-04-11 5/250 2026-04-11 22:56 by 溪涧流水
[考研] 283求调剂 086004考英二数二 +17 那个噜子 2026-04-10 18/900 2026-04-11 16:27 by 明月此时有
[考研] 调剂求助 +6 果然有我 2026-04-11 7/350 2026-04-11 16:22 by 明月此时有
[考研] 求调剂,一志愿大连理工大学354分 +5 雨声余生 2026-04-11 6/300 2026-04-11 16:12 by 雨声余生
[考研] 求调剂 +3 胃痉挛累了 2026-04-11 5/250 2026-04-11 14:13 by luhong1990
信息提示
请填处理意见