串口數據傳輸格式
波特率: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。
舉例說明:
|