我有一个Atmel微控制器发送数据,我希望通过COM1在我的电脑上接收数据。
当我附加终端程序时,数据被正确接收(它全部是ascii,除了\ n之外都是可打印的。)
但是,我的代码似乎正在接收垃圾邮件(非ascii字符)。谁能看到我做错了什么?感谢
发送代码,仅供参考
// USART options.
static const usart_options_t USART_CONSOLE_OPTIONS =
{
.baudrate = 115200,
.charlength = 8,
.paritytype = USART_NO_PARITY,
.stopbits = USART_1_STOPBIT,
.channelmode = USART_NORMAL_CHMODE
};
接收代码
E_boolean OpenCom1(void)
{
COMMTIMEOUTS timeouts;
comPortHandle = CreateFile("COM1", // Specify port device: default "COM1"
GENERIC_READ | GENERIC_WRITE, // Specify mode that open device.
0, // the device isn't shared.
NULL, // the object gets a default security.
OPEN_EXISTING, // Specify which action to take on file.
0, // default (not overlapped i/o).
NULL); // default (hTemplate must be NULL for COM devices).
if (comPortHandle == INVALID_HANDLE_VALUE)
return False;
deviceControlBlock.DCBlength = sizeof(deviceControlBlock);
if((GetCommState(comPortHandle, &deviceControlBlock) == 0))
{
// CodeMe: do what?
return False;
}
deviceControlBlock.BaudRate = CBR_115200;
deviceControlBlock.StopBits = ONESTOPBIT;
deviceControlBlock.Parity = NOPARITY;
deviceControlBlock.ByteSize = DATABITS_8;
deviceControlBlock.fRtsControl = 0;
if (!SetCommState(comPortHandle, &deviceControlBlock))
{
// CodeMe: do what?
return False;
}
// set short timeouts on the comm port.
timeouts.ReadIntervalTimeout = MAXDWORD;
timeouts.ReadTotalTimeoutMultiplier = MAXDWORD;
timeouts.ReadTotalTimeoutConstant = 1000; // oen second
timeouts.WriteTotalTimeoutMultiplier = 1;
timeouts.WriteTotalTimeoutConstant = 1;
if (!SetCommTimeouts(comPortHandle, &timeouts))
{
// CodeMe: do what?
return False;
}
FlushFileBuffers(comPortHandle);
PurgeComm (comPortHandle, PURGE_TXABORT | PURGE_RXABORT | PURGE_TXCLEAR | PURGE_RXCLEAR);
return True;
}//OpenCom1()
// +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=
void ReadCharacterFromCom1(INPUT char *theCharacter)
{
DWORD numBytesRead;
numBytesRead = 0;
while (numBytesRead == 0)
{
ReadFile(comPortHandle, // handle of file to read
theCharacter, // store read data here
sizeof(char), // number of bytes to read
&numBytesRead, // pointer to number of bytes actually read
NULL);
}
return;
}//ReadCharacterFromCom1()
答案 0 :(得分:5)
使用“sizeof(char)”调用函数“ReadFile”,以读取要读取的字节数。这将被评估为1,可能不是您想要的值。结果是每次调用ReadCharacterFromCom1只会从端口读取1个有效字符并返回,其余的你看到的是缓冲区中留下的空白,因为缓冲区不是(手动)以null结尾。
建议您将其更改为:
/* ============================================================ */
DWORD ReadCharacterFromCom1(char *pszBuffer, int nMaxCharToRead)
{
DWORD dwBytesRead = 0;
while (dwBytesRead == 0)
{ ReadFile(comPortHandle, // handle of file to read
pszBuffer, // store read data here
nMaxCharToRead, // number of bytes to read
&dwBytesRead, // pointer to number of bytes actually read
NULL);
}
// terminate string with null
pszBuffer[dwBytesRead] = 0;
return dwBytesRead;
}
// test code ------------------------
char szBuffer[512];
DWORD dwCount = ReadCharacterFromCom1(szBuffer, sizeof(szBuffer)-1);
printf(_T("Receive %d chars: <%s>"), nCount, szBuffer);
答案 1 :(得分:2)
假设波特率,数据位数,奇偶校验和停止位数设置正确,您可能无法设置任何类型的流量控制。您没有(完全)向我们展示如何初始化DCB。
流量控制禁止发送器/接收器中的缓冲区溢出。
根据您使用的串行电缆类型以及传输的数据类型,可以使用软或硬件流量控制。
硬件流控制是首选的流控制,因为它适用于要传输的纯ASCII 和二进制数据。它需要一个完全有线的串行连接。它也被称为RTS和/或DTR流量控制。
如果您只有最小的三线RS232 / V.24电缆,您可能希望使用软件流控制(也称为Xon / Xoff握手)。 Xon / Xoff握手流控制仅适用于要传输的ASCII数据。要通过这种连接发送二进制数据,需要将其编码为纯ASCII。例如,使用base64编码来执行此操作。
如何在您可能希望阅读的窗口下设置流控制:http://www.cplusplus.com/forum/windows/89698/
此http://msdn.microsoft.com/en-us/library/ff802693.aspx可以作为参考。