ziyun
驱动小牛
驱动小牛
  • 注册日期2003-07-28
  • 最后登录2009-05-31
  • 粉丝0
  • 关注0
  • 积分17分
  • 威望109点
  • 贡献值0点
  • 好评度20点
  • 原创分0分
  • 专家分0分
阅读:1593回复:9

串口编程,只用3条线,如何读取串口?

楼主#
更多 发布于:2004-08-27 13:03
我目前写程序测试串口,结果只能发送数据,而接收不到数据,请问大家,如何写接收程序?
我的串口只用了RX,TX,GND三条线,所以没有控制线,请问如何设置DCB,如何写读串口的线程?
leo_cyl
驱动牛犊
驱动牛犊
  • 注册日期2001-08-20
  • 最后登录2009-11-02
  • 粉丝0
  • 关注0
  • 积分22分
  • 威望13点
  • 贡献值0点
  • 好评度2点
  • 原创分0分
  • 专家分0分
沙发#
发布于:2004-08-27 13:08
/***********************************************************************
Module Name:
  port.c

***********************************************************************/

#include <windows.h>
#include "tty.h"

/***********************************************************************

  PortInitialize (LPTSTR lpszPortName)

***********************************************************************/
BOOL PortInitialize (LPTSTR lpszPortName)
{
  DWORD dwError,
        dwThreadID;
  DCB PortDCB;
  COMMTIMEOUTS CommTimeouts;

  // Open the serial port.
  hPort = CreateFile (lpszPortName, // Pointer to the name of the port
                      GENERIC_READ | GENERIC_WRITE,
                                    // Access (read-write) mode
                      0,            // Share mode
                      NULL,         // Pointer to the security attribute
                      OPEN_EXISTING,// How to open the serial port
                      0,            // Port attributes
                      NULL);        // Handle to port with attribute
                                    // to copy

  // If it fails to open the port, return FALSE.
  if ( hPort == INVALID_HANDLE_VALUE )
  {
    // Could not open the port.
    MessageBox (hMainWnd, TEXT("Unable to open the port"),
                TEXT("Error"), MB_OK);
    dwError = GetLastError ();
    return FALSE;
  }

  PortDCB.DCBlength = sizeof (DCB);    

  // Get the default port setting information.
  GetCommState (hPort, &PortDCB);

  // Change the DCB structure settings.
  PortDCB.BaudRate = 9600;              // Current baud
  PortDCB.fBinary = TRUE;               // Binary mode; no EOF check
  PortDCB.fParity = TRUE;               // Enable parity checking
  PortDCB.fOutxCtsFlow = FALSE;         // No CTS output flow control
  PortDCB.fOutxDsrFlow = FALSE;         // No DSR output flow control
  PortDCB.fDtrControl = DTR_CONTROL_ENABLE;
                                        // DTR flow control type
  PortDCB.fDsrSensitivity = FALSE;      // DSR sensitivity
  PortDCB.fTXContinueOnXoff = TRUE;     // XOFF continues Tx
  PortDCB.fOutX = FALSE;                // No XON/XOFF out flow control
  PortDCB.fInX = FALSE;                 // No XON/XOFF in flow control
  PortDCB.fErrorChar = FALSE;           // Disable error replacement
  PortDCB.fNull = FALSE;                // Disable null stripping
  PortDCB.fRtsControl = RTS_CONTROL_ENABLE;
                                        // RTS flow control
  PortDCB.fAbortOnError = FALSE;        // Do not abort reads/writes on
                                        // error
  PortDCB.ByteSize = 8;                 // Number of bits/byte, 4-8
  PortDCB.Parity = NOPARITY;            // 0-4=no,odd,even,mark,space
  PortDCB.StopBits = ONESTOPBIT;        // 0,1,2 = 1, 1.5, 2

  // Configure the port according to the specifications of the DCB
  // structure.
  if (!SetCommState (hPort, &PortDCB))
  {
    // Could not create the read thread.
    MessageBox (hMainWnd, TEXT("Unable to configure the serial port"),
                TEXT("Error"), MB_OK);
    dwError = GetLastError ();
    return FALSE;
  }

  // Retrieve the time-out parameters for all read and write operations
  // on the port.
  GetCommTimeouts (hPort, &CommTimeouts);

  // Change the COMMTIMEOUTS structure settings.
  CommTimeouts.ReadIntervalTimeout = MAXDWORD;  
  CommTimeouts.ReadTotalTimeoutMultiplier = 0;  
  CommTimeouts.ReadTotalTimeoutConstant = 0;    
  CommTimeouts.WriteTotalTimeoutMultiplier = 10;  
  CommTimeouts.WriteTotalTimeoutConstant = 1000;    

  // Set the time-out parameters for all read and write operations
  // on the port.
  if (!SetCommTimeouts (hPort, &CommTimeouts))
  {
    // Could not create the read thread.
    MessageBox (hMainWnd, TEXT("Unable to set the time-out parameters"),
                TEXT("Error"), MB_OK);
    dwError = GetLastError ();
    return FALSE;
  }

  // Direct the port to perform extended functions SETDTR and SETRTS
  // SETDTR: Sends the DTR (data-terminal-ready) signal.
  // SETRTS: Sends the RTS (request-to-send) signal.
  EscapeCommFunction (hPort, SETDTR);
  EscapeCommFunction (hPort, SETRTS);

  // Create a read thread for reading data from the communication port.
  if (hReadThread = CreateThread (NULL, 0, PortReadThread, 0, 0,
                                  &dwThreadID))
  {
    CloseHandle (hReadThread);
  }
  else
  {
    // Could not create the read thread.
    MessageBox (hMainWnd, TEXT("Unable to create the read thread"),
                TEXT("Error"), MB_OK);
    dwError = GetLastError ();
    return FALSE;
  }

  return TRUE;
}


/***********************************************************************

  PortWrite (BYTE Byte)

***********************************************************************/
void PortWrite (BYTE Byte)
{
  DWORD dwError,
        dwNumBytesWritten;

  if (!WriteFile (hPort,              // Port handle
                  &Byte,              // Pointer to the data to write
                  1,                  // Number of bytes to write
                  &dwNumBytesWritten, // Pointer to the number of bytes
                                      // written
                  NULL))              // Must be NULL for Windows CE
  {
    // WriteFile failed. Report error.
    dwError = GetLastError ();
  }
}



/***********************************************************************

  PortReadThread (LPVOID lpvoid)

***********************************************************************/
DWORD PortReadThread (LPVOID lpvoid)
{
  BYTE Byte;
  DWORD dwCommModemStatus,
        dwBytesTransferred;
  
  // Specify a set of events to be monitored for the port.
  SetCommMask (hPort, EV_RXCHAR | EV_CTS | EV_DSR | EV_RLSD | EV_RING);

  while (hPort != INVALID_HANDLE_VALUE)
  {
    // Wait for an event to occur for the port.
    WaitCommEvent (hPort, &dwCommModemStatus, 0);

    // Re-specify the set of events to be monitored for the port.
    SetCommMask (hPort, EV_RXCHAR | EV_CTS | EV_DSR | EV_RING);

    if (dwCommModemStatus & EV_RXCHAR)
    {
      // Loop for waiting for the data.
      do
      {
        // Read the data from the serial port.
        ReadFile (hPort, &Byte, 1, &dwBytesTransferred, 0);

        // Display the data read.
        if (dwBytesTransferred == 1)
          ProcessChar (Byte);

      } while (dwBytesTransferred == 1);
    }

    // Retrieve modem control-register values.
    GetCommModemStatus (hPort, &dwCommModemStatus);

    // Set the indicator lights.
    SetLightIndicators (dwCommModemStatus);
  }

  return 0;
}


/***********************************************************************

  PortClose (HANDLE hCommPort)

***********************************************************************/
BOOL PortClose (HANDLE hCommPort)
{
  DWORD dwError;

  if (hCommPort != INVALID_HANDLE_VALUE)
  {
    // Close the communication port.
    if (!CloseHandle (hCommPort))
    {
      dwError = GetLastError ();
      return FALSE;
    }
    else
    {
      hCommPort = INVALID_HANDLE_VALUE;
      return TRUE;
    }
  }

  return FALSE;
}

ziyun
驱动小牛
驱动小牛
  • 注册日期2003-07-28
  • 最后登录2009-05-31
  • 粉丝0
  • 关注0
  • 积分17分
  • 威望109点
  • 贡献值0点
  • 好评度20点
  • 原创分0分
  • 专家分0分
板凳#
发布于:2004-08-27 15:03
老兄,这个程序是 一旦有数据发到串口就读出来吗,我也有这个程序,可以这个WaitCommEvent (hPort, &dwCommModemStatus, 0);
事件无法触发啊?!
wxl_50685330
论坛版主
论坛版主
  • 注册日期2002-11-19
  • 最后登录2018-09-25
  • 粉丝0
  • 关注0
  • 积分1000分
  • 威望521点
  • 贡献值0点
  • 好评度419点
  • 原创分0分
  • 专家分0分
地板#
发布于:2004-08-27 15:26
这个应该是串口的中断服务触发吧
根据地的兄弟们,团结就是力量
ziyun
驱动小牛
驱动小牛
  • 注册日期2003-07-28
  • 最后登录2009-05-31
  • 粉丝0
  • 关注0
  • 积分17分
  • 威望109点
  • 贡献值0点
  • 好评度20点
  • 原创分0分
  • 专家分0分
地下室#
发布于:2004-08-27 15:48
串口的终端服务用的什么 isr??在哪儿可以看到
ziyun
驱动小牛
驱动小牛
  • 注册日期2003-07-28
  • 最后登录2009-05-31
  • 粉丝0
  • 关注0
  • 积分17分
  • 威望109点
  • 贡献值0点
  • 好评度20点
  • 原创分0分
  • 专家分0分
5楼#
发布于:2004-08-27 15:50
我想串口的中断服务应该没有问题,我用的是pxa255,mdd都是微软提供的啊!
wxl_50685330
论坛版主
论坛版主
  • 注册日期2002-11-19
  • 最后登录2018-09-25
  • 粉丝0
  • 关注0
  • 积分1000分
  • 威望521点
  • 贡献值0点
  • 好评度419点
  • 原创分0分
  • 专家分0分
6楼#
发布于:2004-08-27 16:42
isr跟平台有关,有的系统用hookinterrupt挂接,如x86;有的所有isr在一个函数OEMInterruptHandler里面,比如arm。

你说事件无法触发?Mdd应该没问题,但是触发这个事件的中断是不是需要使能?比如接受缓冲区半满中断,/cts中断等
根据地的兄弟们,团结就是力量
leo_cyl
驱动牛犊
驱动牛犊
  • 注册日期2001-08-20
  • 最后登录2009-11-02
  • 粉丝0
  • 关注0
  • 积分22分
  • 威望13点
  • 贡献值0点
  • 好评度2点
  • 原创分0分
  • 专家分0分
7楼#
发布于:2004-08-27 20:59
我的板子是pxa255的!就用上面的SAMPLE CODE 完全正常!
建议你检查RX,TX,GND三条线吧!
leo_cyl
驱动牛犊
驱动牛犊
  • 注册日期2001-08-20
  • 最后登录2009-11-02
  • 粉丝0
  • 关注0
  • 积分22分
  • 威望13点
  • 贡献值0点
  • 好评度2点
  • 原创分0分
  • 专家分0分
8楼#
发布于:2004-08-27 21:16
忘了最重要的一点。
WINCE中对串口读写有一个限制。(至少在PXA255是这样)
那就是不能一次读/写太多的数据。例如:
WriteFile (hPort,buf,100,&dwNumBytesWritten,NULL);
这样会有问题!要改成这样:

for(int k=0 ;k<100;i++)
WriteFile (hPort,buf++,1,&dwNumBytesWritten,NULL)

根据我的经验,PXA255一次只能发4个BYTE(ReadFile 也一样)。
具体的描述,请看PLATFORMT BUILD 的HELP文档。

[编辑 -  8/27/04 by  leo_cyl]

[编辑 -  8/27/04 by  leo_cyl]
ziyun
驱动小牛
驱动小牛
  • 注册日期2003-07-28
  • 最后登录2009-05-31
  • 粉丝0
  • 关注0
  • 积分17分
  • 威望109点
  • 贡献值0点
  • 好评度20点
  • 原创分0分
  • 专家分0分
9楼#
发布于:2004-08-28 18:49
这个我基本搞定了,原来是驱动的问题,我如果选择FFURAT,则收发正常,而如果用BTURAT,则能发不能收,我研究了一下,原来驱动中使用了BCR,而我的板子上是没有这个的。
游客

返回顶部