字符串拼接/数字转换
参考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;
}