在简单串口协议实验基础上进行改进,完善上位机功能,功能尽可能地丰富,给出完整的C代码,并给出解释
时间: 2023-12-20 07:06:34 浏览: 81
好的,我们可以基于简单串口协议实验,添加更多功能来完善上位机的功能。下面给出完整的C代码,并对其中的主要功能进行解释。
```c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdbool.h>
#include <windows.h>
#define CMD_LED_ON "LED_ON" // 控制LED开启
#define CMD_LED_OFF "LED_OFF" // 控制LED关闭
#define CMD_READ_ADC "READ_ADC" // 读取ADC值
// 定义串口句柄
HANDLE hSerial;
// 打开串口
bool openSerialPort(char* portName)
{
hSerial = CreateFile(portName,
GENERIC_READ | GENERIC_WRITE,
0,
NULL,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL,
NULL);
if (hSerial == INVALID_HANDLE_VALUE) {
printf("Failed to open serial port!\n");
return false;
}
DCB dcbSerialParams = { 0 };
dcbSerialParams.DCBlength = sizeof(dcbSerialParams);
if (!GetCommState(hSerial, &dcbSerialParams)) {
printf("Failed to get current serial parameters!\n");
return false;
}
dcbSerialParams.BaudRate = CBR_115200;
dcbSerialParams.ByteSize = 8;
dcbSerialParams.StopBits = ONESTOPBIT;
dcbSerialParams.Parity = NOPARITY;
if (!SetCommState(hSerial, &dcbSerialParams)) {
printf("Failed to set new serial parameters!\n");
return false;
}
COMMTIMEOUTS timeouts = { 0 };
timeouts.ReadIntervalTimeout = 50;
timeouts.ReadTotalTimeoutConstant = 50;
timeouts.ReadTotalTimeoutMultiplier = 10;
timeouts.WriteTotalTimeoutConstant = 50;
timeouts.WriteTotalTimeoutMultiplier = 10;
if (!SetCommTimeouts(hSerial, &timeouts)) {
printf("Failed to set new timeouts!\n");
return false;
}
return true;
}
// 关闭串口
void closeSerialPort()
{
CloseHandle(hSerial);
}
// 读取串口数据
bool readSerialData(char* buffer, int bufferSize)
{
DWORD bytesRead;
if (!ReadFile(hSerial, buffer, bufferSize, &bytesRead, NULL)) {
printf("Failed to read serial data!\n");
return false;
}
return true;
}
// 写入串口数据
bool writeSerialData(char* buffer, int bufferSize)
{
DWORD bytesSent;
if (!WriteFile(hSerial, buffer, bufferSize, &bytesSent, NULL)) {
printf("Failed to write serial data!\n");
return false;
}
return true;
}
// 控制LED开启
bool turnOnLED()
{
char buffer[100];
sprintf(buffer, "%s\n", CMD_LED_ON);
if (!writeSerialData(buffer, strlen(buffer))) {
return false;
}
return true;
}
// 控制LED关闭
bool turnOffLED()
{
char buffer[100];
sprintf(buffer, "%s\n", CMD_LED_OFF);
if (!writeSerialData(buffer, strlen(buffer))) {
return false;
}
return true;
}
// 读取ADC值
float readADC()
{
char buffer[100];
char response[100];
sprintf(buffer, "%s\n", CMD_READ_ADC);
if (!writeSerialData(buffer, strlen(buffer))) {
return -1;
}
if (!readSerialData(response, sizeof(response))) {
return -1;
}
return strtof(response, NULL);
}
// 主函数
int main()
{
if (!openSerialPort("COM3")) {
return -1;
}
// 控制LED开关
turnOnLED();
Sleep(1000);
turnOffLED();
Sleep(1000);
// 读取ADC值并输出
float adcValue = readADC();
printf("ADC Value: %.2f\n", adcValue);
closeSerialPort();
return 0;
}
```
在这个代码中,我们添加了三个功能:
1. 控制LED开启和关闭。我们定义了两个命令 `CMD_LED_ON` 和 `CMD_LED_OFF`,分别用于控制LED开启和关闭。在 `turnOnLED()` 和 `turnOffLED()` 函数中,我们向串口写入相应的命令,然后通过 `writeSerialData()` 函数将命令发送出去。
2. 读取ADC值。我们定义了一个命令 `CMD_READ_ADC`,用于读取ADC值。在 `readADC()` 函数中,我们向串口写入相应的命令,并通过 `writeSerialData()` 函数将命令发送出去。然后通过 `readSerialData()` 函数读取从串口返回的数据,并将其转换成浮点数类型的ADC值。
这些功能可以通过在主函数中调用相应的函数来使用。在我们的示例代码中,我们控制LED开启和关闭,并读取ADC值并输出。你可以根据自己的需求添加更多的功能。
阅读全文