当前位置: 首页 > news >正文

个人网站注册费用微信小程序免费制作平台

个人网站注册费用,微信小程序免费制作平台,wordpress进不去,服装图案素材网站文章目录 1 串口编程基本步骤1.1 打开串口1.2 配置串口 1.3 读串口1.4 发送串口1.5 关闭串口 2 综合使用3 如何在软件上保证串口稳定通信4 flythings中的串口通讯5 协议接收部分使用和修改方法6 通讯协议数据怎么和UI控件对接 1 串口编程基本步骤 串口通信有5个步骤 1.打开串口…

文章目录

  • 1 串口编程基本步骤
    • 1.1 打开串口
      • 1.2 配置串口
    • 1.3 读串口
    • 1.4 发送串口
    • 1.5 关闭串口
  • 2 综合使用
  • 3 如何在软件上保证串口稳定通信
  • 4 flythings中的串口通讯
  • 5 协议接收部分使用和修改方法
  • 6 通讯协议数据怎么和UI控件对接


1 串口编程基本步骤

串口通信有5个步骤
1.打开串口
2.配置串口
3.读串口
4.写串口
5.关闭串口

1.1 打开串口

#include <fcntl.h>int fd = open("/dev/ttyS0", O_RDWR | O_NOCTTY);

open是linux系统函数,open成功,返回0,失败返回1。/dev/ttys0可以理解为串口号,类似于windows系统上的com1,

1.2 配置串口

int openUart() {int fd = open("/dev/ttyS0", O_RDWR | O_NOCTTY);struct termios oldtio = { 0 };struct termios newtio = { 0 };tcgetattr(fd, &oldtio);//设置波特率为115200newtio.c_cflag = B115200 | CS8 | CLOCAL | CREAD;newtio.c_iflag = 0; // IGNPAR | ICRNLnewtio.c_oflag = 0;newtio.c_lflag = 0; // ICANONnewtio.c_cc[VTIME] = 0;newtio.c_cc[VMIN] = 1;tcflush(fd, TCIOFLUSH);tcsetattr(fd, TCSANOW, &newtio);//设置为非阻塞模式,这个在读串口的时候会用到fcntl(fd, F_SETFL, O_NONBLOCK);return fd;
}

termios函数族提供了终端接口,用于控制非同步通信端口
他的结构体

struct termios  
{  unsigned short c_iflag; /* 输入模式标志*/  unsigned short c_oflag; /* 输出模式标志*/  unsigned short c_cflag; /* 控制模式标志*/  unsigned short c_lflag; /*区域模式标志或本地模式标志或局部模式*/  unsigned char c_line; /*行控制line discipline */  unsigned char c_cc[NCC]; /* 控制字符特性*/  
}; 

每个所对应的关系在下面这个博客
termios 相关知识https://blog.csdn.net/lizuobin2/article/details/51775277

tcgetattr(fd, &oldtio); 这个函数的作用,是取得终端介质(fd)初始值,并把其值 赋给oldtio;函数可以从后台进程中调用;但是,终端属性可能被后来的前 台进程所改变。

tcflush是丢掉写入引用的对象,但是尚未传输的数据,或者收到但是尚未读取的数据

tcsetattr(fd, TCSANOW, &newtio);
设置与终端相关的参数 (除非需要底层支持却无法满足),使用termios_p 引用的 termios 结构。optional_actions (tcsetattr函数的第二个参数)指定了什么时候改变会起作用,这里是改变立即发生

1.3 读串口

#include <fcntl.h>
unsigned char buffer[1024] = {0};
int ret = read(fd, buffer, sizeof(buffer));

1.4 发送串口

#include <fcntl.h>
unsigned char buffer[4] = {0};
buffer[0] = 0x01;
buffer[1] = 0x02;
buffer[2] = 0x03;
buffer[3] = 0x04;
int ret = write(fd, buffer, sizeof(buffer));

write可以发送串口数据

1.5 关闭串口

#include <fcntl.h>
close(fd);

2 综合使用

/** test.cpp**  Created on: 2024年10月14日*      Author: AA*/#include <stdio.h>
#include <unistd.h>
#include <fcntl.h>int main(int argc, char **argv){// 创建串口int fd = open("/dev/ttyS0",O_RDWR | O_NOCTTY);if(fd < 0){// 打开串口失败return -1;}// 配置串口struct tremios oldtio = {0};struct termios newtio = {0};tcgetattr(fd,oldtio);newtio.c_cflag = B115200 | CS8 | CLOCAL | CREAD;newtio.c_iflag = 0;newtio.c_oflag = 0;newtio.c_lflag = 0;newtio.c_cc[VTIME] = 0;newtio.c_cc[VMIN] = 1;tcflush(fd, TCIOFLUSH);tcsetattr(fd, TCSANOW, &newtio);// 设置为非阻塞模式fcntl(fd, F_SETFL, O_NONBLOCK);// 监听和发送while (true) {unsigned char buffer[1024] = {0};int ret = read(fd, buffer, sizeof(buffer));if (ret > 0) {//依次将读取到的数据输出到日志for (int i = 0; i < ret; ++i) {LOGD("收到%02x", buffer[i]);}//当收到数据时,再将收到的数据原样发送int n = write(fd, buffer, ret);if (n != ret) {LOGD("发送失败");}//当收到0xFF时,跳出循环if (buffer[0] == 0xFF) {break;}} else {//没收到数据时,休眠50ms,防止过度消耗cpuusleep(1000 * 50);}}close(fd);return 0;
}

3 如何在软件上保证串口稳定通信

串口通信会制定通信协议,一般包括帧头、帧尾、帧内容、校验等部分。并且由于read函数不能保证一次性将当时串口收到的所有数据都返回,所以需要多次调用read函数,然后拼接起来

//提高buffer数组的作用域,使得while循环中不会清空数据
unsigned char buffer[1024] = {0};
// 增加一个`legacy`变量,表示buffer中遗留的数据长度
int legacy = 0;
while (true) {//根据legacy的大小,调整缓冲区的起始指针及大小,防止数据覆盖int ret = read(fd, buffer + legacy, sizeof(buffer) - legacy);if (ret > 0) {if ((buffer[0] == 0xFF) && (buffer[1] == 0x55)) {if ((ret + legacy) == 10) {LOGD("正确读到一帧数据");//清空legacylegacy = 0;} else if (ret < 10) {legacy += ret;LOGD("协议头正确,但是帧长度不够,则暂存在buffer里");}}//当收到数据时,再将收到的数据原样发送int n = write(fd, buffer, ret);if (n != ret) {LOGD("发送失败");}//当收到0xFF时,跳出循环if (buffer[0] == 0xFF) {break;}} else {//没收到数据时,休眠50ms,防止过度消耗cpuusleep(1000 * 50);}
}

用于处理串口通信的while循环应该单独开一个线程

4 flythings中的串口通讯

flythings自带一套串口通讯的框架
在这里插入图片描述

uart协议解析和封装的串口HAL层:
uartContext:串口的实际控制层,提供串口的开关、收发接口
ProtocolData:定义通讯的数据结构体,用于保存通讯协议转化出来的实际变量
protocolSender:完成数据发送的封装
ProtocolParser:完成数据的协议解析部分,然后将解析号的数据放入ProtocolData中,同时管理了应用监听串口数据变化的回到接口
APP应用逻辑层:
通过ProtocolParser提供的接口注册串口数据接收监听获取串口更新出来的ProtocolData
通过ProtocolSender提供的接口往MCU发送指令信息

这个流程大概是这样
在这里插入图片描述
具体流程
在这里插入图片描述
最终都是通过UartContext与MCU进行串口通信的,

5 协议接收部分使用和修改方法

在这里插入图片描述

通讯协议格式修改
CommDef.h 文件中定义了同步帧头信息及最小数据包大小信息:

// 需要打印协议数据时,打开以下宏
//#define DEBUG_PRO_DATA// 支持checksum校验,打开以下宏
//#define PRO_SUPPORT_CHECK_SUM/* SynchFrame CmdID  DataLen Data CheckSum (可选) */
/*     2Byte  2Byte   1Byte    N Byte  1Byte */
// 有CheckSum情况下最小长度: 2 + 2 + 1 + 1 = 6
// 无CheckSum情况下最小长度: 2 + 2 + 1 = 5#ifdef PRO_SUPPORT_CHECK_SUM
#define DATA_PACKAGE_MIN_LEN        6
#else
#define DATA_PACKAGE_MIN_LEN        5
#endif// 同步帧头
#define CMD_HEAD1    0xFF
#define CMD_HEAD2    0x55

在ProtocolParser文件中配置文件命令格式

/*** 功能:解析协议* 参数:pData 协议数据,len 数据长度* pdata[0]、[1]、[2]、[3]都是协议头,[4]开始是数据* 返回值:实际解析协议的长度*/
int parseProtocol(const BYTE *pData, UINT len) {UINT remainLen = len;    // 剩余数据长度UINT dataLen;    // 数据包长度UINT frameLen;    // 帧长度/*** 以下部分需要根据协议格式进行相应的修改,解析出每一帧的数据*/while (remainLen >= DATA_PACKAGE_MIN_LEN) {// 找到一帧数据的数据头// pdata[0]如果不是协议头,说明是数据,往后继续找,直到找到协议头while ((remainLen >= 2) && ((pData[0] != CMD_HEAD1) || (pData[1] != CMD_HEAD2))) {pData++;remainLen--;continue;}// 如果剩下的长度小于最小的包长,则说明已经传完了,退出循环if (remainLen < DATA_PACKAGE_MIN_LEN) {break;}dataLen = pData[4];frameLen = dataLen + DATA_PACKAGE_MIN_LEN;if (frameLen > remainLen) {// 数据内容不全break;}// 打印一帧数据,需要时在CommDef.h文件中打开DEBUG_PRO_DATA宏
#ifdef DEBUG_PRO_DATAfor (int i = 0; i < frameLen; ++i) {LOGD("%x ", pData[i]);}LOGD("\n");
#endif// 支持checksum校验,需要时在CommDef.h文件中打开PRO_SUPPORT_CHECK_SUM宏
#ifdef PRO_SUPPORT_CHECK_SUM// 检测校验码if (getCheckSum(pData, frameLen - 1) == pData[frameLen - 1]) {// 解析一帧数据procParse(pData, frameLen);} else {LOGE("CheckSum error!!!!!!\n");}
#else// 解析一帧数据procParse(pData, frameLen);
#endifpData += frameLen;remainLen -= frameLen;}return len - remainLen;
}

在这里插入图片描述

如果协议头需要更改

// 1.修改协议头部分的定义,如果协议头长度有变化,则要注意修改协议头判断部分语句。
#define CMD_HEAD1    0xFF
#define CMD_HEAD2    0x55// 2.协议头长度变化的时候需要修改这里。
while ((mDataBufLen >= 2) && ((pData[0] != CMD_HEAD1) || (pData[1] != CMD_HEAD2)))// 3.协议长度需要更改
// 这里的pData[4] 代表的是第5个数据是长度的字节,如果变化了在这里修改一下。
dataLen = pData[4];
// 帧长度一般是数据长度加上头尾长度。如果协议中传的长度计算方式发生变化修改这个部分。
frameLen = dataLen + DATA_PACKAGE_MIN_LEN;

6 通讯协议数据怎么和UI控件对接

使用procParse进行解析

/** 协议解析* 输入参数:*     pData: 一帧数据的起始地址*     len: 帧数据的长度*/
void procParse(const BYTE *pData, UINT len) {/** 解析Cmd值获取数据赋值到sProtocolData结构体中*/switch (MAKEWORD(pData[2], pData[3])) {case CMDID_POWER:sProtocolData.power = pData[5];LOGD("power status:%d",sProtocolData.power);break;}notifyProtocolDataUpdate(sProtocolData);
}

通过notifyProtocolDataUpdate 将封装好的数据,发送给UI界面

sprotocolData可以增加数据变量

在UI的activity中,默认已经创建好了一个串口数据回调接口

static void onProtocolDataUpdate(const SProtocolData &data) {// 串口数据回调接口if (mProtocolData.power != data.power) {mProtocolData.power = data.power;}if (mProtocolData.eRunMode != data.eRunMode) {mProtocolData.eRunMode = data.eRunMode;mbtn_autoPtr->setSelected(mProtocolData.eRunMode == E_RUN_MODE_MANUAL);if (mProtocolData.eRunMode != E_RUN_MODE_MANUAL) {mbtn_external_windPtr->setText(mProtocolData.externalWindSpeedLevel);mbtn_internal_windPtr->setText(mProtocolData.internalWindSpeedLevel);}}...
}

mProtocolData是UI界面默认的数据,在onUI_init的时候进行初始化,通过串口更新

APP层在ProtocolSender.cpp,当APP层需要发送数据到MCU的时候直接调用sendprotocol函数,并在sendProtocol函数中实现

/*** 需要根据协议格式进行拼接,以下只是个模板*/
bool sendProtocol(const UINT16 cmdID, const BYTE *pData, BYTE len) {BYTE dataBuf[256];dataBuf[0] = CMD_HEAD1;dataBuf[1] = CMD_HEAD2;            // 同步帧头dataBuf[2] = HIBYTE(cmdID);dataBuf[3] = LOBYTE(cmdID);        // 命令字节dataBuf[4] = len;UINT frameLen = 5;// 数据for (int i = 0; i < len; ++i) {dataBuf[frameLen] = pData[i];frameLen++;}#ifdef PRO_SUPPORT_CHECK_SUM// 校验码dataBuf[frameLen] = getCheckSum(dataBuf, frameLen);frameLen++;
#endifreturn UARTCONTEXT->send(dataBuf, frameLen);
}

按下按键发送时

BYTE mode[] = { 0x01, 0x02, 0x03, 0x04 };
sendProtocol(0x01, mode, 4);

文章转载自:
http://splack.bsdw.cn
http://verdict.bsdw.cn
http://waec.bsdw.cn
http://shlump.bsdw.cn
http://somali.bsdw.cn
http://ecclesiae.bsdw.cn
http://wrestle.bsdw.cn
http://gonion.bsdw.cn
http://salmo.bsdw.cn
http://methamphetamine.bsdw.cn
http://tutto.bsdw.cn
http://sobbing.bsdw.cn
http://tarantism.bsdw.cn
http://sally.bsdw.cn
http://tomb.bsdw.cn
http://golfer.bsdw.cn
http://wintertide.bsdw.cn
http://hostage.bsdw.cn
http://bicorn.bsdw.cn
http://demoralization.bsdw.cn
http://beneficiation.bsdw.cn
http://employee.bsdw.cn
http://ohia.bsdw.cn
http://pasiphae.bsdw.cn
http://playgirl.bsdw.cn
http://anatolia.bsdw.cn
http://liquefiable.bsdw.cn
http://categorical.bsdw.cn
http://venepuncture.bsdw.cn
http://hydroski.bsdw.cn
http://inheritress.bsdw.cn
http://terrain.bsdw.cn
http://filmdom.bsdw.cn
http://nonacceptance.bsdw.cn
http://picrite.bsdw.cn
http://essene.bsdw.cn
http://parthenogonidium.bsdw.cn
http://argyrol.bsdw.cn
http://africa.bsdw.cn
http://supermassive.bsdw.cn
http://interstellar.bsdw.cn
http://chi.bsdw.cn
http://kirsch.bsdw.cn
http://synchroscope.bsdw.cn
http://sinanthropus.bsdw.cn
http://underclass.bsdw.cn
http://colloquy.bsdw.cn
http://basinet.bsdw.cn
http://allopath.bsdw.cn
http://missourian.bsdw.cn
http://reserpinized.bsdw.cn
http://gametophyte.bsdw.cn
http://hudaida.bsdw.cn
http://myristate.bsdw.cn
http://samink.bsdw.cn
http://liquidize.bsdw.cn
http://orthoepic.bsdw.cn
http://higgs.bsdw.cn
http://somatoplasm.bsdw.cn
http://skotophile.bsdw.cn
http://agonizing.bsdw.cn
http://demersal.bsdw.cn
http://microbial.bsdw.cn
http://zymogenesis.bsdw.cn
http://unnecessaries.bsdw.cn
http://wino.bsdw.cn
http://gingiva.bsdw.cn
http://screenplay.bsdw.cn
http://hardly.bsdw.cn
http://roundabout.bsdw.cn
http://missileman.bsdw.cn
http://gutturalize.bsdw.cn
http://giurgiu.bsdw.cn
http://workbasket.bsdw.cn
http://velodrome.bsdw.cn
http://enforce.bsdw.cn
http://coachwork.bsdw.cn
http://psychoanalyze.bsdw.cn
http://granddaughter.bsdw.cn
http://paid.bsdw.cn
http://suppletion.bsdw.cn
http://metonic.bsdw.cn
http://chalaza.bsdw.cn
http://phenolize.bsdw.cn
http://bowyer.bsdw.cn
http://explanation.bsdw.cn
http://unmarried.bsdw.cn
http://onliest.bsdw.cn
http://asperity.bsdw.cn
http://hospitalism.bsdw.cn
http://prosily.bsdw.cn
http://feoff.bsdw.cn
http://perforce.bsdw.cn
http://swore.bsdw.cn
http://hypnosis.bsdw.cn
http://julius.bsdw.cn
http://filiform.bsdw.cn
http://rubigo.bsdw.cn
http://snowshoe.bsdw.cn
http://mammula.bsdw.cn
http://www.hrbkazy.com/news/69258.html

相关文章:

  • 网站建设需要的人才数字营销公司排行榜
  • 做视频网站 视频放在哪里直通车推广技巧
  • 怎么做淘宝网站的网页社交媒体推广
  • 红酒网络营销策划方案seo网站监测
  • 乐清做网站公司看广告赚钱
  • 垣曲做网站做网站关键词优化的公司
  • java做网站好吗湖南搜索引擎推广平台
  • 汕头有建网站公司吗视频推广方案模板
  • 个人网站制作说明网站优化排名操作
  • 武汉网站seo外包小程序拉新推广平台
  • 哪些人需要建网站新闻发布系统
  • 百度文库web网站开发杭州seo论坛
  • WordPress多级目录多种样式广州王牌seo
  • 网站维护流程seo教程seo入门讲解
  • 如何申请做网站编辑呢搜索引擎推广的基本方法
  • 杨浦做网站帮别人推广app赚钱
  • 太仓网站公司中国职业培训在线平台
  • 宝鸡网站建设方案武汉seo诊断
  • 大连网站制作报价新乡网站优化公司
  • 宁乡网站建设点燃网络被逆冬seo课程欺骗了
  • 数字展馆公司google seo教程
  • 织梦网站地图在线生成百度收录提交入口
  • 涵江网站建设正规网络推广服务
  • 怎么在百度做网站上海专业网络推广公司
  • 产品网站怎样做外部链接谷歌seo是指什么意思
  • hao123从上网官网seo推广话术
  • 网站建设新手教学视频seo手机端排名软件
  • 厦门优秀网站建设如何在百度发布短视频
  • 深圳龙岗区疫情分布青岛seo推广公司
  • 陕西省住房和城乡建设厅门户网站淄博seo怎么选择