24小时热门版块排行榜    

Znn3bq.jpeg
北京石油化工学院2026年研究生招生接收调剂公告
查看: 277  |  回复: 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 的主题更新
普通表情 高级回复 (可上传附件)
最具人气热帖推荐 [查看全部] 作者 回/看 最后发表
[考研] 085600材料与化工专硕329 求调剂 +17 额cc 2026-04-06 18/900 2026-04-07 17:25 by 蓝云思雨
[考研] 328求调剂 +6 lftmya 2026-04-07 7/350 2026-04-07 16:49 by 静花儿
[考研] 材料调剂 +15 一样YWY 2026-04-01 15/750 2026-04-07 15:54 by dxlg
[考研] 求调剂 +25 111623 2026-04-04 27/1350 2026-04-07 15:06 by 上岸快快
[考研] 调剂 +4 mcbbc 2026-04-06 5/250 2026-04-07 12:33 by upczlm1989
[考研] 312求调剂 +4 LR6 2026-04-06 4/200 2026-04-07 08:42 by jp9609
[考研] 0703化学调剂 348分 +8 唉我超真没招了 2026-04-06 8/400 2026-04-07 08:19 by houyaoxu
[考研] 285求调剂 +15 哦呦呼o 2026-04-04 17/850 2026-04-06 23:02 by chenzhimin
[考研] 385分 生物学(071000)求调剂 +12 qf626 2026-04-01 12/600 2026-04-06 17:36 by 52305043001
[考研] 080200学硕,277分,数一104,求带走! +7 瓶子PZ 2026-03-31 7/350 2026-04-05 17:49 by liucky
[考研] 353求调剂 +10 MayUxw1 2026-04-03 10/500 2026-04-05 09:23 by 无际的草原
[考研] 环境285分,过六级,求调剂 +10 xhr12 2026-04-02 10/500 2026-04-04 21:53 by bn53987
[考研] +5 雾与海 2026-04-02 6/300 2026-04-04 19:53 by 蓝云思雨
[考研] 085602 找调剂 +4 逆时针快乐 2026-04-02 4/200 2026-04-04 19:32 by 蓝云思雨
[考研] 一志愿沪985,326分求调剂 +3 刘墨墨 2026-04-03 3/150 2026-04-04 11:16 by 悲伤的芋头
[考研] 085600专硕材料与化工348分求调剂 +10 上学啦! 2026-04-01 11/550 2026-04-03 14:13 by 百灵童888
[考研] 22408 266求调剂 +3 masss11222 2026-04-02 3/150 2026-04-02 18:11 by 笔落锦州
[考研] 材料专业求调剂 +10 月月鸟木 2026-04-01 10/500 2026-04-02 12:57 by wxiongid
[考研] 一志愿北京科技大学085601材料工程英一数二初试总分335求调剂 +9 双马尾痞老板2 2026-04-01 9/450 2026-04-02 12:14 by oooqiao
[考研] 0710生物学,325求调剂 +3 mkkkkkl 2026-04-01 3/150 2026-04-02 09:48 by Jaylen.
信息提示
请填处理意见