串口数据传输格式
2015-6-9 09:36 查看: 2111
波特率:38400
起始结束: 数据由起始位0x3A开始,结束位0x0D结束。
LRC检验:从起始位的下一byte开始到LRC位前一byte计算LRC,置入LRC byte。
状态Byte说明:
7bit |
6bit |
5bit |
4bit |
3bit |
2bit |
1bit |
0bit |
故障位 1:故障 |
0:恒压 1:恒流 |
保留 |
保留 |
保留 |
保留 |
保留 |
1:开机 0:关机 |
1 单片机向PC发送功能号0x09数据(即PC会收到的数据格式)
0 |
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
0x3A |
0x09 |
电压值 |
电流值 |
保留0x00 |
状态Byte |
LRC |
0x0D |
注:电压值、电流值为float类型
例:
fV = *((float*)&pu8Temp[2]);
fI = *((float*)&pu8Temp[6]);
此数据格式为单片机向PC发送的电源信息。如:电流电压值,恒流、开关机等
2 单片机向PC发送功能号0x00 数据(即PC会收到的数据格式)
0 |
1 |
2 |
3 |
0x3A |
0x00 |
LRC |
0x0D |
当PC收到此数据格式,说明单片机需要跟PC沟通。PC收到此数据格式后立即向单片机回复数据,格式如3。
3 PC向单片机发送设置数据
0 |
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
0x3A |
0x00 |
电压值 |
电流值 |
保留0x00 |
状态位 |
LRC |
0x0D |
注:电压值、电流值为float类型
例:(请自行按照所处运行环境定义BYTE(8位BIT变量))
BYTE * pu8Temp = (BYTE*)&m_fSetV; szu8Re[2] = pu8Temp[0]; szu8Re[3] = pu8Temp[1]; szu8Re[4] = pu8Temp[2]; szu8Re[5] = pu8Temp[3]; pu8Temp = (BYTE*)&m_fSetI; szu8Re[6] = pu8Temp[0]; szu8Re[7] = pu8Temp[1]; szu8Re[8] = pu8Temp[2]; szu8Re[9] = pu8Temp[3];
当PC收到0x00号功能数据时,立即按照此格式回复电流电压设置值。
关机操作:回复此格式,状态位最小bit为0即可。
开机操作:亦发送此格式,状态为最小bit为1即可。
注:开机操作应由PC主动向单片机发送数据。其他(设置电流电压、或者关机)应收到单片机0x00功能号时立即回复。
Example Code
#define FRAME_START 0x3A #define FRAME_END 0x0D //-- 计算LRC BYTE CalLRC(BYTE * pu8Buf, int i32Len) { BYTE u8LRC = 0; for(int i = 0; i < i32Len; i++) u8LRC += pu8Buf[i]; u8LRC = ~u8LRC; u8LRC++; return u8LRC; } Void OnComm(WPARAM ch, LPARAM port) { m_szu8RevBuf[m_i32RevLen] = (char)ch; m_i32RevLen++; if(ch == FRAME_END) { if(m_i32RevLen >= 4 && m_szu8RevBuf[m_i32RevLen - 4] == FRAME_START && m_szu8RevBuf[m_i32RevLen - 3] == 0x00) {//-- 0号功能 BYTE u8LRC = CalLRC(&m_szu8RevBuf[m_i32RevLen - 3], 1); if(u8LRC == m_szu8RevBuf[m_i32RevLen - 2]) { memset(m_szu8RevBuf, 0, sizeof(m_szu8RevBuf)); m_i32RevLen = 0; //-- 回复信息--------- if(!m_bSerialPortOpened) return 0; BYTE szu8Re[14] = {0}; szu8Re[0] = FRAME_START; szu8Re[13] = FRAME_END; szu8Re[1] = 0;//-- 地址0 BYTE * pu8Temp = (BYTE*)&m_fSetV; szu8Re[2] = pu8Temp[0]; szu8Re[3] = pu8Temp[1]; szu8Re[4] = pu8Temp[2]; szu8Re[5] = pu8Temp[3]; pu8Temp = (BYTE*)&m_fSetI; szu8Re[6] = pu8Temp[0]; szu8Re[7] = pu8Temp[1]; szu8Re[8] = pu8Temp[2]; szu8Re[9] = pu8Temp[3]; szu8Re[10] = 0; if(!m_bMacOn) szu8Re[11] = 0x01; szu8Re[12] = CalLRC(&szu8Re[1], 11); WriteToPort((char*)&szu8Re, sizeof(szu8Re)); return 0; } } if(m_i32RevLen >= 8 && m_szu8RevBuf[m_i32RevLen - 8] == FRAME_START && m_szu8RevBuf[m_i32RevLen - 7] == 0x01) {//-- 1号功能 BYTE u8LRC = CalLRC(&m_szu8RevBuf[m_i32RevLen - 7], 5); if(u8LRC == m_szu8RevBuf[m_i32RevLen - 2]) { //-- 1号功能数据,PC不关心这个数据,丢弃 memset(m_szu8RevBuf, 0, sizeof(m_szu8RevBuf)); m_i32RevLen = 0; return 0; } } if(m_i32RevLen >= 14 && m_szu8RevBuf[m_i32RevLen - 14] == FRAME_START && m_szu8RevBuf[m_i32RevLen - 13] == 0x09) {//-- 9号功能 单片机机向PC发送信息 BYTE u8LRC = CalLRC(&m_szu8RevBuf[m_i32RevLen - 13], 11); if(u8LRC == m_szu8RevBuf[m_i32RevLen - 2]) { //-- 9号功能数据,主机向PC发送信息 ParseFunction(9, 10, &m_szu8RevBuf[2]); //-- 分析数据获取开关电源信息,如:电流 //-- 电压等 m_wndShow.Invalidate(); memset(m_szu8RevBuf, 0, sizeof(m_szu8RevBuf)); m_i32RevLen = 0; return 0; } } } if(m_i32RevLen >= 250) { memset(m_szu8RevBuf, 0, sizeof(m_szu8RevBuf)); m_i32RevLen = 0; } return 0; }
PC机和单片机的交互流程
1 PC机发送开机数据给单片机(此数据和PC机设置单片机的电流电压数据一样):
3a 00 00 00 00 00 00 00 00 00 00 01 ff 0d 蓝色的为需要计算LRC的数据,红色为LRC结果。
注:此数据格式为电压0V,电流0A,状态为0x01,即开机。
2 单片机收到开机数据后开机,然后不断的向PC发送0x09、0x00 功能号的数据。
PC收到0x09功能号数据,即是开关电源上传给PC的信息。其中包含电流电压和状态,格式见上面说明。此格式不用回复。
PC收到0x00功能号数据,即是开关电源要跟PC沟通,PC应该立即回复需要设置的信息。其中包括电流电压和状态(状态中包含了开机或者关机信息,最低bit为1即开机,0为关机)。
关机:即回复给单片机的状态Byte最低位为0即可。电流电压的位置可以设置为0。
举例说明:
/******************************************************************************/
文档下载地址:
/******************************************************************************/
测试软件下载地址:
英文版
/******************************************************************************/
float转hex计算软件
/******************************************************************************/
LRC计算工具