如何向串口发送数据,并接收串口发来的数据

Jason_88_ 2013-12-06 04:38:39
#include <stdio.h>
#include <iostream>
#include <afxwin.h>
#include <windows.h>

HANDLE hCom = NULL;//全局变量,串口句柄

class BP{
public:
void Set_Init_pressure_OnSend(void); //主机向血压板发送数据
void Set_Init_pressure_OnReceive(void); //血压板返回给主机数据
void Set_Init_pressure_OnClose(void); //关闭串口
private:
int str[100];
DWORD dwErrorFlags;
COMSTAT ComStat;
BOOL bWriteStat;
BOOL bReadStat;
};
//主机向血压板发送数据
void BP::Set_Init_pressure_OnSend(void)
{
int lpOutBuffer[11];
memset(lpOutBuffer, '\0', sizeof(int)*11); //把前五个字符先清零
lpOutBuffer[0] = 0x55; //发送缓冲区的第一个字节为3A
lpOutBuffer[1] = 0x12; //发送缓冲区的第二个字节为17
lpOutBuffer[2] = 0x01; //发送缓冲区的第三个字节为B4
lpOutBuffer[3] = 0x00; //发送缓冲区的第四个字节为00
lpOutBuffer[4] = 0x00; //发送缓冲区的第五个字节为F8
lpOutBuffer[5] = 0x00; //发送缓冲区的第五个字节为F8
lpOutBuffer[6] = 0x00; //发送缓冲区的第五个字节为F8
lpOutBuffer[7] = 0x00; //发送缓冲区的第五个字节为F8
lpOutBuffer[8] = 0x00; //发送缓冲区的第五个字节为F8
lpOutBuffer[9] = 0xAA; //发送缓冲区的第五个字节为F8
lpOutBuffer[10] = '\0'; //发送缓冲区的第五个字节为F8

printf("发送数据 : ");
for(int i=0; i<10; i++){
printf("%x ", lpOutBuffer[i]);
}
printf("\n");
//55 12 01 00 00 00 00 00 00 aa
DWORD dwBytesWrite = 11;
ClearCommError(hCom, &dwErrorFlags, &ComStat);//返回串口错误和报告(也可以查看缓冲区状态)
bWriteStat = WriteFile(hCom, lpOutBuffer, dwBytesWrite, &dwBytesWrite, NULL);
if(!bWriteStat)
{
printf("写串口失败!\n");
}
printf("写串口成功!\n");
printf("\n");
}
//血压板返回给主机数据
void BP::Set_Init_pressure_OnReceive(void)
{
memset(str, '\0', 100);
DWORD wCount = 100;
bReadStat = ReadFile(hCom, str, wCount, &wCount, NULL);
if(!bReadStat){
printf("读串口失败!");
}
printf("读串口成功!\n");
// m_disp = str;
// UpdateData(FALSE);
printf("接收数据 : %x \n", str);
PurgeComm(hCom, PURGE_TXABORT|PURGE_RXABORT|PURGE_TXCLEAR|PURGE_RXCLEAR);//清空缓冲区
}
//关闭串口
void BP::Set_Init_pressure_OnClose(void){
CloseHandle(hCom);
}
int main(void)
{
BP bp;
//打开串口
if (hCom != NULL)
{
CloseHandle(hCom);
hCom = NULL;
}
hCom = CreateFile("COM4", //COM1口
GENERIC_READ|GENERIC_WRITE, //允许读和写
0, //独占方式
NULL,
OPEN_EXISTING, //设置产生方式
NULL, // 我们准备使用异步通信0, //同步方式
NULL);
if(hCom == (HANDLE)-1)
{
printf("打开COM失败!\n");
return FALSE;
}
printf("打开COM成功!\n");
//SetupComm设置串口输入输出缓冲区大小
SetupComm(hCom,1024,1024); //输入缓冲区和输出缓冲区的大小都是1024

COMMTIMEOUTS TimeOuts;
//设定读超时
TimeOuts.ReadIntervalTimeout = 100;
TimeOuts.ReadTotalTimeoutMultiplier = 100;
TimeOuts.ReadTotalTimeoutConstant = 100;
//设定写超时
TimeOuts.WriteTotalTimeoutMultiplier = 1000;
TimeOuts.WriteTotalTimeoutConstant = 1000;
printf("定时器设置成功!\n");
SetCommTimeouts(hCom, &TimeOuts); //用COMMTIMEOUTS结构体某个内容设置超时

DCB dcb;
GetCommState(hCom,&dcb); //获取串口的初始配置(获得COM口的设备控制块,获得相关参数)
dcb.BaudRate = 9600; //波特率为9600
dcb.ByteSize = 8; //每个字节有8位
dcb.Parity = NOPARITY; //无奇偶校验位
dcb.StopBits = TWOSTOPBITS; //两个停止位
SetCommState(hCom,&dcb); //设置串口(设置COM口的设备控制块)
//PurgeComm清空缓冲区
PurgeComm(hCom,PURGE_TXCLEAR|PURGE_RXCLEAR);//清空缓冲区中断所以写操作并立即返回,即使写操作还没有完成。
printf("端口设置成功!\n");

bp.Set_Init_pressure_OnSend(); //主机向血压板发送数据
bp.Set_Init_pressure_OnReceive(); //血压板返回给主机数据
bp.Set_Init_pressure_OnClose(); //关闭串口

return 0;
}
...全文
11152 20 打赏 收藏 转发到动态 举报
写回复
用AI写文章
20 条回复
切换为时间正序
请发表友善的回复…
发表回复
Pillar_csdn 2015-07-23
  • 打赏
  • 举报
回复
大神能不能给我分享一下你的源代码?
Jason_88_ 2013-12-12
  • 打赏
  • 举报
回复
引用 17 楼 woshi_hujunjun 的回复:
看看 SetCommState 的返回值对吗
SetCommState 返回值对
woshi_hujunjun 2013-12-11
  • 打赏
  • 举报
回复
看看 SetCommState 的返回值对吗
Jason_88_ 2013-12-11
  • 打赏
  • 举报
回复
引用 15 楼 allenemo 的回复:
BOOL CxComm::Send(LPBYTE lpbtData, DWORD dwSize) { if (m_hComm == NULL) return FALSE; DWORD dwWritten = 0, dwToWrite, dwRet; BOOL bRet; OVERLAPPED o = {0}; char szEvent[MAX_EVENT]; sprintf(szEvent, "%d.%d.%d.Send", GetTickCount(), (DWORD)this, m_hComm); // asynchronous while (dwWritten != dwSize) { dwToWrite = dwSize - dwWritten; o.hEvent = CreateEvent(NULL, TRUE, FALSE, szEvent); bRet = WriteFile(m_hComm, &lpbtData[dwWritten], dwToWrite, NULL, &o); if (!bRet) { dwRet = GetLastError(); if (ERROR_IO_PENDING == dwRet) WaitForSingleObject(o.hEvent, INFINITE); } CloseHandle(o.hEvent); dwWritten += o.InternalHigh; } return TRUE; } 注意看这个函数。 注意这个变量的使用:OVERLAPPED o; 注意异步写串口的返回处理: bRet = WriteFile(m_hComm, &lpbtData[dwWritten], dwToWrite, NULL, &o); if (!bRet) { dwRet = GetLastError(); if (ERROR_IO_PENDING == dwRet) WaitForSingleObject(o.hEvent, INFINITE); }
问题大体上是解决了,只是发送十六进制数的时候发送不过去,WriteFile返回的总是0
Jason_88_ 2013-12-09
  • 打赏
  • 举报
回复
引用 3 楼 hdg3707 的回复:
bp.Set_Init_pressure_OnSend(); //主机向血压板发送数据 延点时,因为板子可能还没处理完你就开始接收,然后超时退出 bp.Set_Init_pressure_OnReceive(); //血压板返回给主机数据
数据发送不到串口,板子根本就接不到数据
Jason_88_ 2013-12-09
  • 打赏
  • 举报
回复
引用 11 楼 allenemo 的回复:
异步写 WriteFile 多数情况下是返回 FALSE,因为它只是把数据放入缓冲区就返回了,至于串口有没有把数据发出去,多数情况下是需要一定时间的。 建议你参考下文: http://www.cnblogs.com/EdmundDwyane/p/3161524.html http://www.cnblogs.com/EdmundDwyane/p/3174308.html 同时建议你使用一下串口调试工具: http://www.cnblogs.com/EdmundDwyane/p/3443074.html
这个我没看太懂 麻烦你能帮我看看我的代码吗 谢谢
Jason_88_ 2013-12-09
  • 打赏
  • 举报
回复
2脚和3脚 短接,发送的数据和接收到的数据不一样,结果和之前出现的状况是一样的
camphor 2013-12-09
  • 打赏
  • 举报
回复
bWriteStat = WriteFile(hCom, lpOutBuffer, dwBytesWrite, &dwBytesWrite, NULL); lpOutBuffer的大小不是11,lpOutBuffer的类型最好改一下,BYTE[] 或char[]。查一下发送的缓存里的数据
阿先森 2013-12-09
  • 打赏
  • 举报
回复
BOOL CxComm::Send(LPBYTE lpbtData, DWORD dwSize) { if (m_hComm == NULL) return FALSE; DWORD dwWritten = 0, dwToWrite, dwRet; BOOL bRet; OVERLAPPED o = {0}; char szEvent[MAX_EVENT]; sprintf(szEvent, "%d.%d.%d.Send", GetTickCount(), (DWORD)this, m_hComm); // asynchronous while (dwWritten != dwSize) { dwToWrite = dwSize - dwWritten; o.hEvent = CreateEvent(NULL, TRUE, FALSE, szEvent); bRet = WriteFile(m_hComm, &lpbtData[dwWritten], dwToWrite, NULL, &o); if (!bRet) { dwRet = GetLastError(); if (ERROR_IO_PENDING == dwRet) WaitForSingleObject(o.hEvent, INFINITE); } CloseHandle(o.hEvent); dwWritten += o.InternalHigh; } return TRUE; } 注意看这个函数。 注意这个变量的使用:OVERLAPPED o; 注意异步写串口的返回处理: bRet = WriteFile(m_hComm, &lpbtData[dwWritten], dwToWrite, NULL, &o); if (!bRet) { dwRet = GetLastError(); if (ERROR_IO_PENDING == dwRet) WaitForSingleObject(o.hEvent, INFINITE); }
阿先森 2013-12-08
  • 打赏
  • 举报
回复
异步写 WriteFile 多数情况下是返回 FALSE,因为它只是把数据放入缓冲区就返回了,至于串口有没有把数据发出去,多数情况下是需要一定时间的。 建议你参考下文: http://www.cnblogs.com/EdmundDwyane/p/3161524.html http://www.cnblogs.com/EdmundDwyane/p/3174308.html 同时建议你使用一下串口调试工具: http://www.cnblogs.com/EdmundDwyane/p/3443074.html
hdg3707 2013-12-08
  • 打赏
  • 举报
回复
你把串口的2脚和3脚短接(不接板子),这样,你发什么就接收什么,看看对不对
Jason_88_ 2013-12-07
  • 打赏
  • 举报
回复
哪位大神帮帮忙吧!
Jason_88_ 2013-12-07
  • 打赏
  • 举报
回复
板子没有问题,用调试助手看过了
向立天 2013-12-07
  • 打赏
  • 举报
回复
引用 5 楼 u011572082 的回复:
板子那边不通电 和 板子通电 返回的数据是一样的, 应该只是操作了串口,数据到串口那就直接返回了
不会是你的板子出问题了吧 用串口助手分别调试一下你的程序和板子看看
Jason_88_ 2013-12-07
  • 打赏
  • 举报
回复
发送55 12 01 00 00 00 00 00 00 aa 串口返回的数据是 12fd90 每次都这样
Jason_88_ 2013-12-07
  • 打赏
  • 举报
回复
板子那边不通电 和 板子通电 返回的数据是一样的, 应该只是操作了串口,数据到串口那就直接返回了
Jason_88_ 2013-12-07
  • 打赏
  • 举报
回复
写延时已经设置够大了,还是不行 只能打开串口 根本就写不到板子里去
hdg3707 2013-12-07
  • 打赏
  • 举报
回复
bp.Set_Init_pressure_OnSend(); //主机向血压板发送数据 延点时,因为板子可能还没处理完你就开始接收,然后超时退出 bp.Set_Init_pressure_OnReceive(); //血压板返回给主机数据
Jason_88_ 2013-12-06
  • 打赏
  • 举报
回复
编译 运行都没有问题,只是数据发送不过去
Jason_88_ 2013-12-06
  • 打赏
  • 举报
回复
给板子发送数据时有问题,麻烦哪位大神帮帮忙吧!

2,640

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC 硬件/系统
社区管理员
  • 硬件/系统社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧