一直想将串口编程整理一下,一来分享给想了解串口编程的爱好者,二来防止梳理一下对COM的认识,^_^。

以前在网上也查询了很多相关的串口编程,居多的是在Windos环境,使用VC,VB编写的,也有在DOS下编写,但是看了很久的代码,揣摩很久,有的地方还不明白。这次我分享的是DOS下的COM操作,下面是我编写验证OK的Code。

编译环境:MS-DOS 7.1 +Borland C3.1

通过一个例子来说明吧,实现在DOS环境下,将DOS下的文件通过串口传送到其它终端设备(如:另一PC:Personal Computer)。

DOS(PC)  <---------(COM)-------> Windows(PC) 实现不同OS之间传送,Windows接收到数据可以依据规则做相应的处理,暂时不考虑数据的冗余校验(CRC)。

Code:

#include<stdio.h>
#include<dos.h>
#include<conio.h>
#include <sys\stat.h>
#include <fcntl.h>
#include <io.h>
#include <stdlib.h>
#include <string.h>
#include <malloc.h>
#include <dir.h>

unsigned char *cy_receive_buf; //文件字符
int lenchar=0;//文件字符的长度

/*=========================================================================*/
//1.初始化串口函数
/*initial COM */
/*Ex:InitCom(C1,0x0C,0x0B) --COM1,9600pbs,8bit Data,1 Stop Bit,odd Check*/

void InitCom(int Port,char BaudRate,char bits)
{
outportb(Port + 1, 0);         /* Turn off interrupts - Port*/
outportb(Port + 3, 0x80);      /* SET DLAB ON */
outportb(Port + 0, BaudRate);  /* Set Baud rate-Low 8 Byte */
outportb(Port + 1, 0x00);      /* Set Baud rate -High 8 Byte */
outportb(Port + 3, bits);      /* 8 Bits, No Parity, 1 Stop Bit */
}

/*=========================================================================*/
//2.发送数据函数
// Send Data Function,Data 为字节
int Send(int Port,char Data)
{
  unsigned char status = inportb(Port + 5);  /* Check Line Status */
  unsigned int count = 2000;
  while(!(status & 0x20) && (count > 0))
  {
    count --;
    status = inportb(Port + 5);
  }

if(count > 0)
  {
    outportb(Port + 0, Data);
    return 0;
  }
  else
  {
    printf("COM Send Data Error!\n");
    return -1;
  }
}
/*=========================================================================*/

//3.接收数据
//Receive Data Function
int Receive(int Port)
{
  char *pd;
  unsigned char  status = inportb(Port + 5); /* Check Line Status */
  if(status & 0x01)
{
*pd = inportb(Port + 0); /* Read */

//printf(" %x \n",*pData);
return *pd;
}
return 0;
}
/*=========================================================================*/

//4.Help
void Help(void)
{
printf("Syntax error :\n");
printf("Usage : send |<COM Port>|<filename>\n");
printf("<COM Port> : C1 ==> COM1 0x3F8\n");
printf("<COM Port> : C2 ==> COM2 0x2F8\n");
printf("<COM Port> : C3 ==> COM3 0x3E8\n");
printf("<COM Port> : C4 ==> COM4 0x2E8\n");
printf("<COM Port> : C5 ==> COM5 0x2E0\n");
printf("<COM Port> : C6 ==> COM6 0x2F0\n");
printf("<filename> : C123NB6.008 ==>Log File Name\n");
printf("Example : send C1 \\C123NB6.008==> Use COM1 Up log File C123NB6.008\n" );
exit(-1);
}
/*=========================================================================*/

/*=========================================================================*/
//5.Main Function

int main(int argc,char **argv)
{
int i,Port;
FILE *fp;  //For Open Log File ,文件指针
char ch;         // Read Log File
int  wFileLen; //读取文件长度
char *CName; //Use Which Com Port
char *FName ; //For LogFile Name

//char Path[50]="C:\\Borlandc\\bin\\";   //For Log File Path

char *PathFile;     //For Link Path +FileName

char buffer[MAXPATH];
getcwd(buffer, MAXPATH); //获取当前路径

if (argc <2 )
{
Help();
return -1;
}

if (strcmp( argv[1],"/?")==0)
{
Help();
return -1;
}

if (strcmp( argv[1],"?")==0)
{
Help();
return -1;
}

if((strcmp(argv[1],"C1") != 0) && (strcmp(argv[1],"C2") != 0) && (strcmp(argv[1],"C3") != 0) && (strcmp(argv[1],"C4") != 0))
{
Help();
return -1;
}

if (argc >3)
{
Help();
return -1;
}

//第一个参数是COM PortID,第二个参数是要传送的文件名
if (argc >= 2)
{
//COM PortID
//printf("Which COM Port Used:%s\n",argv[1]);

CName=argv[1];
if (strcmp(CName,"C1")==0)
Port=0x3F8;
if(strcmp(CName,"C2")==0)
Port=0x2F8;
if(strcmp(CName,"C3")==0)
Port=0x3E8;
if(strcmp(CName,"C4")==0)
Port=0x2E8;
if(strcmp(CName,"C5")==0)
Port=0x2E0;
if(strcmp(CName,"C6")==0)
Port=0x2F8;

//要传送的文件名称
//printf(" LogFile Name is:%s\n",argv[2]);
FName=argv[2];
}

//For Debug调试使用
// printf("Port is %d \n",Port);
//printf("Path is :%s\n",buffer);

//路径加文件名称 
PathFile=strcat(buffer,FName);  
 
//For Debug调试使用
  //printf("Path and File Name is :%s\n",PathFile);
    // getch();

//读取要传送的文件
if((fp=fopen(PathFile,"rb"))==NULL) //Read Only
{
printf("Open Log File Error!\n");
exit(-1);
}

//文件读取成功,获取文件内容长度
//printf("File length :%ld\n",filelength(fileno(fp)));

wFileLen=filelength(fileno(fp));

//对内容做CRC16校验的话,要在发送的内容上加入2位校验位
//重新定义数组的大小为文件大小加2(校验位的高低位)

//不考虑校验值的情况,取消下一步
//cy_receive_buf = (unsigned char*)calloc(wFileLen+2,sizeof(char));

cy_receive_buf =(unsigned char*)calloc(wFileLen+0,sizeof(char));

ch=fgetc(fp);

//printf("COM Initialize...           \n");

InitCom(Port,0x0C, 0x03);//9600bps,8位数据位,0x03无校验,1为停止位
     delay(50);
while(ch!=EOF)
{
//putchar(ch);//输出显示,方便调试
//crc_chec_fuc(ch) ;
//Send(Port,ch);
cy_receive_buf[lenchar]=ch;
lenchar++;
  //delay(5);
ch=fgetc(fp);
}
printf("\n");

//计算读取字符串的CRC值
//暂时不做CRC
//Calculate_CRC(cy_receive_buf,wFileLen);
//getch();

//printf("\n");

//获取要发送字符串的CRC高位和低位
//cy_receive_buf[wFileLen+0]=get_Hvalue(CRC) ;
//cy_receive_buf[wFileLen+1]=get_Lvalue(CRC);

//显示获取的高低位的值   
  //printf("CRCH is %x\n",cy_receive_buf[wFileLen+0]);
//printf("CRCL is %x\n",cy_receive_buf[wFileLen+1]);
// getch();

//开始上传读取的文件的内容
//printf(" Log File Uploading ....\n");

//移除校验的高低字节(2位)
//for(i=0;i <wFileLen+2;i++)
for(i=0;i <wFileLen;i++)
{
 //For Debug 显示发送的字符
// printf("%02X ",cy_receive_buf[i]);
delay(1);
//getch();
Send(Port,cy_receive_buf[i]);
}
//发送完成后发送一个特殊字符,告知接收到该字符
//为发送完成标志,这个字符由上位机处理(Windos PC )
Send(Port,'§');
fclose(fp);
return 0;
}

此代码编译验证PASS,可以发送文件内容,可以使用串口调试工具测试。

接收的数据可以在上位机上处理成自己需要的字符串。如果有任何疑问,可以联系我讨论。

DOS系统下控制串口(1)相关推荐

  1. 61-20210407华为海思Hi3516DV300的linux系统下控制GPIO口(标准linux模式点亮LED灯)

    61-20210407华为海思Hi3516DV300的linux系统下控制GPIO口(标准linux模式点亮LED灯) 2021/4/7 15:13 https://xueqiu.com/797071 ...

  2. Linux系统下安装串口调试工具

    问题描述: 在Linux系统下,想使用串口调试工具,可以安装 miniCom.(基于Ubuntu 16.04) 安装命令: sudo apt install miniCom 配置: 首次使用时,需要进 ...

  3. dos系统下oracle,oracle 在win2000 DOS 下的启动(转)

    在网上搜了好多有关oracle下DOS方式启动数据库的文章都没有解决这个问题偶然把这个问题给解决了 在网上看到有些网友说在oracle9i把svrmgr30(unix下为svrmgrl)给取消了用sq ...

  4. Win系统下打开串口转换USB口的RS232串口,打不开问题

    一.[问题] 1. QT窗口程序想通过串口与设备通信,于是以QT的方式初始化好,由于串口(物理)转换USB的串口只有一个,别人用了,自己就没法用,然后用虚拟串口调试,一切都正常,把功能都实现了8成了. ...

  5. dos系统下Python换行方法

    第一步cmd 第二步输入Python 第三步写代码后缀有:即可 输入后就变成- 退出换行按ctrl+Z回车即可 下面是有关案例详情

  6. Linux系统下的几种终端设备文件

    终端是一种字符型设备,它有多种类型,通常使用tty来简称各种类型的终端设备. 在Linux系统的设备特殊文件目录/dev/下,终端特殊设备文件一般有以下几种: 1.串行端口终端(/dev/ttySn) ...

  7. Linux系统下的文件管理类常命令及使用方式

    Linux上的文件管理类命令有哪些,常用的使用方式 文件系统操作命令分为:目录操作命令.文件操作命令.权限操作命令 目录操作命令: ls 列出目录的属性信息 pwd 列出用户当前所处目录路径 du 列 ...

  8. 关于Linux系统下在使用close关闭串口设备时引起的内核崩溃问题解决方法

    有时在Linux系统下使用串口时,在操作关闭时会遇到内核崩溃或者其他的一些问题. 经过研究发现很可能是数据未发送完成引起的,即在关闭的时候,串口还在忙碌状态导致了崩溃问题. 解决方法就是,等待串口完成 ...

  9. linux下串口设备文件,linux下各种串口调试助手

    在 linux 系统下进行串口调试或者开发时配合简单易用的串口调试工具那是必不可少.这篇博客对当前用的较多的,且我自己经常用的一些串口工具做一下汇总,大家可以参考一下. 实验环境: OS: Ubunt ...

  10. 机器人底层通讯(3): linux系统下获取电子罗盘数据(上)

    1.已有设备和接口 电子罗盘–1个 RS485转RS232接口–1个 RS232转USB接口-- 1个 2.在window10系统下借助串口调试器可以正常接收数据,说明电子罗盘正常: 3.查看是否已正 ...

最新文章

  1. PyTorch 的 Autograd详解
  2. fisher's exact test
  3. 正确使用 Android 性能分析工具——TraceView
  4. ArrayList和数组间的相互转换
  5. NS安装问题收集(3)
  6. Centos7安装tengine-2.3.2版本
  7. umi权限路由_Umi 小白纪实(三)—— 震惊!路由竟然如此强大!
  8. 计算机缺少fixos.dll,fix_toolbox.dll
  9. 【视频】LSTM神经网络架构和原理及其在Python中的预测应用|数据分享
  10. how to write a good api
  11. 【IPTV】TCP/IP四层模型
  12. paypal如何退款
  13. linux安装打字软件
  14. “网上下单”生活神技能,寄快递在线下单、查快递实时物流信息
  15. 微信小程序开发基础(02模板与配置)
  16. IT66021FN 寄存器配置
  17. <<视觉问答>>2022:SwapMix: Diagnosing and Regularizingthe Over-Reliance on Visual Context in VQA
  18. ❤️交房步骤和注意事项❤️
  19. 中国量化金行业全解:金融工计机计金领就指
  20. 在 44186 款开源软件中搜索 前端开发者不得不知的 ECMAScript 6 十大特性 oschina 2016年03月16日 前端开发者不得不知的 ECMAScript 6 十大特性

热门文章

  1. Mixly02:米思齐(Mixly)软件安装及初体验
  2. TBase开源版V2.1.0 集群搭建部署完整版
  3. 周末闲来——2048游戏开发
  4. C#可用的RSA公钥加密私钥解密以及私钥加密公钥解密,支持2048
  5. 图像白平衡原理及实现
  6. 双目视觉测距离(三维重建)
  7. matlab基础编程,Matlab 编程入门(一):编程基础
  8. FAT文件系统与文件恢复
  9. PHP 递归算法操作文件编程
  10. Linux下oracle数据库备份方案