【STM32代码移植问题4:字符串拼接/数字转换、共用体与时间戳】
创始人
2024-06-03 03:35:22
0

目录

  • 字符串拼接/数字转换
  • 共用体(串口发送长整型)
  • 时间上发(时间戳)
    • 1.下位机(pic16f...)
    • 2.上位机(QT...)
  • 时间下发(字符形式)
    • 1.上位机
    • 2.下位机

字符串拼接/数字转换

参考https://blog.csdn.net/qq_45539458/article/details/122525869

拼接:sprintf

#define u8 unsigned char
#define u32  unsigned  int  
#define u16 unsigned short int int temp=0;char spiBuf[10];u8 Rx_data3=0,Rx_data2=0,Rx_data1=0;Rx_data3=0x00;Rx_data2=0x8D;Rx_data1=0x2C;sprintf(spiBuf, "%x%x%x\0", Rx_data1, Rx_data2, Rx_data3);	//字符串:拼接temp=strtol(spiBuf,0,16);//字符串:数字转换

转换:

        u32 code=0;    for(u16 t=0;t<6;t++){//字符转为整数if((spiBuf[t]>='0')&&(spiBuf[t]<='9'))code=spiBuf[t]-48+code*16;if((spiBuf[t]>='A')&&(spiBuf[t]<='F'))code=spiBuf[t]-65+code*16+10;if((spiBuf[t]>='a')&&(spiBuf[t]<='f'))code=spiBuf[t]-97+code*16+10;}       

共用体(串口发送长整型)

参考https://zhidao.baidu.com/question/205390688.html
定义长整型变量为共用体类型。

union
{long int address;
uchar a1[4];
}c8;

赋值时先给c8.address赋值,发送时只需要发送a1[0]至a1[3]即可,也就是8位8位的发送。他们共用一个地址,即数组的地址便是长整型的地址。

时间上发(时间戳)

即下位机发送时间戳给上位机

1.下位机(pic16f…)

参考
mktime算法解析:https://blog.csdn.net/axx1611/article/details/1792827
时间戳、标准格式转换:https://blog.csdn.net/cjsycyl/article/details/8690531

#define u8  unsigned char
#define u16 unsigned short int 
#define u32 long int
u16 day=6,month=12,year=2022; //year=22
u8 hour=0,min=0,sec=0;
struct tm stm;  
union{
long int num;
unsigned char character[4];
}realtime;unsigned char SendBuf[7]; 
void send_byte(u8 data ) { 
TXREG= data; 
while(!TRMT); 
} 
void Send_String( char * str){  
u16 k = 0; //void Send_String(char * str)
do { 
send_byte(*(str + k)); 
k++; 
} while(k 

主函数

    stm.tm_year=year-1900;  stm.tm_mon=month-1;  stm.tm_mday=day;  stm.tm_hour=hour-8;  stm.tm_min=min;  stm.tm_sec=sec;  realtime.num=mktime(&stm); //....当下位机收到'b'时,向上位机发送{时间戳}if(RsBuf[0]=='b') { Send_String("{");  send_byte(realtime.character[3]);send_byte(realtime.character[2]);send_byte(realtime.character[1]);send_byte(realtime.character[0]); Send_String("}\n");RsPoint=0;} 

2.上位机(QT…)

参考
Qt获取时间戳:https://blog.csdn.net/lmhuanying1012/article/details/78016352
点击按钮,向下位机发送’b’

void MainWindow::on_pB_read_Time_clicked(){this->serial_port->write(" b");// 串口发送"b" 读取下位机时间
}

接收数据,处理得到时间戳

union
{long int num;
unsigned char character[4];
}buf;
int id=0;
static int time_flag = 0;MainWindow::MainWindow(QWidget* parent) :QMainWindow(parent), is_open_serailport(false),serial_port(new QSerialPort(this)), ui(new Ui::MainWindow)
{QObject::connect(this->serial_port, &QSerialPort::readyRead, [this]{if(!this->is_open_serailport) return;const QByteArray& info = this->serial_port->readAll();if(info.length() <= 0) return;QString rcvStr;if(this->ui->rB_rcvMode_text->isChecked()){foreach(char b , info )//数据解析{if(b == ']'&&id==4&&data_flag == 1)... //其他数据if(b == '['&&id==0)...if(data_flag == 1)...if(data_flag == 2)...if((b != ']')&&(b != '}')&&(b != '[')&&(b != '{')&&(b != '(')&&(b != ')')&&data_flag == 0&&time_flag == 0&&rom_flag == 0)rcvStr += b;if(b == '}'&&id==5&&time_flag == 1)//结束处理time_flag = 2;if(b == '{'&&id==0)//开始处理time_flag = 1;if(time_flag == 1){//数据存入数组(得到时间戳)if(id!=0)buf.character[4-id]=b;id++;}//qDebug()<<"buf == "<//处理数据(时间戳转为字符形式)QDateTime time = QDateTime::fromTime_t(buf.num);//qDebug()<<"time == "<

时间下发(字符形式)

即上位机发送时间的字符形式给下位机

1.上位机

void MainWindow::on_pB_SetRealTime_clicked()
{// 上位机发送{yyyy/MM/dd-hh:mm:ss} 设置下位机实时时间this->serial_port->write(" {");QByteArray time;const quint64& unix_timestamp = QDateTime::currentMSecsSinceEpoch();   //获取当前时间time+=QDateTime::fromMSecsSinceEpoch(unix_timestamp).toString("yyyy/MM/dd-hh:mm:ss");//this->serial_port->write(time);//一次性发送单片机无法处理  for (int i=0;i<=20;i++) {this->serial_port->putChar(time[i]);//延时100msQTime dieTime = QTime::currentTime().addMSecs(10);while( QTime::currentTime() < dieTime )QCoreApplication::processEvents(QEventLoop::AllEvents, 100);}this->serial_port->write("}");
}

2.下位机

串口中断函数:

RCIF=0;//关闭其他中断
TMR1IF=0;  
RsBuf[RsPoint++]=RCREG;//校正时间if(RsBuf[0]=='{'&&RsPoint>=20) { // 下位机收到{2022/12/06-12:31:00}  year=RsBuf[1]-48;year=RsBuf[2]-48+year*10;year=RsBuf[3]-48+year*10;//year=RsBuf[3]-48;year=RsBuf[4]-48+year*10;month=RsBuf[6]-48;month=RsBuf[7]-48+month*10; day=RsBuf[9]-48;day=RsBuf[10]-48+day*10;   hour=RsBuf[12]-48;hour=RsBuf[13]-48+hour*10;min=RsBuf[15]-48;min=RsBuf[16]-48+min*10; sec=RsBuf[18]-48;sec=RsBuf[19]-48+sec*10;  timeflag=1;Send_String("Time calibration "); Send_String("successful\n");RsPoint=0;            } 
RCIF=1;//恢复其他中断
TMR1IF=1;    

定时器中断(5s发生一次定时器中断):

        TMR1IF=0;TMR1H=0x60;// TMR1H=0x80;  1*1.25*4TMR1L=0x00;//TMR1L=0x0;realtime.num=realtime.num+5;//时间+5s

主函数:

    if(timeflag==1){ stm.tm_year=year-1900;  stm.tm_mon=month-1;  stm.tm_mday=day;  stm.tm_hour=hour-8;  stm.tm_min=min;  stm.tm_sec=sec;  realtime.num=mktime(&stm); timeflag=0;   }

相关内容

热门资讯

监控摄像头接入GB28181平... 流程简介将监控摄像头的视频在网站和APP中直播,要解决的几个问题是:1&...
Windows10添加群晖磁盘... 在使用群晖NAS时,我们需要通过本地映射的方式把NAS映射成本地的一块磁盘使用。 通过...
protocol buffer... 目录 目录 什么是protocol buffer 1.protobuf 1.1安装  1.2使用...
在Word、WPS中插入AxM... 引言 我最近需要写一些文章,在排版时发现AxMath插入的公式竟然会导致行间距异常&#...
Fluent中创建监测点 1 概述某些仿真问题,需要创建监测点,用于获取空间定点的数据࿰...
educoder数据结构与算法...                                                   ...
MySQL下载和安装(Wind... 前言:刚换了一台电脑,里面所有东西都需要重新配置,习惯了所...
MFC文件操作  MFC提供了一个文件操作的基类CFile,这个类提供了一个没有缓存的二进制格式的磁盘...
有效的括号 一、题目 给定一个只包括 '(',')','{','}'...
【Ctfer训练计划】——(三... 作者名:Demo不是emo  主页面链接:主页传送门 创作初心ÿ...