【STM32代码移植问题4:字符串拼接/数字转换、共用体与时间戳】

字符串拼接/数字转换

参考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 <strlen(str)); 
}

主函数

    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 == "<<buf.character[0]<<buf.character[1]<<buf.character[2]<<buf.character[3];
            if(time_flag == 2){//处理数据(时间戳转为字符形式)
                	QDateTime time = QDateTime::fromTime_t(buf.num);
                	//qDebug()<<"time == "<<buf.num;
                	rcvStr+=QDateTime::fromTime_t(buf.num).toString("yyyy/MM/dd\thh:mm:ss\t");
                	time_flag = 0;
                	id = 0;
                    }
                                
            }
        }
    }
}

时间下发(字符形式)

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

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]);
        //延时100ms
        QTime 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*4
        TMR1L=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;   
    }
  • 1
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Dawn Yue

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值