OS:Windows7
环境:Visual Studio 2010 VC++ MFC Application问题:访问单片机内存,并提取数据保存。我的想法步骤是:
1.用API函数,GreateFile()来打开串口。
2.用WriteFile()来写信息,并发给单片机内存,单片机回应Version信息,用ReadFile()来读取,这样就可以证明已经连通了。
  我想先确认他是连通,不然,下面也没法进行下面操作。
3.然后,用ReadFile()来读取单片机内存的信息,并保存到PC上。第一次做硬件程序。请各位多多指教。
请指教详细正确的步骤,每步的具体实现方法。如果能有代码例子就太好了。
拜托了,急用。

解决方案 »

  1.   


    这个我了解了一下,说是用GreateFile(),WriteFile(),ReadFile()函数来实现是吧。
    我GreateFIle()连接上了。
    但是WriteFile()不知道写什么,才能给我回应。
    我试了写了一些,都没有回应,请指教。
      

  2.   

    http://download.csdn.net/source/3435268
      

  3.   

    而且串口通信不只是
    GreateFile(),WriteFile(),ReadFile()
    还有一些设置
    http://topic.csdn.net/u/20100523/18/05338e61-eb5b-49eb-80e7-ca7cfa3120bf.html这是VC串口的例子
    通信是相互的。。单片机通信的也要写啊
    这样才能用叫通信嘛
      

  4.   

    for(int i=2; i<256; i++)
    {
    char szPort[15];
    wsprintf( szPort, "COM%d", i);
    HANDLE hCom;
    hCom = CreateFile( szPort,
    GENERIC_READ | GENERIC_WRITE,
    0, 
    NULL, 
    OPEN_EXISTING,
    FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED,
    NULL );

    if(hCom == INVALID_HANDLE_VALUE)
    {
    AfxMessageBox("无效port");
    }
    else
    {
    AfxMessageBox("有效port");
    unsigned char[20];
    DWORD length=0;
    char="02h,56h,0Dh,0Ah"//STX=02h,ID=56h,CR=0Ch,LF=0Bh.
    WriteFile(hCom,ch,1,&length,NULL);

    ReadFile(hCom,ch,1,&length,NULL);
    }
    }
    目前代码是这样的,请各位多多指教。
      

  5.   

    是哪款单片机??只有串口么?现在一些单片机、DSP都带网口了。这样多机通信就更方便更强大了。
      

  6.   


    //定义
    #pragma once
    #include <Windows.h>
    #include "Defines.h"
    #include "DbConnection.h"
    #include "Comm.h"
    #include "stdafx.h"
    class Comm
    {
        private:        HANDLE m_hComm;// 串口设备句柄    public:        Comm(void);
        public:
            ~Comm(void);    public:
            BOOL OpenComm(wchar_t* pPort, int nBaudRate, int nParity, int nByteSize, int nStopBits);
            BOOL CloseComm();
            int ReadComm(void* pData, int nLength);
            int WriteComm(void* pData, int nLength);
    };
    //实现
    Comm::Comm()
    {
        m_hComm=NULL;
    }Comm::~Comm()
    {
        m_hComm=NULL;
    }// 打开串口
    // 输入: pPort - 串口名称或设备路径,可用"COM1"或"\\.\COM1"两种方式,建议用后者
    //       nBaudRate - 波特率
    //       nParity - 奇偶校验
    //       nByteSize - 数据字节宽度
    //       nStopBits - 停止位
    BOOL Comm::OpenComm(wchar_t * pPort, int nBaudRate, int nParity, int nByteSize, int nStopBits)
    {
        DCB dcb;        // 串口控制块
        COMMTIMEOUTS timeouts = {    // 串口超时控制参数
            100,                // 读字符间隔超时时间: 100 ms
            1,                    // 读操作时每字符的时间: 1 ms (n个字符总共为n ms)
            500,                // 基本的(额外的)读超时时间: 500 ms
            1,                    // 写操作时每字符的时间: 1 ms (n个字符总共为n ms)
            100};                // 基本的(额外的)写超时时间: 100 ms        m_hComm = CreateFile(pPort,    // 串口名称或设备路径
                GENERIC_READ | GENERIC_WRITE,    // 读写方式
                0,                // 共享方式:独占
                NULL,            // 默认的安全描述符
                OPEN_EXISTING,    // 创建方式
                0,                // 不需设置文件属性
                NULL);            // 不需参照模板文件        if(m_hComm == INVALID_HANDLE_VALUE) return FALSE;        // 打开串口失败        GetCommState(m_hComm, &dcb);        // 取DCB        dcb.BaudRate = nBaudRate;
            dcb.ByteSize = nByteSize;
            dcb.Parity = nParity;
            dcb.StopBits = nStopBits;        SetCommState(m_hComm, &dcb);        // 设置DCB        SetupComm(m_hComm, 4096, 1024);    // 设置输入输出缓冲区大小        SetCommTimeouts(m_hComm, &timeouts);    // 设置超时        return TRUE;
    }// 关闭串口
    BOOL Comm::CloseComm()
    {
        return CloseHandle(m_hComm);
    }// 写串口
    // 输入: pData - 待写的数据缓冲区指针
    //       nLength - 待写的数据长度
    // 返回: 实际写入的数据长度
    int Comm::WriteComm(void* pData, int nLength)
    {
        DWORD dwNumWrite;    // 串口发出的数据长度    WriteFile(m_hComm, pData, (DWORD)nLength, &dwNumWrite, NULL);    return (int)dwNumWrite;
    }// 读串口
    // 输入: pData - 待读的数据缓冲区指针
    //       nLength - 待读的最大数据长度
    // 返回: 实际读出的数据长度
    int Comm::ReadComm(void* pData, int nLength)
    {
        DWORD dwNumRead;    // 串口收到的数据长度    ReadFile(m_hComm, pData, (DWORD)nLength, &dwNumRead, NULL);    return (int)dwNumRead;
    }
      

  7.   


    看来你DCBCOM都是使用默认的参数了简单说来顺序是对了   但是很多错误处理你都没做  先都不管这些吧至少要判断一下WriteFile成功了没有,
    即使成功了也不能马上就ReadFile啊;单片机哪有这么快会给你数据啊,
    最好sleep一段时间再ReadFile
      

  8.   

    学习异步串口通信还是 最好还是看看网上到处都是的CserialPort串口类  写得还可以
    看懂了自己照自己的需求改改用就行了。
      

  9.   


    能告诉我WriteFIle()的时候,要写什么代码,
    串口才能给回复信息啊
      

  10.   


    多谢你的代码,代码我是懂了。
    但是不知道WriteFile()的时候,应该怎么写信息,串口才能回应我呢。
    我是这个地方不懂,请各位多多指教
      

  11.   

    。。
    你PC机和单片机得通信协议是什么?你想怎么通信就怎么写啊,协议都是你自己定的,别人怎么知道该怎么写呢。PC机调用WriteFile函数,从串口按协议发相关命令给单片机,单片机收到串口数据响应串口中断->进入中断响应函数按协议处理收到的数据->根据处理结果从串口回发相应数据,PC机执行ReadFile函数读取数据。
      

  12.   


    有关键字做了变量名了吗?请提示一下,多谢。
    我也想看书啊,时间紧迫啊。
    我用的是USB线连接的,Virtual COM Port通信形式。
    应该是用USB的通信协议吗?
      

  13.   


    从串口按协议发相关命令给单片机->单片机收到串口数据响应串口中断->进入中断响应函数按协议处理收到的数据->根据处理结果从串口回发相应数据WrtieFile和ReadFile中间的这些步骤,是要我编代码来实现,还是又什么别的方法实现。
    协议怎么用,高手启示我一下,推荐我几本书也行。拜托了
      

  14.   


    楼主,其实我很想帮你,应为谁都是从什么都不懂开始的。只要愿意学习就行。
    其实你问的问题本来比较简单,只是涉及到了单片机编程和PC串口通信。
    如果单片机得程序是现成的,你只需要了解单片机程序中有关实现你所需功能的串口通讯协议,然后按照协议在PC端通过串口发送报文、获取报文,完成通讯就好了。
    如果单片机得程序没有实现你所需的串口通讯功能,那么就需要你自己去编写那款单片机的串口通讯程序了。你就得仔细看看那款单片机的datasheet,设置好相关寄存器的值,让串口工作在你需要的状态(数据位,校验位,波特率等等)。然后还要设置串口的中断相关的寄存器,因为一般单片机接受串口数据通过串口中断响应来接受。之后就是实现中断响应程序,接收并处理你的PC端发过来的数据。至于具体的接收和处理方法就得看你自己是怎么定义你的通信协议的。所谓通信协议其实就是你自己定的一套通信方法。比如你定义PC向单片机发送‘0X0A’代表询问单片机是否处于活跃状态,单片机收到询问后回复‘0X0B’代表是处于活跃状态,回复‘0X0C’代表处于非活跃状态。这样一个简单的询问活跃状态的过程你就可以编程实现了。当然这只是打个比方,根据具体的功能需求,需要定制具体的完善的通信协议,很大程度上,程序的健壮信和稳定性都取决于你定制的通信协议够不够好,因为很多逻辑上的问题你都可以通过定制巧妙的协议来解决。
      

  15.   


    我问我们老师了,他说MUC方面不用设置。已经是设置好的了。
    只要我编写读写程序就直接可以读写。
    我用仪器测试了,我的代码,来写都没写进去。
    帮我看看代码吧。拜托了。BOOL Comm::OpenComm(char * pPort, int nBaudRate, int nParity, int nByteSize, int nStopBits)
    {
        DCB dcb;        // 串口控制块
         COMMTIMEOUTS timeouts = {    // 串口超时控制参数
            100,                // 读字符间隔超时时间: 100 ms
            1,                    // 读操作时每字符的时间: 1 ms (n个字符总共为n ms)
            500,                // 基本的(额外的)读超时时间: 500 ms
            1,                    // 写操作时每字符的时间: 1 ms (n个字符总共为n ms)
            100};                // 基本的(额外的)写超时时间: 100 ms        m_hComm = CreateFile(pPort,    // 串口名称或设备路径
                GENERIC_READ | GENERIC_WRITE,    // 读写方式
                0,                // 共享方式:独占
                NULL,            // 默认的安全描述符
                OPEN_EXISTING,    // 创建方式
                0,                // 不需设置文件属性
                NULL);            // 不需参照模板文件
            if(m_hComm == INVALID_HANDLE_VALUE) return FALSE;        // 打开串口失败
            GetCommState(m_hComm, &dcb);        // 取DCB        dcb.BaudRate = nBaudRate;
            dcb.ByteSize = nByteSize;
            dcb.Parity = nParity;
            dcb.StopBits = nStopBits;        SetCommState(m_hComm, &dcb);        // 设置DCB
            SetupComm(m_hComm, 4096, 1024);    // 设置输入输出缓冲区大小
            SetCommTimeouts(m_hComm, &timeouts);    // 设置超时
            return TRUE;
    }// 关闭串口
    BOOL Comm::CloseComm()
    {
        return CloseHandle(m_hComm);
    }int Comm::WriteVersion()
    {
        Comm send;
        DWORD dwNumWrite = 0;    // 串口发出的数据长度
         char senddate1[1024] = {0x02,0x56,0x20,0x20,0x0D,0x0A};
        int wLength = 6;
        WriteFile(m_hComm,senddate1, wLength, &dwNumWrite, NULL);
        return (int)dwNumWrite;
    }// 读串口
    int Comm::ReadVersion()
    {
        DWORD dwNumRead = 0;    // 串口收到的数据长度
         char readdate1[1024];
        int rLength = 35;
        ReadFile(m_hComm, readdate1, rLength, &dwNumRead, NULL);
        AfxMessageBox(readdate1);
        return (int)dwNumRead;
    }用下面函数来执行
    int check()
    {
            Comm com;
    com.OpenComm("COM5", 9600, 2, 8, 1);
    com.WriteVersion();
    com.ReadVersion();
    com.CloseComm();
    }
      

  16.   

    老师说发送
    0x02,0x56,0x20,0x20,0x0D,0x0A
    这个MCU就应该返回Version数据。
      

  17.   

    老师说发送
    0x02,0x56,0x20,0x20,0x0D,0x0A
    MCU就会返回Version数据。
    我读取这个Version数据,然后显示出来就算成功。
    帮我看看程序吧,哪里不足。
      

  18.   

    发现一个问题,谁帮我解决分就给他了。返回的Version长度是34Byte
    但是却跟着返回了13个乱码=12个乱码一个引号。
    如果我把char改成37,就是出现17个乱码=16个乱码一个引号。
    char改成35和36都不变,改成41时,就出现21个论吗=17乱码一个引号。
    下面是代码,请高手们帮忙啊int CSerial::ReadData()
    {
    if( !m_bOpened || m_hIDComDev == NULL ) return( 0 );
    BOOL bReadStatus;
    DWORD dwBytesRead = 0; 
    DWORD dwErrorFlags;
    COMSTAT ComStat;
    char buffer[34];
    int rLength = 34;
    ClearCommError( m_hIDComDev, &dwErrorFlags, &ComStat );
    if( !ComStat.cbInQue ) return( 0 );
    dwBytesRead = (DWORD) ComStat.cbInQue;
    bReadStatus = ReadFile( m_hIDComDev, buffer, rLength, &dwBytesRead, &m_OverlappedRead );
    if( !bReadStatus ){
    if( GetLastError() == ERROR_IO_PENDING ){
    WaitForSingleObject( m_OverlappedRead.hEvent, 2000 );
    return( (int) dwBytesRead );
    }
    return( 0 );
    } AfxMessageBox(buffer);
    return( (int) dwBytesRead );
    }
      

  19.   

    char buffer[34] = {0};OK??不懂是学生的话  不懂还是多问老师吧。