AVR單片機(jī)與上位機(jī)通信協(xié)議的制定
單片機(jī)和上位機(jī)的串口通信協(xié)議分為上行協(xié)議和下行協(xié)議,要分別制定!
上行協(xié)議,即由單片機(jī)向上位機(jī)發(fā)送數(shù)據(jù)。
下行協(xié)議,即由上位機(jī)向單片機(jī)發(fā)送數(shù)據(jù)。
而通信協(xié)議又要分固定長度和不定長度兩種
本文所介紹的協(xié)議屬于簡單的固定字長的通信協(xié)議!
下行協(xié)議由四個字節(jié)構(gòu)成
起始字PRE 命令字ORD 值VAL 結(jié)束字END 附注
1byte 1byte 1byte 1byte
BBH AAH(ORD_SATA) 單片機(jī)狀態(tài)轉(zhuǎn)換命令標(biāo)識
01H EEH 模式1:空閑
02H EEH 模式2:溫度采集
03H EEH 模式3:溫度采集向上位機(jī)傳送采集值
04H EEH 模式4:PWM測試
BBH DDH(ORD_PWM) value EEH PWM占空比值修改指令
BBH FFH(ORD_TEM) value EEH 目標(biāo)溫度控制指令
上表是簡單的上位機(jī)對單片機(jī)的控制指令
下述函數(shù)是C#中封裝的串口通信類中的發(fā)送函數(shù)的封裝
public void SerSendCommu(byte orderDef, byte data)//參數(shù)1為命令字,參數(shù)二為要發(fā)送的數(shù)
//據(jù),需要時可直接調(diào)用
{
Byte[] BSendTemp = new Byte[SEND_LENTH];
BSendTemp[0] = PRE;
BSendTemp[1] = orderDef;
BSendTemp[2] = data;
BSendTemp[3] = END;
this.serialPort1.Write(BSendTemp, 0, SEND_LENTH);
}
下位機(jī)中用中斷方式接收字符,本文用的是GCC語言,下面是串口接收數(shù)據(jù)中斷
ISR(USART_RXC_vect)//串口接收中斷
{
unsigned char status,data;
status = UCSRA; //**首先讀取UCSRA的值,再讀取UDR值,順序不能顛倒,否則讀取UDR后的UCSRA的
//值即會改變**
data = UDR;
if(!Uart_RecvFlag)//判斷緩存中的數(shù)據(jù)是否讀完,讀完則接收指令
{
if((status((1FE)|(1PE)|(1DOR)))==0)
{
rx_buffer[rx_counter]=data;
rx_counter++;
switch(rx_counter)
{
case 1:
if(data!=USART_BEGIN_STX)
rx_counter=0;
break;
case 4:
rx_counter=0;
if(data==USART_END_STX)
Uart_RecvFlag=1;
break;
}
}
}
}
評論