| 网站首页 | 业界新闻 | 小组 | 威客 | 人才 | 下载频道 | 博客 | 代码贴 | 在线编程 | 编程论坛
欢迎加入我们,一同切磋技术
用户名:   
 
密 码:  
共有 10734 人关注过本帖, 1 人收藏
标题:用C语言编程操作计算机串口,请大神们看看这个程序该怎样修改???
只看楼主 加入收藏
一叶扁舟2014
Rank: 1
等 级:新手上路
帖 子:8
专家分:0
注 册:2014-4-1
结帖率:0
收藏(1)
已结贴  问题点数:20 回复次数:13 
用C语言编程操作计算机串口,请大神们看看这个程序该怎样修改???
   #include <stdio.h>
    #include <string.h>
    #include <stdlib.h>
    #include <conio.h>
    #include <windows.h>
    #include <winnt.h>

    #define BAUD_RATE  9600
    #define COM1_BASE  ???                        /* com1基地址 */
    #define p  printf
   
    int main()
    {
    /*  打开串口  */
    Handle hCom;
   //    int pos;
    unsigned char  buff[128];                     //要传输串口数据到缓冲区

    /*  把串口作为文件打开  */
    hCom=CreateFile("COM1",                       //打开串口1
                GENERIC_READ|GENERIC_WRITE,       //允许读写
                0,                                //通讯设备必须以独占方式打开
                NULL,                             //安全属性
                OPEN_EXISTING,                    //通讯设备已存在
                FILE_FLAG_OVERLAPPED,             //异步I/O
                0,                                //通讯设备不能用模板打开
                NULL);   
    if(hCom==(HANDLE)-1)                          //打开串口失败返回
    {
    p("打开串口失败");
    return 0;
        }

    /*  串口超时结构体设置  */
     typedef COMMTIMEOUTS TimeOuts
    {
    TimeOuts.ReadIntervalTimeout=1000;            //接收时两字符之间的最大时延
    TimeOuts.ReadTotalTimeoutMultiplier=500;      //指定以毫秒为单位的累积值,用于计算读操作时的超时总数
    TimeOuts.ReadTotalTimeoutConstant=5000;       //指定以毫秒为单位的常数,用于计算读操作时的超时总数
    TimeOuts.WriteTotalTimeoutMultiplier=500;     //计算写操作时的超时总数
    TimeOuts.WriteTotalTimeoutConstant=2000       //计算写操作时的超时总数
     };
   
    if(!SetCommTimeouts(hCom,&TimeOuts))          //与串口绑定失败返回
    {
        p("与串口绑定失败")
        return 0;
    }
    /* 设置串口各项参数  */
    DCB dcb;
    {
        if(!GetCommState(hCom,&dcb))
            p("获取串口属性失败");
            return 0;
    }
    dcb.BaudRate=BAUD_RATE;     //波特率为9600
    dcb.ByteSize=8;             //设置数据位
    dcb.Parity=EVENPARITY;      //偶校验
    dcb.StopBits=2;             //两个停止位
    dcb.fBinary=TRUE;
    dcb.fParity=TRUE;

    if(!SetCommState(hCom,&dcb))                  //DCB绑定失败返回
    {
        p("串口设置出错!");
        return 0;
    }
   
    if(!SetupComm(hCom,1024,1024))                //设置串口的输入/输出缓冲区大小
    {
    p("设置串口读写缓冲区失败");
    return 0;
    }
    PurgeComm(hCom,PURGE_TXABORT|PURGE_RXABORT|PURGE_TXCLEAR|PURGE_RXCLEAR);  //终止所有的后台读写操作并清空缓冲区
   
   /*  发送数据操作  */
    if(WriteFile(hCom,         //文件句柄
        outputData,            //数据缓冲区指针
        sizeBuffer,            //字节数
        &length,               //接收成功发送数据长度的指针
        NULL)==0)              //重叠I/O结构体        
    {
    p("写入串口数据失败");
    return FALSE;
    }

    /*  接收数据  */
        if(ReadFile(hCom,      //文件句柄
        inputData,             //数据缓冲区指针
        sizeBuffer,            //字节数
        &length,               //指向已经读入的字节数
        NULL)==0)              //重叠I/O结构体      
            
    {
    p("读取串口数据失败");
    return FALSE;
    }

   /*  关闭串口  */
   bool CloseHandle
        (
        hCom
        ); //关闭设备句柄
            
      
搜索更多相关主题的帖子: 缓冲区 C语言 计算机 include 
2014-04-06 09:49
Andrew_Lee
Rank: 7Rank: 7Rank: 7
等 级:黑侠
威 望:3
帖 子:185
专家分:626
注 册:2014-3-21
收藏
得分:20 
没啥大问题,不知道楼主用软件的,我用VC6.0,小修了下,最后测试OK了,你可以对照修改后的代码看看,主要过程还是按照你的代码过程的。。
按照我个人来说PurgeComm(hCom,PURGE_TXABORT|PURGE_RXABORT|PURGE_TXCLEAR|PURGE_RXCLEAR);  //终止所有的后台读写操作并清空缓冲区
这个还是不要用了,貌似代价太大,而且对于你这个串口操作基本0影响
程序代码:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <conio.h>
#include <windows.h>
#include <winnt.h>

#define BAUD_RATE 9600
#define p printf

int main()
{
    HANDLE hCom;
    //unsigned char buf[128];
    char inputData[1024]="nihao";
    char outputData[1024];
    int sizeBuffer = 6;
    int length;
    COMMTIMEOUTS TimeOuts; /*定义超时变量*/
    DCB dcb;/*串口DCB设置*/

    /*打开串口文件*/
    hCom = CreateFile("COM4",GENERIC_READ|GENERIC_WRITE,0,NULL,OPEN_EXISTING,0,NULL);
   

    /*强制类型转换-1为HANDLE类型*/
    if(hCom == (HANDLE)-1)
    {
        printf("open COM failed\n");
        exit(1);
    }

    /* 超时设置 */
    TimeOuts.ReadIntervalTimeout=1000;
    TimeOuts.ReadTotalTimeoutMultiplier=500;
    TimeOuts.ReadTotalTimeoutConstant=5000;
    TimeOuts.WriteTotalTimeoutMultiplier=500;
    TimeOuts.WriteTotalTimeoutConstant=2000;

    /* 写入串口超时参数,出错返回0*/
    if(!SetCommTimeouts(hCom,&TimeOuts))
    {
        printf("写入超时参数错误");
        exit(1);
    }

    /* 设置输入输出缓冲区参数,返回非0表示成功 */
    if(!SetupComm(hCom,1024,1024))
    {
        printf("设置串口读写缓冲区失败\n");
        exit(1);
    }

    /* 获取当前串口状态信息(只需要修改部分串口信息),调用失败返回0*/
    if(!GetCommState(hCom,&dcb))
    {
        printf("获取串口属性失败\n");
        exit(1);
    }
   

    /*具体情况,具体对待*/
    dcb.BaudRate = BAUD_RATE;
    dcb.ByteSize = 8;
    dcb.Parity = NOPARITY;    /*无校验*/
    dcb.StopBits=ONESTOPBIT; /*1位停止位*/

    if(!SetCommState(hCom,&dcb))
    {
        printf("设置串口参数出错\n");
        exit(1);
    }

 

    if(WriteFile(hCom,outputData,sizeBuffer,&length,NULL)==0)
    {
        printf("写入串口数据失败\n");
        exit(1);
    }

    if(ReadFile(hCom,inputData,sizeBuffer,&length,NULL)==0)
    {
        printf("读取串口数据失败\n");
        exit(1);
    }

    /*关闭串口*/
    CloseHandle(hCom);
   

    return 0;
}
DCB的是我按照我自己的要求设置的,用的时候可以根据你自己的下位机要求具体设置


[ 本帖最后由 Andrew_Lee 于 2014-4-7 11:01 编辑 ]
2014-04-07 10:59
一叶扁舟2014
Rank: 1
等 级:新手上路
帖 子:8
专家分:0
注 册:2014-4-1
收藏
得分:0 
回复 2楼 Andrew_Lee
谢谢!
2014-04-07 15:09
一叶扁舟2014
Rank: 1
等 级:新手上路
帖 子:8
专家分:0
注 册:2014-4-1
收藏
得分:0 
回复 2楼 Andrew_Lee
#include <windows.h>  
    #include <stdio.h>
    #include <string.h>
    #include <stdlib.h>
    #include <commdlg.h>
    #include <windef.h>

  

    #define BAUD_RATE  9600
    #define p  printf
    #define  size  1024                           //数据缓冲区大小

    int nread,nwrite;
  
    void main()
    {
    HANDLE hCom;
    COMMTIMEOUTS timeouts;
    COMMCONFIG dcb;
    char *buffRead;
    char *buffWrite;
    DWORD dwBytesWritten,dwBytesRead;
   
    retry:
    /*  把串口作为文件打开  */
    hCom=CreateFile("COM1",                       //打开串口1
                GENERIC_READ|GENERIC_WRITE,       //允许读写
                0,                                //通讯设备必须以独占方式打开
                NULL,                             //安全属性
                OPEN_EXISTING,                    //通讯设备已存在
                FILE_FLAG_OVERLAPPED,             //异步I/O                                             
                NULL);   
    if(hCom==(HANDLE)-1)                          //打开串口失败返回
    {
        if(GetLastError()==ERROR_FILE_NOT_FOUND)
        {
            p("serial port does exist.\n");
        }
        p("some other error occured, Inform user.\n");
    }
    else
        p("port open successed!\n");


    /*  串口超时结构体设置  */
    SetCommTimeouts(hCom,&timeouts);
    //COMMTIMEOUTS timeouts={0};
   
    timeouts.ReadIntervalTimeout=1000;            //接收时两字符之间的最大时延
    timeouts.ReadTotalTimeoutMultiplier=500;      //指定以毫秒为单位的累积值,用于计算读操作时的超时总数
    timeouts.ReadTotalTimeoutConstant=5000;       //指定以毫秒为单位的常数,用于计算读操作时的超时总数
    timeouts.WriteTotalTimeoutMultiplier=500;     //计算写操作时的超时总数
    timeouts.WriteTotalTimeoutConstant=2000;       //计算写操作时的超时总数
     
    if(!SetCommTimeouts(hCom,&timeouts))          //与串口绑定失败返回
    {
        p("error setting port state.\n");
    }
   
    /* 设置串口各项参数  */
    if(!GetCommState(hCom,&dcb.dcb))
    {
    p("error setting serial port state.\n");  //串口绑定失败
    }
    dcb.dcb.BaudRate=BAUD_RATE;     //波特率为9600
    dcb.dcb.ByteSize=8;             //设置数据位
    dcb.dcb.Parity=EVENPARITY;      //偶校验
    dcb.dcb.StopBits=2;             //两个停止位
    dcb.dcb.fBinary=TRUE;
    dcb.dcb.fParity=TRUE;

    if(!SetCommState(hCom,&dcb.dcb))                  //DCB绑定失败返回
    {
        p("串口设置出错!");
    }
   
/*    /*  设置串口输入输出缓冲区  
    if(!SetupComm(hCom,1024,1024))                //设置串口的输入/输出缓冲区大小
    {
    p("设置串口读写缓冲区失败");
    }
    PurgeComm(hCom,PURGE_TXABORT|PURGE_RXABORT|PURGE_TXCLEAR|PURGE_RXCLEAR);  //终止所有的后台读写操作并清空缓冲区   */
   
    /*  将数据写入缓冲区操作  */
    buffWrite=(char *)malloc(size);             //输入缓冲区分配
        p("please input yourdata:");
    scanf("%s",buffWrite);
    nwrite=255;                                 //nwrite=1024
     
    if(!WriteFile(hCom,buffWrite,nwrite,&dwBytesWritten,NULL))
    {
        p("error writting to output buffer.\n");
    }
    else
        p("written data:%s\n",buffWrite);
        system("pause");                       //调用系统命令pause,输出类似于“press any key to exit”的字

    /*  从输出缓冲区读取数据操作  */
    // buffRead=0;
       buffRead=(char *)malloc(size);

    /*  在缓冲区设置当前的读写位置  */
         SetFilePointer(hCom,                 //问价句柄
             0,                               //偏移量(低位)
             0,                               //偏移量(高位)
             FILE_BEGIN);                     //基准位置
     nread=GetFileSize(hCom,NULL);            
     buffRead=(char *)malloc(nread+1);
     memset(buffRead,0,size);                 //将缓冲区的前1024个字节用0代替,相当于初始化

     if(!ReadFile(hCom,buffRead,nread,&dwBytesRead,NULL))
     {
     p("error reading from input buffer.\n");
     }
     else
         p("Data read from read buffer is:%s\n",buffRead);

    /*  关闭串口  */
  CloseHandle
        (
        hCom        //关闭设备句柄
        );
         
  Sleep(2000);
  goto retry;
  }
      
我在那个程序基础上又编写了一个,但是在读取缓冲区数据时出现错误,能再帮我改正一下吗?
2014-04-07 15:12
Andrew_Lee
Rank: 7Rank: 7Rank: 7
等 级:黑侠
威 望:3
帖 子:185
专家分:626
注 册:2014-3-21
收藏
得分:0 
能把错误信息也放在上面吗?这样会快些,还有个就是你调用malloc分配的内存,使用完之后调用free函数将这段内存释放掉,我粗略看了下,调用了两次malloc,都没有调用free

[ 本帖最后由 Andrew_Lee 于 2014-4-7 16:00 编辑 ]
2014-04-07 15:46
一叶扁舟2014
Rank: 1
等 级:新手上路
帖 子:8
专家分:0
注 册:2014-4-1
收藏
得分:0 
回复 5楼 Andrew_Lee
编译是通过的,但就是运行读取缓冲区的数据时会出现乱码,运行两次后窗口出现错误,直接关闭。

[ 本帖最后由 一叶扁舟2014 于 2014-4-7 16:11 编辑 ]
2014-04-07 16:09
Andrew_Lee
Rank: 7Rank: 7Rank: 7
等 级:黑侠
威 望:3
帖 子:185
专家分:626
注 册:2014-3-21
收藏
得分:0 
数据出现乱码最大的可能性就是波特率设置出错。
2014-04-07 16:19
一叶扁舟2014
Rank: 1
等 级:新手上路
帖 子:8
专家分:0
注 册:2014-4-1
收藏
得分:0 
回复 7楼 Andrew_Lee
不应该吧!下位机通过串口调试助手发送数据,波特率直接设置的就是9600啊。
2014-04-07 16:33
Andrew_Lee
Rank: 7Rank: 7Rank: 7
等 级:黑侠
威 望:3
帖 子:185
专家分:626
注 册:2014-3-21
收藏
得分:0 
这可不一定,我用的都是115200,夜晚我再看看。
2014-04-07 16:50
一叶扁舟2014
Rank: 1
等 级:新手上路
帖 子:8
专家分:0
注 册:2014-4-1
收藏
得分:0 
麻烦你了,非常感谢!
2014-04-07 17:00
快速回复:用C语言编程操作计算机串口,请大神们看看这个程序该怎样修改???
数据加载中...
 
   



关于我们 | 广告合作 | 编程中国 | 清除Cookies | TOP | 手机版

编程中国 版权所有,并保留所有权利。
Powered by Discuz, Processed in 0.023171 second(s), 7 queries.
Copyright©2004-2024, BCCN.NET, All Rights Reserved