VS2015+Win32API串口通信函数与Arduino通信
程序员文章站
2022-06-29 23:43:38
...
实现上位机与Arduino板子的串口通信,读写均可,上位机用VS2015实现,Arduino型号是mega2560,亲测可用。有问题可以写在评论区,看到都会回复,这是我的第一篇分享博客,如果对你有用的话,请点个赞吧~
VS2015新建Win32控制台项目,只需要额外添加一个源文件即可。代码如下
// ConsoleSerial.cpp : 定义控制台应用程序的入口点。
//
#include "stdafx.h"
#include "windows.h"
#include <stdio.h>
#include <conio.h>
#include <math.h>
#include<fstream>
#include<iostream>
using namespace std;
HANDLE hDevice = CreateFile(L"\\\\.\\COM4", //注意COM1~COM10与COM10以上的窗口的命名规则
GENERIC_READ | GENERIC_WRITE, //使用读写方式
0,
0,
OPEN_EXISTING,
0,
0);
BOOL Serial_open()
{
SetupComm(hDevice, 1024, 1024); //输入缓冲区和输出缓冲区的大小都是1024
COMMTIMEOUTS TimeOuts;
TimeOuts.ReadIntervalTimeout = 1000;
TimeOuts.ReadTotalTimeoutMultiplier = 500;
TimeOuts.ReadTotalTimeoutConstant = 5000;
//设定写超时
TimeOuts.WriteTotalTimeoutMultiplier = 500;
TimeOuts.WriteTotalTimeoutConstant = 2000;
SetCommTimeouts(hDevice, &TimeOuts);
DCB lpTest;
GetCommState(hDevice, &lpTest); //获取当前的参数设置
lpTest.BaudRate = CBR_9600; //设置波特率
lpTest.ByteSize = 8; //数据位数为8
lpTest.Parity = NOPARITY; //无校验
lpTest.StopBits = ONESTOPBIT; //1位停止位
SetCommState(hDevice, &lpTest); //设置通信参数
PurgeComm(hDevice, PURGE_TXCLEAR | PURGE_RXCLEAR);
return true;
}
int Serial_read(char str[], int size) //同步读串口
{
DWORD rCount=0; //读取的字节数
BOOL bReadStat;
while(rCount<6)
bReadStat = ReadFile(hDevice, str, size, &rCount, NULL);
printf("read_success\n");
if (!bReadStat)
{
printf("读串口失败!\n");
return FALSE;
}
return rCount;
}
BOOL Serial_write(char test[])
{
DWORD btsIO;
char a=0;
while (true)
{
a++;
WriteFile(hDevice,test , strlen(test), &btsIO, NULL); //发送数据
Sleep(2000);
if (a == 3)
break;
}
PurgeComm(hDevice, PURGE_TXCLEAR | PURGE_RXCLEAR);
return true;
}
int _tmain(int argc, _TCHAR* argv[])
{
char test[] = "1"; //点亮
char test2[] = "0";
char for_read[100];
int len;
double value=0;
int input;
if (hDevice != INVALID_HANDLE_VALUE)
{
Serial_open();
printf("Port opened!\n");
Sleep(500);
Serial_write(test);
printf("write_success\n");
while (1)
{
printf("开始读\n");
len = Serial_read(for_read, 100);
PurgeComm(hDevice, PURGE_TXCLEAR | PURGE_RXCLEAR);
value = 0;
if (len)
{
printf("len=%d\n", len);
for (size_t j = 0; j<len; j++)
{
printf("read %d\n", for_read[j] - 1);
value = value + (for_read[j] - 1)*pow(10, j);
}
printf("value=%f\n", value);
}
ofstream out("D:\\data.txt");
out << value;
out.close();
Sleep(500);
//Serial_write(test);
ifstream in("D:\\输入.txt");
in >> input;
printf("input=%d\n", input);
if (input)
{
Serial_write(test);
printf("write test success\n");
}
else
{
Serial_write(test2);
printf("write test2 success\n");
}
in.close();
}
CloseHandle(hDevice); //关闭串口
}
system("pause");
return 0;
}
Serial_open()函数实现打开串口,并配置一些串口参数。
Serial_read()函数实现读取串口,代码中会将串口读到的数据位数len,每一位的数值和所有位拼在一起组成的数字的值value显示出来。并将value值实时保存在D盘的data.txt文件中。
Serial_write()函数实现写串口,代码会将D盘的输入.txt文件中的数值赋给input变量,并根据它的值来写串口。
这是一个实时更新的系统,读写操作都在循环中进行。
Arduino端的代码如下:
char buff2[6]={1,1,1,2,4,6};
char a=0;
int i;
int data=4911;
int data2=4911;
void setup() {
// put your setup code here, to run once:
Serial.begin(9600);
pinMode(13, OUTPUT);
for(i=5;i>=0;i--)
{
buff2[i]=(data%10)+1;
data=data/10;
Serial.write(buff2[i]);
}
}
void loop() {
delay(10000);//每10s发送一次数据
// put your main code here, to run repeatedly:
data2++;
data=data2;
if(data>14911)//这个14911是随便设的
{data=0;
data2=0;
}
for(i=5;i>=0;i--)
{
buff2[i]=(data%10)+1;
data=data/10;
Serial.write(buff2[i]);
//delay(100);
}
while(Serial.available())
{
a=Serial.read();
}
if(a=='1')
digitalWrite(13, HIGH);
if(a=='0')
digitalWrite(13,LOW);
}
Arduino每10s给上位机传一个data值,并且逐次加1,同时单片机会根据上位机传给自己的值对led灯进行点亮或者熄灭操作。
要注意的问题:
1. 当Arduino板子刚接到电脑上时,运行VS程序,虽然提示串口会打开,但是读写操作均不能进行,原因我没找到,但是先打开串口助手软件,将连接单片机的串口手动打开可以解决这个问题,我也不知道为什么,菜鸡哭了。
其他问题暂时没想到,想到会补充。
上一篇: python -socket通信
下一篇: Python之Socket通信