24小时热门版块排行榜    

查看: 337  |  回复: 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 的主题更新
普通表情 高级回复 (可上传附件)
最具人气热帖推荐 [查看全部] 作者 回/看 最后发表
[基金申请] 欢迎发来filecode的Mz6后的代码验证其规律 +8 医学老男孩 2026-08-13 25/1250 2026-08-13 21:15 by yq199112088
[文学芳草园] 阿姨 +4 汪汪锅 2026-08-09 4/200 2026-08-13 19:43 by arzu_hma
[硕博家园] 一作与独作在应聘高校教师时区别大吗 +3 mbygzh 2026-08-08 4/200 2026-08-13 19:31 by 龙-樱
[基金申请] 静等基金结果 +8 gjjjzhong 2026-08-10 21/1050 2026-08-13 17:56 by 且听虎啸
[基金申请] filecode +14 documentary 2026-08-10 16/800 2026-08-13 16:39 by 润生71
[基金申请] 重要来源:本周末出结果 +10 瞬息宇宙 2026-08-12 10/500 2026-08-13 15:46 by likettle
[基金申请] 不应该看fileCode +7 且听虎啸 2026-08-12 9/450 2026-08-13 14:27 by flydreamws
[基金申请] Filecode 又变了,巨变 +3 WH3796 2026-08-12 4/200 2026-08-13 14:13 by 小木虫6752397
[基金申请] 我的国基提前知道中了,可是同事的操作让我实在接受不了,怎么会有这样的人 +9 家与远方 2026-08-10 14/700 2026-08-13 09:41 by 臭臭不臭01
[基金申请] 应该是93bebmhtak前后十一个字符比较关键 +22 Lanmanbaby 2026-08-09 36/1800 2026-08-12 22:50 by sdfapple719
[论文投稿] 职称评审,求友友推荐见刊最快的期刊 +4 工厂打螺丝 2026-08-08 4/200 2026-08-12 09:18 by hansi2025
[硕博家园] 读博的好处 +3 lnee 2026-08-11 3/150 2026-08-11 18:10 by 希望我好好的
[基金申请] 什么时候出结果,有咨询渠道??? +3 Tide man 2026-08-11 3/150 2026-08-11 17:54 by kudofaye
[基金申请] 确定了,国自然21号放榜 +6 布布和一二 2026-08-10 7/350 2026-08-10 19:15 by 2000zf36392
[基金申请] 关于代码变化问题,想知道的进来 +17 且听虎啸 2026-08-07 24/1200 2026-08-10 18:35 by zhangduo2008
[基金申请] 国自然结果 +4 Vierhys 2026-08-10 8/400 2026-08-10 15:06 by Vierhys
[基金申请] 据悉今年马上要出结果了 +7 瞬息宇宙 2026-08-10 8/400 2026-08-10 12:42 by Vivilian
[基金申请] 这样的filecode谁见过 +11 布布和一二 2026-08-08 22/1100 2026-08-10 11:10 by wmfsnow
[基金申请] 面上项目filecode邪修 +5 西山十月 2026-08-09 7/350 2026-08-10 07:32 by 仁砚薪传
[基金申请] 国基金的申报应该改成非等额制,评价高的钱多评价低的钱少,但是增加资助率 +7 a089 2026-08-07 7/350 2026-08-08 18:05 by gltch
信息提示
请填处理意见