使用C语言编程实现COM口数据的收发

#include <stdio.h>  
#include <windows.h>
#include   <stdlib.h>
#include <string.h>  
#include <conio.h>  
#include <winnt.h>  

int main()
{
DWORD dwLength;
char recvBuf[1024];
DWORD dwactlen;
char psendbuf[32] = "test\n";
char ch;
DCB myDCB;
HANDLE m_hComm;
m_hComm = CreateFile(
"COM4:",
GENERIC_READ | GENERIC_WRITE,   //允许读和写  
0,                          //独占方式(共享模式)  
NULL,
OPEN_EXISTING,              //打开而不是创建(创建方式)  
0,
NULL
);
if (m_hComm == (HANDLE)-1)                          //打开串口失败返回  
{
printf("打开串口失败");
return 0;
}
//得到打开串口的当前属性参数,修改后再重新设置串口。  


if (!GetCommState(m_hComm, &myDCB))
{
printf("GetCommState error");
return FALSE;
}


//设置串口参数  
myDCB.BaudRate = CBR_9600;   // 设置波特率9600  
myDCB.fBinary = TRUE; // 设置二进制模式,此处必须设置TRUE  
myDCB.fParity = TRUE; // 支持奇偶校验  
myDCB.fOutxCtsFlow = FALSE;  // No CTS output flow control  
myDCB.fOutxDsrFlow = FALSE;  // No DSR output flow control  
myDCB.fDtrControl = DTR_CONTROL_DISABLE; // No DTR flow control  
myDCB.fDsrSensitivity = FALSE; // DSR sensitivity  
myDCB.fTXContinueOnXoff = TRUE; // XOFF continues Tx  
myDCB.fOutX = FALSE;     // No XON/XOFF out flow control  
myDCB.fInX = FALSE;        // No XON/XOFF in flow control  
myDCB.fErrorChar = FALSE;    // Disable error replacement  
myDCB.fNull = FALSE;  // Disable null stripping  
myDCB.fRtsControl = RTS_CONTROL_DISABLE;   //No RTS flow control  
myDCB.fAbortOnError = FALSE;  // 当串口发生错误,并不终止串口读写  
myDCB.ByteSize = 8;   // 数据位,范围:4-8  
myDCB.Parity = NOPARITY; // 校验模式  
myDCB.StopBits = 0;   // 1位停止位  
//设置串口参数  
if (!SetCommState(m_hComm, &myDCB))
{
printf("SetCommState error");
return FALSE;
}
SetupComm(m_hComm, 1024, 1024);//设置串口的输入/输出缓冲区大小
PurgeComm(m_hComm, PURGE_RXCLEAR | PURGE_TXCLEAR);
COMMTIMEOUTS TimeOuts;
//设定读超时
TimeOuts.ReadIntervalTimeout = 1000;
TimeOuts.ReadTotalTimeoutMultiplier = 500;
TimeOuts.ReadTotalTimeoutConstant = 5000;
//设定写超时
TimeOuts.WriteTotalTimeoutMultiplier = 500;
TimeOuts.WriteTotalTimeoutConstant = 2000;
SetCommTimeouts(m_hComm, &TimeOuts); //设置超时 !mportant


//ClearCommError(m_hComm, &dwReadErrors, &cmState);
//printf("Input a character:");
//ch = _getch();
//printf("\nYou input a '%c'\n", ch);
//psendbuf[0] = ch;


while (1)
{
WriteFile(m_hComm, psendbuf, 32, &dwactlen, NULL);
ReadFile(m_hComm, recvBuf, 10, &dwLength, NULL);
printf("read success!\nread string: %s", recvBuf);
PurgeComm(m_hComm, PURGE_RXCLEAR | PURGE_TXCLEAR);
}

/*WriteFile(m_hComm, psendbuf,32, &dwactlen, NULL);
if (WriteFile(m_hComm, psendbuf, 32, &dwactlen, NULL))
{
printf("write success!\n");
}
else
{
printf("write failed!\n");
}


if (ReadFile(m_hComm, recvBuf, 10, &dwLength, NULL))
{
printf("read success!\nread string: %s", recvBuf);
}
else
{
printf("read failed!\n");
}*/
CloseHandle(m_hComm); //m_hComm是CreateFile函数返回的串口句柄。  
return 0;

}

该程序在vs2013中能运行,能进行简单的读写操作,尚待进一步完善。调试过程中可能遇到的问题及解决办法如下:

问题一:

IntelliSense: "const char *" 类型的实参与 "LPCTSTR" 类型的形参不兼容 (vs2010)
例如:
MessageBox(szNameList,"人员");
 
改为:MessageBox(szNameList,_T("人员"));
原因:
unicode字符问题。2010工程默认是宽字符版本

解决方法:
菜单 项目 -> 属性 (打开属性页) -> 配置属性 -> 常规 -> 字符集  
单前选中的应该是“使用Unicode字符集”,改为“使用多字节字符集”*/

问题二:

1>d:\code\20130925\20130925\stdafx.cpp(18): error C4996: 'fopen': This function or variable may be unsafe. Consider using fopen_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details.
1>          d:\vs2012\vc\include\stdio.h(218) : 参见“fopen”的声明
1>  20130925.cpp
1>  正在生成代码...
========== 生成: 成功 0 个,失败 1 个,最新 0 个,跳过 0 个 ==========
 
解决方案,项目 =》属性 =》c/c++  =》预处理器=》点击预处理器定义,编辑,加入_CRT_SECURE_NO_WARNINGS,即可。*/

还遇到一个比较有意思的程序(转载),可以进行读取操作:

#include <stdio.h>  
#include <windows.h>  
int main(void)
{
FILE *fp;
char temp;
char buf[100];
if ((fp = fopen("com4", "r")) == NULL) puts("Can't open com3 /n");
while (1)
{
temp = 0;
fscanf(fp, "%c", &temp);
if (temp != 0)
putchar(temp);
else
Sleep(100);
}
fclose(fp);
return 0;
}

  • 0
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
下面是使用 Keil4 和 C 语言实现 51 单片机使用计数器0实现收发数据的示例代码: ```c #include <reg51.h> #define FOSC 11059200L // 单片机时钟频率 #define BAUD 9600 // 串波特率 #define TIMER_TICK (65536 - FOSC / 12 / BAUD) // 计数器初值 sbit LED = P1^0; // 用于测试串收发的 LED 灯 sbit TXD = P3^1; // 串发送引脚 sbit RXD = P3^0; // 串接收引脚 unsigned char TX_buffer[32]; // 发送缓冲区 unsigned char RX_buffer[32]; // 接收缓冲区 unsigned char TX_index = 0; // 发送缓冲区索引 unsigned char RX_index = 0; // 接收缓冲区索引 bit TX_busy = 0; // 发送忙标志位 bit RX_complete = 0; // 接收完成标志位 void UART_init() // 串初始化函数 { TMOD &= 0xF0; // 清除计数器0模式位 TMOD |= 0x02; // 设置计数器0为模式1 TH0 = TIMER_TICK / 256; // 设置计数器0初值高位 TL0 = TIMER_TICK % 256; // 设置计数器0初值低位 TR0 = 1; // 启动计数器0 SM0 = 0; // 串工作在模式1 SM1 = 1; // 串工作在模式1 REN = 1; // 允许串接收 EA = 1; // 允许中断 ES = 1; // 允许串中断 } void UART_send(unsigned char dat) // 串发送函数 { while (TX_busy); // 等待前一次发送完成 TX_busy = 1; // 标记为发送忙 SBUF = dat; // 发送数据 } void UART_putc(unsigned char dat) // 串发送单个字符 { TX_buffer[TX_index++] = dat; if (TX_index >= 32) TX_index = 0; // 缓冲区溢出则重置索引 } void UART_puts(unsigned char *str) // 串发送字符串 { while (*str != '\0') { UART_putc(*str++); } } void UART_recv() interrupt 4 using 1 // 串接收中断服务程序 { if (RI) { // 接收中断 RI = 0; // 清除接收中断标志位 RX_buffer[RX_index++] = SBUF; // 保存接收数据 if (RX_index >= 32) RX_index = 0; // 缓冲区溢出则重置索引 if (RX_index == 1) { RX_complete = 1; // 标记为接收完成 } } if (TI) { // 发送中断 TI = 0; // 清除发送中断标志位 TX_busy = 0; // 标记为发送空闲 if (TX_index > 0) { SBUF = TX_buffer[0]; for (unsigned char i = 0; i < TX_index; i++) { TX_buffer[i] = TX_buffer[i+1]; } TX_index--; TX_busy = 1; // 标记为发送忙 } } } void main() { UART_init(); while (1) { if (RX_complete) { RX_complete = 0; LED = ~LED; // 翻转 LED 灯 UART_puts(RX_buffer); } } } ``` 注:以上代码仅供参考,具体实现还需要根据具体的硬件平台和编程语言进行调整。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值