1 Star 0 Fork 0

GiteeKey/纯C语言串口

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
文件
该仓库未声明开源许可证文件(LICENSE),使用请关注具体项目描述及其代码上游依赖。
克隆/下载
com.cpp 11.58 KB
一键复制 编辑 原始数据 按行查看 历史
GiteeKey 提交于 2024-08-19 09:02 . update com.cpp.
#include <windows.h>
#include <stdio.h>
#include <chrono>
#include <thread>
#include <iostream>
#include <unistd.h>
#include <pthread.h>
#include <time.h>
#include <signal.h>
using namespace std;
#define BAUD_RATE CBR_115200
#define PORT_NAME "COM2"
#define BUFFER_SIZE 1024
char send_buffer[BUFFER_SIZE];
char send_hex[2];
unsigned int sum = 0;
uint8_t ascii_buffer[BUFFER_SIZE];
const static uint8_t bd_cmd_header[2] = "$"; /* 帧头 */
const static uint8_t bd_cmd_get_id[6] = "CCICR"; /* 获取卡号 */
const static uint8_t bd_cmd_sent[6] = "CCTCQ"; /* 发送报文 */
const static uint8_t bd_cmd_test[6] = "BDMCH"; /* 检测工况 */
const static uint8_t bd_cmd_split[1] = {0x2C}; /* 分割用逗号 */
const static uint8_t bd_dest_id[8] = "1150002"; /* 收信方ID */
const static uint8_t bd_lf_id[2] = "2"; /* 入站频点 */
const static uint8_t bd_answer[2] = "1"; /* 不需确认 */
const static uint8_t bd_encode[2] = "3"; /* 编码类别 1.内码 2.ASC 3.混编*/
const static uint8_t bd_freq[2] = "0"; /* 频度 */
const static uint8_t bd_cmd_end[2] = {0x0D, 0x0A}; /* 结尾 */
const static uint8_t bd_star[1] = {0x2A}; /* * */
uint8_t bd_cmd_sum[1] = {0x00}; /* 和校验 */
HANDLE hSerial;
/*******************************************************************
* 名称: OpenSerialPort
* 功能: 打开串口
* 参数: 串口句柄
* 返回: 串口句柄
*******************************************************************/
HANDLE OpenSerialPort(const char *portName)
{
HANDLE hSerial = CreateFileA(portName, GENERIC_READ | GENERIC_WRITE,
0, NULL, OPEN_EXISTING, 0, NULL);
if (hSerial == INVALID_HANDLE_VALUE)
{
printf("Error opening serial port: %d\n", GetLastError());
return INVALID_HANDLE_VALUE;
}
return hSerial;
}
/*******************************************************************
* 名称: closeComm
* 功能: 关闭串口
* 参数: 无
* 返回: 正确返回为ture,错误返回为false
*******************************************************************/
void CloseSerialPort()
{
if (NULL == hSerial)
return;
CloseHandle(hSerial);
hSerial = NULL;
}
/*******************************************************************
* 名称: SetupSerialPort
* 功能: 配置串口
* 参数: 串口句柄
* 返回: 正确返回为ture,错误返回为false
*******************************************************************/
BOOL SetupSerialPort(HANDLE hSerial)
{
DCB dcbSerialParams = {0};
dcbSerialParams.DCBlength = sizeof(DCB);
// 获取当前串口设置并修改
if (!GetCommState(hSerial, &dcbSerialParams))
{
printf("Error getting current serial port settings: %d\n", GetLastError());
CloseHandle(hSerial);
return FALSE;
}
// 设置波特率和其他参数
dcbSerialParams.BaudRate = BAUD_RATE;
dcbSerialParams.ByteSize = 8;
dcbSerialParams.StopBits = ONESTOPBIT;
dcbSerialParams.Parity = NOPARITY;
if (!SetCommState(hSerial, &dcbSerialParams))
{
printf("Error setting serial port parameters: %d\n", GetLastError());
CloseHandle(hSerial);
return FALSE;
}
// 设置超时参数
COMMTIMEOUTS timeouts;
timeouts.ReadIntervalTimeout = MAXDWORD;
timeouts.ReadTotalTimeoutMultiplier = 0;
timeouts.ReadTotalTimeoutConstant = 0;
timeouts.WriteTotalTimeoutMultiplier = 0;
timeouts.WriteTotalTimeoutConstant = 0;
if (!SetCommTimeouts(hSerial, &timeouts))
{
printf("Error setting timeouts: %d\n", GetLastError());
CloseHandle(hSerial);
return FALSE;
}
return TRUE;
}
/*******************************************************************
* 名称: WriteToSerialPort
* 功能: 发送数据到串口
* 参数: 串口句柄,需要发送的数据
* 返回: 正确返回为ture,错误返回为false
*******************************************************************/
BOOL WriteToSerialPort(HANDLE hSerial, const char *data)
{
DWORD bytesWritten;
if (!WriteFile(hSerial, data, strlen(data), &bytesWritten, NULL))
{
printf("Error writing to serial port: %d\n", GetLastError());
return FALSE;
}
return TRUE;
}
/*******************************************************************
* 名称: ReadFromSerialPort
* 功能: 从串口读取数据
* 参数: 串口句柄,缓存区,大小
* 返回: 正确返回为ture,错误返回为false
*******************************************************************/
BOOL ReadFromSerialPort(HANDLE hSerial, char *buffer, DWORD size)
{
DWORD bytesRead;
if (!ReadFile(hSerial, buffer, size, &bytesRead, NULL))
{
printf("Error reading from serial port: %d\n", GetLastError());
return FALSE;
}
buffer[bytesRead] = '\0'; // 添加结束符以形成字符串
return TRUE;
}
/*******************************************************************
* 名称: TimerProc
* 功能: 发送当前时间数据到串口
* 参数: 串口句柄
* 返回: 无
*******************************************************************/
VOID CALLBACK TimerProc(HANDLE hSerial)
{
if (hSerial)
{
char sendData[] = "Hello, World!";
WriteToSerialPort(hSerial, sendData);
char receiveBuffer[BUFFER_SIZE];
}
}
/*******************************************************************
* 名称: checksum
* 功能: 计算数据异或和校验
* 参数: 数据
* 返回: 异或和
*******************************************************************/
unsigned int checksum(char *str)
{
sum = 0;
if (&str[0] == "$")
{
str++;
} // 跳过第一个字符
while (*str)
{
sum ^= *str;
str++;
}
return sum;
}
/*******************************************************************
* 名称: char_to_hex
* 功能: 用于将一个字符转化为ASCII码十六进制表示
* 参数: 数据
* 返回: ASCII码十六进制
*******************************************************************/
char *char_to_hex(char *c)
{
// 创建一个长度为 3 的字符串,用于存储结果
// char* hex;
// 使用 sprintf 函数,将字符 c 的 ASCII 码转化为十六进制,并存储在 hex 中
sprintf(send_hex, "%02X", *c);
// scanf(c,"s%",hex);
// 返回 hex
return send_hex;
}
//
/*******************************************************************
* 名称: ArrayToHex
* 功能: 用于将字符串转化为十六进制表示
* 参数: 数据,长度
* 返回: 数据指针
*******************************************************************/
uint8_t *ArrayToHex(char *para, int lenth)
{
for (int i = 0; i < lenth; i++)
{
memcpy(&ascii_buffer[i * 2], char_to_hex(para + i), 2);
}
return ascii_buffer;
}
/*******************************************************************
* 名称: bd_message_sent
* 功能: 用于将北斗短报文发送到串口
* 参数: 串口句柄,数据,长度
* 返回: 无
*******************************************************************/
void bd_message_sent(HANDLE hSerial, uint8_t *param, int lenth)
{
int offset = 0;
memset(&send_buffer, 0, sizeof(send_buffer));
memcpy(send_buffer + offset, bd_cmd_header, 1);
offset += sizeof(bd_cmd_header) - 1;
memcpy(send_buffer + offset, bd_cmd_sent, 5); // 通信申请
offset += sizeof(bd_cmd_sent) - 1;
memcpy(send_buffer + offset, bd_cmd_split, 1);
offset += sizeof(bd_cmd_split);
memcpy(send_buffer + offset, bd_dest_id, sizeof(bd_dest_id)); // 收信方 ID
offset += sizeof(bd_dest_id) - 1;
memcpy(send_buffer + offset, bd_cmd_split, 1);
offset += sizeof(bd_cmd_split);
memcpy(send_buffer + offset, bd_lf_id, 1); // 频点
offset += sizeof(bd_lf_id) - 1;
memcpy(send_buffer + offset, bd_cmd_split, 1);
offset += sizeof(bd_cmd_split);
memcpy(send_buffer + offset, bd_answer, 1); // 入站确认申请
offset += sizeof(bd_answer) - 1;
memcpy(send_buffer + offset, bd_cmd_split, 1);
offset += sizeof(bd_cmd_split);
memcpy(send_buffer + offset, bd_encode, 1); // 编码类别
offset += sizeof(bd_encode) - 1;
memcpy(send_buffer + offset, bd_cmd_split, 1);
offset += sizeof(bd_cmd_split);
if (bd_encode[0] == 51)
{
memcpy(send_buffer + offset, "A4", 2); // 编码类别3时增加A4头
offset += 2;
}
memcpy(send_buffer + offset, param, lenth - 2); // 通信数据
offset += lenth - 2;
memcpy(send_buffer + offset, bd_cmd_split, 1);
offset += sizeof(bd_cmd_split);
memcpy(send_buffer + offset, bd_freq, 1); // 报文通信频度
offset += sizeof(bd_freq) - 1;
bd_cmd_sum[0] = checksum(send_buffer);
sprintf(send_hex, "%x", *bd_cmd_sum);
memcpy(send_buffer + offset, bd_star, 1);
offset += sizeof(bd_star);
memcpy(send_buffer + offset, send_hex, 2); // 校验和
offset += 2;
memcpy(send_buffer + offset, bd_cmd_end, 2); // 结尾
// rt_device_write(bd_serial, 0, send_buffer, 1024);
WriteToSerialPort(hSerial, send_buffer);
}
void CALLBACK timer_handler(HWND hwnd, UINT uMsg, UINT_PTR idEvent, DWORD dwTime)
{
printf("Timer expired!\n");
}
// 数据处理中的定时器函数
void (*data_processing_timer)(void);
// 定时器函数
void on_data_processing_timer(void)
{
printf("数据处理定时器事件发生\n");
// 执行数据处理任务
// ...
}
void handler(int signum)
{
printf("Timer expired\n");
}
int main()
{
// 读取RDSS2IC卡信息
const char *bd_read_rdss2 = "$CCICA,0,00*7B\r\n";
// 读取RDSS3IC卡信息
const char *bd_read_rdss3 = "$CCICR,0,00*68\r\n";
// 关闭所有语句
const char *bd_close_all = "$$CCRMO,,3,1*7E\r\n";
// 打开RMC,频率1秒
const char *bd_open_rmc = "$CCRMO,RMC,2,1*23\r\n";
char testchar[] = "CCRMO,RMC,2,1";
HANDLE hSerial = OpenSerialPort(PORT_NAME);
uint8_t param[] = "$GNRMC,072930.000,A,3412.169361,N,10855.447472,E,0.000,133.580,190916,1,0,52,0000,00,1,2172288,1*";
char para1[] = "$GNRMC,072930.000,A,3412.169361,N,10855.447472,E,0.000,133.580,190916,1,0,52,0000,00,1,2172288,1*21";
uint8_t *aChar = ArrayToHex(para1, sizeof(para1));
if (hSerial != INVALID_HANDLE_VALUE)
{
if (SetupSerialPort(hSerial))
{
int i = 0;
while (i < 10)
{
char time1[32];
// 使用ctime获取当前时间
std::time_t now = std::time(nullptr);
// std::cout << "当前时间:" << std::ctime(&now);
std::tm *now_tm = std::localtime(&now);
strftime(time1, 32, "SentTime:%Y.%m.%d %H:%M:%S\r\n", now_tm);
WriteToSerialPort(hSerial, time1);
WriteToSerialPort(hSerial, bd_read_rdss3);
Sleep(100);
bd_message_sent(hSerial, aChar, sizeof(para1) * 2 - 1);
char receiveBuffer[BUFFER_SIZE];
ReadFromSerialPort(hSerial, receiveBuffer, BUFFER_SIZE);
printf("Received: %s%s\n", receiveBuffer, std::ctime(&now));
Sleep(1000);
i++;
}
CloseHandle(hSerial);
}
}
exit(NULL);
return 0;
}
马建仓 AI 助手
尝试更多
代码解读
代码找茬
代码优化
1
https://gitee.com/coonoo/c-language-serial-port.git
git@gitee.com:coonoo/c-language-serial-port.git
coonoo
c-language-serial-port
纯C语言串口
master

搜索帮助

0d507c66 1850385 C8b1a773 1850385