;*******************************************************************************
;*
;*子程序名:USART_AINT.asm
;*程序名稱:通用同步和異步串行接收器和轉發(fā)器(USART)
;*異步中斷接收和發(fā)送通信程序
;*版本:1.0
;*適用MCU型號:AVR所有型號
;*使用資源:r5,r6,r16,r17,r18,r19,r20,r28,r29,r30,r31
;*定時器/計數器0(溢出中斷)
;*
;*程序功能:
;* 本程序是通用同步和異步串行接收器和轉發(fā)器(USART)在異步狀態(tài)下使用中斷
;*方式進行全雙工接收和發(fā)送數據的通信程序。共包括下面列表中這四個子程序。這
;*四個子程序的具體使用方法請參考各自的說明。
;*┏───────────┳───────────────────────┓
;*┃子程序名稱┃子程序功能描述┃
;*┣───────────╋───────────────────────┫
;*┃USART_AINT_INI┃USART異步通信中斷接收和發(fā)送初始化┃
;*┣───────────╋───────────────────────┫
;*┃USART_INT_ACOM┃USART異步通信中斷接收與發(fā)送協(xié)議命令和數據處理┃
;*┣───────────╋───────────────────────┫
;*┃USART_RXCINT┃USART異步通信接收結束中斷處理┃
;*┣───────────╋───────────────────────┫
;*┃USART_TXDREINT┃USART異步通信數據寄存器空中斷發(fā)送處理┃
;*┗───────────┻───────────────────────┛
;*
;*注意:
;* ①.r5(USARTAI_RXNum)《接收作業(yè)次數寄存器》和r6(USARTAI_TXNum)
;*《發(fā)送作業(yè)次數寄存器》為全局寄存器變量,不得被其他程序使用,否則將導致接收
;*和發(fā)送的數據錯誤。
;* ?、?本程序共使用了3個中斷向量,需在主程序中設置其中斷向量轉移地址,分
;*別為如下具體設置:
;*┏─────────────┳───────┳─────────────┓
;*┃中斷名稱┃中斷向量地址┃中斷處理程序┃
;*┣─────────────╋───────╋─────────────┫
;*┃USART接收結束中斷┃URXCaddr┃USART_RXCINT┃
;*┣─────────────╋───────╋─────────────┫
;*┃USART數據寄存器空中斷┃UDREaddr┃USART_TXDREINT┃
;*┣─────────────╋───────╋─────────────┫
;*┃T/C0溢出中斷┃OVF0addr┃TC0_Timer_OVFINT┃
;*┗─────────────┻───────┻─────────────┛
;*
;*通信協(xié)議:
;* ?、?每次進行接收和發(fā)送的作業(yè)時均以協(xié)議命令來決定下一步操作方式,關于通信
;*協(xié)議命令的約定方法請見下述詳細說明和命令字符串的具體定義。接收和發(fā)送的命令
;*的數據字節(jié)長度固定為10個字節(jié),其格式定義如下:COM(命令起始標識字符串)+
;*設備編號(4個字節(jié))+命令字(3個字節(jié))。
;* ?、?接收或發(fā)送的數據幀格式:“8個數據位,1個停止位,使用奇校驗”。注:如
;*需更改本程序的數據幀格式可在“USART_AINT_INI”子程序中進行修改。
;* ?、?本程序約定雙方通信的波特率為“115.2Kbps”。注:如需更改本程序的通
;*信波特率可在“波特率(bps)常數定義”中進行設置,但雙方通信的波特率受定時器/
;*計數器0定時時間的約束,如果要修改最小雙方通信波特率,則需修改定時器/計數器
;*0的定時時間(減小最小波特率需延長定時時間,增大則縮短定時時間)。定時器/計
;*數器0的定時時間應略大于在約定雙方通信的波特率下接收完255個字節(jié)所用的時間
;*總和,也不宜取得過大,過大則影響雙方通信的速度。
;* ?、?接收和發(fā)送的數據時均以[命令>數據,命令>數據……]形式為作業(yè)方式進行
;*通信,但接收和發(fā)送的命令時可以任意形式進行通信。對于接收和發(fā)送的數據的校驗方
;*法采用循環(huán)冗余檢測(CRC)校驗法,接收和發(fā)送的雙方必須采用相同的校驗算法,具
;*體的檢測校驗算法請參考子程序“Data_CRC_2Byte”中的具體說明。
;* ?、?每次接收和發(fā)送的數據總長度均不超過255個字節(jié)。而且每次接收或發(fā)送數據
;*的第一個字節(jié)為本次接收或發(fā)送的數據長度字符,最后兩個字節(jié)為循環(huán)冗余檢測校驗字
;*節(jié),因此每次接收和發(fā)送的有效數據長度均不得超過252個字節(jié)。,其計算公式如下:
;*數據長度數值=有效數據字節(jié)長度+3(1個長度字符本身+2個校驗字節(jié))
;* ?、?在發(fā)送數據前要向對方先發(fā)送一請求發(fā)送數據命令字符串“COMXXXXATX”,等待
;*對方回應一允許發(fā)送命令字符串“COMXXXXYET”的握手信號后,方可接著進行發(fā)送數據。
;* ?、?當接收到的數據或命令有錯誤時,可向對方發(fā)送要求重新發(fā)送命令字符串“CO
;*MXXXXRPT”,要求對方重新發(fā)送。對方在接收到此命令字符串后,依據上次發(fā)送的作業(yè)
;*類型來重新發(fā)送數據或命令。對于接收到的數據經循環(huán)冗余檢測校驗錯誤后,也可使用
;*重新發(fā)送一次允許發(fā)送命令字符串“COMXXXXYET”來要求對方重新發(fā)送數據。
;* ⑧.當接收到的數據(不包括命令)經循環(huán)冗余檢測校驗正確后,必須向對方發(fā)送
;*一接收數據正確命令字符串“COMXXXXOKD”,來結束本次接收數據操作。如果對方不發(fā)
;*送收到此命令字符串“COMXXXXOKD”錯誤的信息(即發(fā)回“COMXXXXRPT”),不允許多
;*次發(fā)送此命令字符串,否則將導致接收數據錯誤。
;* ?、?本程序通信協(xié)議命令還包括了下面三個協(xié)議命令字符串,具體用法如下述:
;*“COMXXXXSTD”[要求對方發(fā)送指定數據],此命令用于啟動雙方對指定數據的收發(fā)
;*操作。
;*“COMXXXXRII”[要求對方重新初始化USART端口狀態(tài)],此命令用于當通信協(xié)議命令
;*混亂,致使收發(fā)作業(yè)操作無法正常運行時,向對方發(fā)出從頭再重新開始收發(fā)作業(yè)請求。
;*此命令也可用于雙方開始通信前向對方發(fā)送開始通信命令使用,使雙方的USART端口
;*均處于起始狀態(tài)。
;*“COMXXXXYRI”[重新初始化USART端口狀態(tài)完成],此命令用于通知對方,我方己可
;*以從頭再重新開始收發(fā)作業(yè)。
;* ⑩.“COMXXXXCIT”[從USART端口傳送控制操作指令],此命令用于通知對方下
;*面接著發(fā)送的數據為控制操作指令字符串,其字符串的第一個字節(jié)也為數據長度字符,
;*但字符串的數值有無CRC校驗碼都可以,有CRC校驗碼時長度值相應也加2個。發(fā)送
;*和回應控制操作指令字符串的通信協(xié)議遵循發(fā)送數據方式。接收方在收到控制操作指令
;*字符串后,可能會發(fā)回三種回應協(xié)議命令:
;*⑴.無法正確識別控制操作指令字符串的內容,表示接收到的指令錯誤或受到干擾,將
;*發(fā)回要求對方重新發(fā)送命令字符串“COMXXXXRPT”。
;*⑵.己經完成了控制操作指令字符串的內容指定的操作程序,將發(fā)回接收數據正確命令
;*字符串“COMXXXXOKD”。
;*⑶.控制操作指令字符串的內容為要求向其發(fā)送指定的數據,將發(fā)回請求發(fā)送數據命令
;*字符串“COMXXXXATX”。
;*
;*注釋:
;* ①.定時器/計數器0用于約束接收作業(yè)全部完成(指從接收第一個數據到最后一
;*個數據之間)的時間范圍,如果在規(guī)定的時間內沒有接收作業(yè)全部完成,則強制結束
;*此次接收作業(yè),以便下次接收作業(yè)正確操作。其定時時間應略大于在約定雙方通信的
;*波特率下接收完256個字節(jié)所用的時間總和。
;* ②.當收發(fā)命令字符串“COMXXXXRPT”超過16次時,即雙方接收和發(fā)送無論是數
;*據還是協(xié)議命令只要其錯誤總次數超過16次,那么就認為雙方通信處于不同步狀態(tài),
;*或通信協(xié)議命令混亂。系統(tǒng)將會首先重新初始化本身的USART端口狀態(tài)和數據處理狀
;*態(tài),然后向對方發(fā)送要求對方重新初始化USART端口狀態(tài)命令字符串“COMXXXXRII”,
;*以使雙方通信重新處于同步狀態(tài)。
;*
;*******************************************************************************
;*
;*指令條數:1398+return
;*指令執(zhí)行周期:0+return
;*低位寄存器使用:2(r5,r6)(注:此兩個為全局寄存器變量,不得被其他程序使用)
;*高位寄存器使用:5(r16,r17,r18,r19,r20)
;*指針寄存器使用:Y,Z
;*
;*******************************************************************************
;********本程序需調用的子程序定義:
.include"DataCheck_CRC2B.asm";包括2字節(jié)數據循環(huán)冗余檢測校驗子程序
;********依據硬件設置需修改的SRAM存儲地址定義:
.equUSARTAI_TXCOM=$0070;發(fā)送命令作業(yè)標志
.equDataUPD_TXALW=$0071;允許更新發(fā)送數據標志
.equUSARTAI_TXEnd=$0072;發(fā)送作業(yè)全部結束標志
.equUSARTAI_TXAPL=$0074;發(fā)送地址指針低字節(jié)
.equUSARTAI_TXAPH=$0075;發(fā)送地址指針高字節(jié)
.equUSARTAI_TXCOA=$0076;首個發(fā)送命令字符地址
;要再占用往下的10個字節(jié)位置
.equUSARTAI_TXDAA=$0080;首個發(fā)送數據地址
;要再占用往下的255個字節(jié)位置
.equUSARTAI_RXCOM=$0182;接收命令作業(yè)標志
.equDataUPD_RXALW=$0183;允許處理接收數據標志
.equUSARTAI_RXUPD=$0184;接收作業(yè)己更新標志
.equUSARTAI_RXEnd=$0185;接收作業(yè)全部結束標志
.equUSARTAI_RXAPL=$0186;接收作業(yè)地址指針低字節(jié)
.equUSARTAI_RXAPH=$0187;接收作業(yè)地址指針高字節(jié)
.equUSARTAI_RXCOA=$0188;首個接收命令字符地址
;要再占用往下的10個字節(jié)位置
.equUSARTAI_RXDAA=$0192;首個接收數據地址
;要再占用往下的255個字節(jié)位置
.equUSARTAI_ERRNum=$0293;USART發(fā)生收發(fā)錯誤次數計數器
.equUSARTAI_T0VNum=$0294;定時器/計數器0溢出次數計數器
;***波特率(bps)常數定義:
;下面波特率設置以單片機的時鐘=11.0592MHz,且不打開倍速的條件下進行定義。
;波特率(bps)=115.2Kbps,誤差=0.0%
.equUSARTAI_UBRRL=$05
.equUSARTAI_UBRRH=0
;***定時器/計數器0定時2秒常數定義:
;下面定時器/計數器0定時參數設置以 單片機 的時鐘=11.0592MHz,且定時器/計數
;器0的預分頻因子=1024進行的條件下定義。其計算公式如下:
;定時時間=1÷ 單片機 的時鐘頻率×1024×USARTAI_T0CNT×USARTAI_T0Num
.equUSARTAI_T0CNTI=$80;定時器/計數器0計數預定比例值
.equUSARTAI_T0NumI=$03;定時器/計數器0溢出次數值
;*******************************************************************************
;*
;*通用同步和異步串行接收器和轉發(fā)器(USART)異步中斷接收和發(fā)送通信程序:
;*
;*“USART_AINT_INI”---USART異步通信中斷接收和發(fā)送初始化子程序
;*
;*“USART_RXCINT”------USART異步通信接收結束中斷處理子程序。
;*
;*“USART_TXDREINT”----USART異步通信數據寄存器空中斷發(fā)送處理子程序。
;*
;*“USART_INT_ACOM”----USART異步通信中斷接收與發(fā)送協(xié)議命令和數據處理子程序
;*
;*******************************************************************************
;********全局程序寄存器變量定義(不得被其他程序使用):
.defUSARTAI_RXNum=r5;接收作業(yè)次數寄存器
.defUSARTAI_TXNum=r6;發(fā)送作業(yè)次數寄存器
;********本程序寄存器變量定義:
.defUSARTAI_TEMP=r16;暫存寄存器
.defUSARTAI_TEMP2=r17;暫存寄存器2
.defUSARTAI_TEMP3=r18;暫存寄存器3
;********本程序常數定義:
.equUSARTAI_TCOMI=$e0;發(fā)送命令作業(yè)標志值(11100000)
.equDataUPD_TALWI=$c0;允許更新發(fā)送數據標志值(11000000)
.equUSARTAI_TEndI=$f0;全部數據發(fā)送結束標志值(11110000)
.equUSARTAI_RCOMI=$07;接收命令作業(yè)標志值(00000111)
.equDataUPD_RALWI=$03;允許處理接收數據標志值(00000011)
.equUSARTAI_RUPDI=$0a;接收作業(yè)己更新標志值(00001010)
.equUSARTAI_REndI=$0f;全部數據接收結束標志值(00001111)
.equUSARTAI_ENALWI=$10;允許USART發(fā)生收發(fā)錯誤次數值(16次)
.equUSARTAI_CMATNI=$0a;收發(fā)命令的字符串總長度數值(10個)
.equUSARTAI_CMANI=$03;收發(fā)命令的有效字符串長度數值(3個)
;********程序指令代碼清單:
;*******************************************************************************
;*
;*USART異步通信中斷接收和發(fā)送初始化子程序?。 癠SART_AINT_INI”
;*
;*說明:
;* 本子程序用于初始化USART異步中斷接收和發(fā)送通信。本初始化子程序只打開了
;*USART的中斷接收功能,沒有打開中斷發(fā)送功能。
;* 本子程序只需在主程序中運行一次即可。除非釋放RXD與TXD引腳功能作為其
;*他用途,如要再使用USART通信則需在主程序中再運行一次本子程序。
;*
;*******************************************************************************
USART_AINT_INI:
pushZL;壓入寄存器中的數值到堆棧
pushZH
inZL,SREG;壓狀態(tài)寄存器中的標志值到堆棧
pushZL
ldiZL,USARTAI_TEndI;置發(fā)送作業(yè)全部結束標志值
stsUSARTAI_TXEnd,ZL
ldiZL,USARTAI_TCOMI;置發(fā)送命令作業(yè)標志值,首次發(fā)送一定為
stsUSARTAI_TXCOM,ZL;請求向對方發(fā)送或允許對方發(fā)送命令
clrZL;清除允許更新發(fā)送數據標志
stsDataUPD_TXALW,ZL
ldiZL,USARTAI_REndI;置接收作業(yè)全部結束標志值
stsUSARTAI_RXEnd,ZL
ldiZL,USARTAI_RCOMI;置接收命令作業(yè)標志值,首次接收一定為
stsUSARTAI_RXCOM,ZL;對方請求發(fā)送或對方允許發(fā)送命令
clrZL;清除接收作業(yè)己更新標志
stsUSARTAI_RXUPD,ZL
clrZL;清除允許處理接收數據標志
stsDataUPD_RXALW,ZL
clrZL;清除USART發(fā)生收發(fā)錯誤次數計數器值
stsUSARTAI_ERRNum,ZL
clrZL;清除定時器/計數器0溢出次數計數器值
stsUSARTAI_T0VNum,ZL
cli;禁止全局中斷
ldiZL,USARTAI_UBRRL;設置通信波特率
outUBRRL,ZL
ldiZL,USARTAI_UBRRH
outUBRRH,ZL
ldiZL,(1<
;并使能奇校驗。USART異步模式
;ldiZL,(1<
;并使能奇校驗。USART異步模式
outUCSRC,ZL
ldiZL,(1<
sei;打開全局中斷
popZL
outSREG,ZL;彈出堆棧中的標志值到狀態(tài)寄存器
popZH;彈出堆棧中的數值到寄存器
popZL
ret;子程序返回
;*******************************************************************************
;*
;*USART異步通信接收結束中斷處理子程序?。 癠SART_RXCINT”
;*
;*說明:
;* 本子程序用于USART異步通信接收結束中斷處理。
;*
;*SRAM中標志字節(jié)用法:
;* 入口標志:本子程序將檢查這些標志,依據這些標志置值來控制不同接收作業(yè)。
;*接收作業(yè)全部結束(USARTAI_RXEnd)=$07(USARTAI_REndI)
;*≠$07(USARTAI_REndI)
;*r5---接收作業(yè)次數(USARTAI_RXNum)
;* 出口標志:①.接收作業(yè)全部正確接收完成后,將對下面這兩個標志置值。
;*接收作業(yè)全部結束(USARTAI_RXEnd)=$0f(USARTAI_REndI)
;*接收作業(yè)己更新(USARTAI_RXUPD)=$0a(USARTAI_RUPDI)
;*r5---接收作業(yè)次數(USARTAI_RXNum)=$00
;* ②.接收作業(yè)開始后(正在進行中),將對下面這兩個標志置值。
;*接收作業(yè)全部結束(USARTAI_RXEnd)=$00
;*接收作業(yè)己更新(USARTAI_RXUPD)=$00
;* ?、郏邮兆鳂I(yè)發(fā)生錯誤時,將對下面這兩個標志置值。
;*接收作業(yè)全部結束(USARTAI_RXEnd)=$00
;*接收作業(yè)己更新(USARTAI_RXUPD)=$0a(USARTAI_RUPDI)
;*
;*******************************************************************************
USART_RXCINT:
pushUSARTAI_TEMP;壓入寄存器中的數值到堆棧
pushZL
pushZH
inUSARTAI_TEMP,SREG;壓狀態(tài)寄存器中的標志值到堆棧
pushUSARTAI_TEMP
ldsUSARTAI_TEMP,USARTAI_RXEnd;檢查接收作業(yè)是否己全部結束?
cpiUSARTAI_TEMP,USARTAI_REndI;否,則繼續(xù)
breqUSART_RXCINT_First;是,就轉至接收第一個字節(jié)處理
ldiZH,(1<
andUSARTAI_TEMP,ZH;否,則繼續(xù)
brneUSART_RXCINT_Error;是,就轉至接收錯誤處理
ldsZL,USARTAI_RXAPL;置接收作業(yè)地址指針
ldsZH,USARTAI_RXAPH
inUSARTAI_TEMP,UDR;從USART數據寄存器取出接收數據
stZ,USARTAI_TEMP;存儲進SRAM中
adiwZL,$01;接收作業(yè)地址指針+1
stsUSARTAI_RXAPL,ZL;存儲回SRAM中
stsUSARTAI_RXAPH,ZH
decUSARTAI_RXNum;全部接收作業(yè)完畢否?
breqUSART_RXCINT_End;是,就轉至結束處理
rjmpUSART_RXCINT_RET;否,轉到中斷返回
USART_RXCINT_End:
ldiZL,USARTAI_REndI;置接收作業(yè)全部結束標志值
stsUSARTAI_RXEnd,ZL
ldiZL,USARTAI_RUPDI;置接收作業(yè)己更新標志值
stsUSARTAI_RXUPD,ZL
ldiZH,(1<
inZL,TIMSK;器中的此項設置,對于其他T/C
andZL,ZH;中斷狀態(tài)保留原來設置
outTIMSK,ZL
rjmpUSART_RXCINT_RET;轉到中斷返回
USART_RXCINT_Error:
ldiZH,(1<
inZL,TIMSK;器中的此項設置,對于其他T/C
andZL,ZH;中斷狀態(tài)保留原來設置
outTIMSK,ZL
inUSARTAI_TEMP,UDR;讀USART數據寄存器使RXC標志清除,
;以結束本次USART接收結束中斷處理
ldiZL,USARTAI_RUPDI;置接收作業(yè)己更新標志值
stsUSARTAI_RXUPD,ZL
rjmpUSART_RXCINT_RET;轉到中斷返回
USART_RXCINT_First:
clrZL;清除接收作業(yè)全部結束標志
stsUSARTAI_RXEnd,ZL
stsUSARTAI_T0VNum,ZL;定時器/計數器0溢出次數清0
inZL,TIFR;清除T/C0計數溢出標志
oriZL,(1<
;中斷標志保留原來狀態(tài)
ldiZL,USARTAI_T0CNTI;置T/C0定時參數的預定計數比例值
outTCNT0,ZL
inZL,TIMSK;使能T/C0計數溢出中斷
oriZL,(1<
;中斷狀態(tài)保留原來設置
ldiZL,(1<
ldsZL,USARTAI_RXCOM;接收作業(yè)是否為接收命令
cpiZL,USARTAI_RCOMI;否,則為接收數據
breqUSART_RXCINT_FCOMM;是,就轉至接收命令處理
USART_RXCINT_FData:
ldiZL,Low(USARTAI_RXDAA);置接收作業(yè)地址指針為
ldiZH,High(USARTAI_RXDAA);首個接收數據地址指針
inUSARTAI_TEMP,UDR;從USART數據寄存器取出接收數據
stZ,USARTAI_TEMP;存儲進SRAM中
adiwZL,$01;接收作業(yè)地址指針+1
stsUSARTAI_RXAPL,ZL;存儲回SRAM中
stsUSARTAI_RXAPH,ZH
MOV USARTAI_RXNum,USARTAI_TEMP;置接收作業(yè)次數計數器初值
decUSARTAI_RXNum;接收作業(yè)次數-1
rjmpUSART_RXCINT_RET;轉到中斷返回
USART_RXCINT_FCOMM:
ldiZL,Low(USARTAI_RXCOA);置接收作業(yè)地址指針為
ldiZH,High(USARTAI_RXCOA);首個接收命令地址指針
inUSARTAI_TEMP,UDR;從USART數據寄存器取出接收數據
stZ,USARTAI_TEMP;存儲進SRAM中
adiwZL,$01;接收作業(yè)地址指針+1
stsUSARTAI_RXAPL,ZL;存儲回SRAM中
stsUSARTAI_RXAPH,ZH
ldiUSARTAI_TEMP,(USARTAI_CMATNI-1)
;置接收作業(yè)次數計數器初值,
MOV USARTAI_RXNum,USARTAI_TEMP;第一個命令的字符串己接收
USART_RXCINT_RET:
popUSARTAI_TEMP;彈出堆棧中的標志值到狀態(tài)寄存器
outSREG,USARTAI_TEMP
popZH;彈出堆棧中的數值到寄存器
popZL
popUSARTAI_TEMP
reti;中斷返回
;*******************************************************************************
;*
;*USART異步通信數據寄存器空中斷發(fā)送處理子程序?。 癠SART_TXDREINT”
;*
;*說明:
;* 本子程序用于USART異步通信數據寄存器空中斷發(fā)送處理。
;*
;*注意:
;* 發(fā)送作業(yè)全部結束后,將禁止USART數據寄存器空中斷操作。
;*
;*SRAM中標志字節(jié)用法:
;* 入口標志:本子程序將檢查這些標志,依據這些標志置值來控制不同發(fā)送作業(yè)。
;*r6---發(fā)送作業(yè)次數(USARTAI_TXNum)
;* 出口標志:發(fā)送作業(yè)全部正確發(fā)送完成后,將對下面這兩個標志置值。
;*發(fā)送作業(yè)全部結束(USARTAI_TXEnd)=$f0(USARTAI_TEndI)
;*r6---發(fā)送作業(yè)次數(USARTAI_TXNum)=$00
;*
;*******************************************************************************
USART_TXDREINT:
pushUSARTAI_TEMP;壓入寄存器中的數值到堆棧
pushZL
pushZH
inUSARTAI_TEMP,SREG;壓狀態(tài)寄存器中的標志值到堆棧
pushUSARTAI_TEMP
ldsZL,USARTAI_TXAPL;置發(fā)送作業(yè)地址指針
ldsZH,USARTAI_TXAPH
ldUSARTAI_TEMP,Z;從SRAM中取出發(fā)送字節(jié),
outUDR,USARTAI_TEMP;送入USART數據寄存器
adiwZL,$01;發(fā)送作業(yè)地址指針+1
stsUSARTAI_TXAPL,ZL;存儲回SRAM中
stsUSARTAI_TXAPH,ZH
decUSARTAI_TXNum;發(fā)送作業(yè)全部完畢否?
brneUSART_TXDREINT1;否,轉到中斷返回
ldiUSARTAI_TEMP,USARTAI_TEndI;置發(fā)送作業(yè)全部結束標志值
stsUSARTAI_TXEnd,USARTAI_TEMP
cbiUCSRB,UDRIE;禁止USART數據寄存器空中斷
USART_TXDREINT1:
popUSARTAI_TEMP;彈出堆棧中的標志值到狀態(tài)寄存器
outSREG,USARTAI_TEMP
popZH;彈出堆棧中的數值到寄存器
popZL
popUSARTAI_TEMP
reti;中斷返回
;*******************************************************************************
;*
;*USART異步通信數據寄存器空中斷發(fā)送處理初始化子程序 - “USART_AINT_TXINI”
;*
;*說明:
;* 本子程序用于初始化USART異步通信數據寄存器空中斷發(fā)送處理。
;*
;*注意:
;* 1.在運行本程序前必須先運行“USART_AINT_INI”子程序。
;* 2.在運行本程序前必須先將要發(fā)送的數據塊復制到SRAM相應的存儲區(qū)中。
;* 3.本子程序運行后,將立即啟動數據寄存器空中斷,進行發(fā)送作業(yè)。
;*
;*SRAM中標志字節(jié)用法:
;* 入口標志:本子程序將檢查這些標志,依據這些標志置值來控制不同發(fā)送作業(yè)。
;*發(fā)送命令作業(yè)(USARTAI_TXCOM)=$e0(USARTAI_TCOMI)
;* 出口標志:本子程序運行后,將對下面這兩個標志置值。
;*發(fā)送作業(yè)全部結束(USARTAI_TXEnd)=$00
;*r6---發(fā)送作業(yè)次數(USARTAI_TXNum)=發(fā)送的首個字節(jié)
;*
;*******************************************************************************
USART_AINT_TXINI:
clrZL;清除全部數據發(fā)送結束標志
stsUSARTAI_TXEnd,ZL
ldsZL,USARTAI_TXCOM;發(fā)送任務是否為發(fā)送命令
cpiZL,USARTAI_TCOMI;否,則為發(fā)送數據
breqUSART_AINT_TXINI1;是,就轉至發(fā)送命令處理
ldiZL,Low(USARTAI_TXDAA);置首個發(fā)送地址指針為發(fā)送數據初值
ldiZH,High(USARTAI_TXDAA);發(fā)送的首個數據為本次發(fā)送作業(yè)次數
stsUSARTAI_TXAPL,ZL
stsUSARTAI_TXAPH,ZH
ldUSARTAI_TXNum,Z;置發(fā)送作業(yè)次數計數器初值
rjmpUSART_AINT_TXINI2
USART_AINT_TXINI1:
ldiZL,Low(USARTAI_TXCOA);置首個發(fā)送地址指針為發(fā)送命令初值
ldiZH,High(USARTAI_TXCOA);發(fā)送的首個命令為本次發(fā)送作業(yè)次數
stsUSARTAI_TXAPL,ZL
stsUSARTAI_TXAPH,ZH
ldiUSARTAI_TEMP,USARTAI_CMATNI;置發(fā)送作業(yè)次數計數器初值
MOV USARTAI_TXNum,USARTAI_TEMP;注:發(fā)送命令作業(yè)為固定次數
USART_AINT_TXINI2:
ldiZL,(1<
;與USART數據寄存器空中斷使能
ret;子程序返回
;*******************************************************************************
;*
;*向USART端口發(fā)送通信協(xié)議命令子程序清單
;*
;*說明:
;* 本子程序用于向USART端口發(fā)送通信協(xié)議命令。調用這些子程序后,將立即
;*啟動該命令的發(fā)送作業(yè)。共包括下列這些獨立的子程序。
;*
;* 向端口發(fā)送[向對方請求發(fā)送]命令---------“USART_TX_COMM_AskTX”
;* 向端口發(fā)送[允許對方發(fā)送]命令-----------“USART_TX_COMM_OKRX”
;* 向端口發(fā)送[要求對方重新發(fā)送]命令-------“USART_TX_COMM_REPTX”
;* 向端口發(fā)送[接收數據正確]命令-----------“USART_TX_COMM_DataOK”
;* 向端口發(fā)送[要求對方發(fā)送指定數據]命令---“USART_TX_COMM_DCOMTX”
;* 向端口發(fā)送[要求對方重新初始化]命令-----“USART_TX_COMM_REPINI”
;* 向端口發(fā)送[重新初始化完成]命令---------“USART_TX_COMM_RINIOK”
;*
;*******************************************************************************
;***此段程序用于發(fā)送[重新初始化完成]命令?。 癠SART_TX_COMM_RINIOK”
USART_TX_COMM_RINIOK:
rcallUSART_TXD_COMM_Head;將開頭字符串和端口編號復制到SRAM中
ldiZL,Low(USART_RINIOK*2);置Z指針為重新初始化完成命令字符串,
ldiZH,High(USART_RINIOK*2);在FLASH中的存儲地址
rcallUSART_TXD_COMM_COM;將命令字符串復制到SRAM的發(fā)送地址中,
;并置發(fā)送命令作業(yè)標志值
rcallUSART_AINT_TXINI;發(fā)送本命令字符串
ret;子程序返回
;***此段程序用于發(fā)送[要求對方重新初始化]命令?。 癠SART_TX_COMM_REPINI”
USART_TX_COMM_REPINI:
rcallUSART_TXD_COMM_Head;將開頭字符串和端口編號復制到SRAM中
ldiZL,Low(USART_REPINI*2);置Z指針為要求對方重新初始化命令字符串,
ldiZH,High(USART_REPINI*2);在FLASH中的存儲地址
rcallUSART_TXD_COMM_COM;將命令字符串復制到SRAM的發(fā)送地址中,
;并置發(fā)送命令作業(yè)標志值
rcallUSART_AINT_TXINI;發(fā)送本命令字符串
ret;子程序返回
;***此段程序用于發(fā)送[向對方請求發(fā)送]命令?。 癠SART_TX_COMM_AskTX”
USART_TX_COMM_AskTX:
rcallUSART_TXD_COMM_Head;將開頭字符串和端口編號復制到SRAM中
ldiZL,Low(USART_AskTX*2);置Z指針為向對方請求發(fā)送命令字符串,
ldiZH,High(USART_AskTX*2);在FLASH中的存儲地址
rcallUSART_TXD_COMM_COM;將命令字符串復制到SRAM的發(fā)送地址中,
;并置發(fā)送命令作業(yè)標志值
rcallUSART_AINT_TXINI;發(fā)送本命令字符串
ret;子程序返回
;***此段程序用于發(fā)送[允許對方發(fā)送]命令 - “USART_TX_COMM_OKRX”
USART_TX_COMM_OKRX:
rcallUSART_TXD_COMM_Head;將開頭字符串和端口編號復制到SRAM中
ldiZL,Low(USART_OKRX*2);置Z指針為向對方請求發(fā)送命令字符串,
ldiZH,High(USART_OKRX*2);在FLASH中的存儲地址
rcallUSART_TXD_COMM_COM;將命令字符串復制到SRAM的發(fā)送地址中,
;并置發(fā)送命令作業(yè)標志值
rcallUSART_AINT_TXINI;發(fā)送本命令字符串
ret;子程序返回
;***此段程序用于發(fā)送[要求對方重新發(fā)送]命令?。 癠SART_TX_COMM_REPTX”
USART_TX_COMM_REPTX:
rcallUSART_TXD_COMM_Head;將開頭字符串和端口編號復制到SRAM中
ldiZL,Low(USART_REPTX*2);置Z指針為向對方請求發(fā)送命令字符串,
ldiZH,High(USART_REPTX*2);在FLASH中的存儲地址
rcallUSART_TXD_COMM_COM;將命令字符串復制到SRAM的發(fā)送地址中,
;并置發(fā)送命令作業(yè)標志值
rcallUSART_AINT_TXINI;發(fā)送本命令字符串
ret;子程序返回
;***此段程序用于發(fā)送[接收數據正確]命令 - “USART_TX_COMM_DataOK”
USART_TX_COMM_DataOK:
rcallUSART_TXD_COMM_Head;將開頭字符串和端口編號復制到SRAM中
ldiZL,Low(USART_DataOK*2);置Z指針為向對方請求發(fā)送命令字符串,
ldiZH,High(USART_DataOK*2);在FLASH中的存儲地址
rcallUSART_TXD_COMM_COM;將命令字符串復制到SRAM的發(fā)送地址中,
;并置發(fā)送命令作業(yè)標志值
rcallUSART_AINT_TXINI;發(fā)送本命令字符串
ret;子程序返回
;***此段程序用于發(fā)送[要求對方發(fā)送指定數據]命令?。 癠SART_TX_COMM_DCOMTX”
USART_TX_COMM_DCOMTX:
rcallUSART_TXD_COMM_Head;將開頭字符串和端口編號復制到SRAM中
ldiZL,Low(USART_DCOMTX*2);置Z指針為向對方請求發(fā)送命令字符串,
ldiZH,High(USART_DCOMTX*2);在FLASH中的存儲地址
rcallUSART_TXD_COMM_COM;將命令字符串復制到SRAM的發(fā)送地址中,
;并置發(fā)送命令作業(yè)標志值
rcallUSART_AINT_TXINI;發(fā)送本命令字符串
ret;子程序返回
;***此段程序用于發(fā)送命令開頭字符串和端口編號?。 癠SART_TXD_COMM_Head”
USART_TXD_COMM_Head:
ldiYL,Low(USARTAI_TXCOA);置Y指針為發(fā)送命令SRAM中的地址
ldiYH,High(USARTAI_TXCOA)
ldiZL,Low(COMAgreement_Head*2);置Z指針為向發(fā)送命令開頭字符串,
ldiZH,High(COMAgreement_Head*2);在FLASH中的存儲地址
lpmUSARTAI_TEMP3,Z+;置循環(huán)計數器初值=開頭命令字長度數值
USART_TXD_COMM_Head1:
lpmUSARTAI_TEMP,Z+;從FLASH中取出發(fā)送命令開頭字符串
stY+,USARTAI_TEMP;裝入SRAM的發(fā)送命令地址中
decUSARTAI_TEMP3;命令字長度數值—1
brneUSART_TXD_COMM_Head1;裝入完成否?
USART_TXD_COMM_HeadDN:
ldiEEPROM_AddrL,Low(CC_EEPROM_DNAr)
ldiEEPROM_AddrH,High(CC_EEPROM_DNAr)
;置在EEPROM中的本端口編號地址指針
ldiUSARTAI_TEMP3,CTRLCDN_CharNI;置循環(huán)計數器初值=本端口編號長度數值
USART_TXD_COMM_HeadDN1:
callEEPROM_ReadSingle;讀取EEPROM中的本USART端口編號
MOV USARTAI_TEMP2,EEPROM_Data
stY+,USARTAI_TEMP2;裝入SRAM的發(fā)送命令地址中
adiwEEPROM_AddrL,$01;EEPROM中的端口編號地址指針+1
decUSARTAI_TEMP3;端口編號字符串長度數值長度數值—1
brneUSART_TXD_COMM_HeadDN1;端口編號裝入完否?未完,則繼續(xù)裝入
ret;子程序返回
;***此段程序用于發(fā)送命令字符串公共子程序?。 癠SART_TXD_COMM_COM”
USART_TXD_COMM_COM:
lpmUSARTAI_TEMP,Z+;從FLASH中取出首個發(fā)送命令字符
stY+,USARTAI_TEMP;裝入SRAM的發(fā)送命令地址中
lpmUSARTAI_TEMP,Z+;從FLASH中取出下一個發(fā)送命令字符
stY+,USARTAI_TEMP;裝入SRAM的發(fā)送命令地址中
lpmUSARTAI_TEMP,Z+;從FLASH中取出下一個發(fā)送命令字符
stY+,USARTAI_TEMP;裝入SRAM的發(fā)送命令地址中
ldiUSARTAI_TEMP,USARTAI_TCOMI;置發(fā)送命令作業(yè)標志值
stsUSARTAI_TXCOM,USARTAI_TEMP
ret;子程序返回
;*******************************************************************************
;*
;*從USART端口上接收到的通信協(xié)議命令處理子程序?。 癠SART_RXD_COMM”
;*
;*說明:
;* 本子程序用于從USART端口上接收到的通信協(xié)議命令處理。
;* 本子程序要在主程序中不間斷循環(huán)查詢運行。
;*
;*******************************************************************************
USART_RXD_COMM:
ldsZL,USARTAI_RXUPD;檢查接收作業(yè)是否己更新?
cpiZL,USARTAI_RUPDI;否,直接返回
breqUSART_RXD_COMMTO1;是,則繼續(xù)
rjmpUSART_RXD_COMM_RET
USART_RXD_COMMTO1:
ldsZL,USARTAI_RXCOM;檢查接收作業(yè)是否為接收命令?
cpiZL,USARTAI_RCOMI;否,直接返回
breqUSART_RXD_COMMTO2;是,則繼續(xù)
rjmpUSART_RXD_COMM_RET
USART_RXD_COMMTO2:
ldsZL,USARTAI_RXEnd;檢查接收作業(yè)是否全部結束?
cpiZL,USARTAI_REndI;否,轉至接收錯誤處理
breqUSART_RXD_COM_CAHead;是,則繼續(xù)
rjmpUSART_RXD_COMM_Error
USART_RXD_COM_CAHead:
ldiYL,Low(USARTAI_RXCOA);置首個接收命令字符地址指針
ldiYH,High(USARTAI_RXCOA)
ldiZL,Low(COMAgreement_Head*2);置通信協(xié)議命令開頭標識字符串地址指針
ldiZH,High(COMAgreement_Head*2)
lpmUSARTAI_TEMP,Z+;置循環(huán)計數器初值=開頭命令字長度數值
MOV CTRLCOM_CNT,USARTAI_TEMP
rcallCTRLCOMM_IdentifyCOM;識別通信協(xié)議命令開頭標識字符串
MOV USARTAI_TEMP,CCTSSDV_Right
cpiUSARTAI_TEMP,CCTSSDV_RightI;檢查接收字節(jié)是否為命令開頭標識字符?
breqUSART_RXD_COM_EAddr;是,則繼續(xù)
rjmpUSART_RXD_COMM_Error;否,轉至接收錯誤處理
USART_RXD_COM_EAddr:
ldiZL,Low(COMAgreement_Head*2);置通信協(xié)議命令開頭標識字符串地址指針
ldiZH,High(COMAgreement_Head*2)
lpmUSARTAI_TEMP2,Z+;讀取開頭命令字長度數值
clrUSARTAI_TEMP
addYL,USARTAI_TEMP2;置Y指針為本端口編號字符串的地址指針
adcYH,USARTAI_TEMP
ldiUSARTAI_TEMP3,CTRLCDN_CharNI;置循環(huán)計數器初值=本端口編號長度數值
ldiEEPROM_AddrL,Low(CC_EEPROM_DNAr)
ldiEEPROM_AddrH,High(CC_EEPROM_DNAr)
;置在EEPROM中的本端口編號地址指針
USART_RXD_COM_EAddr1:
callEEPROM_ReadSingle;讀取EEPROM中的本USART端口編號
MOV USARTAI_TEMP2,EEPROM_Data
ldUSARTAI_TEMP,Y+
cpUSARTAI_TEMP,USARTAI_TEMP2;檢查是否為本USART端口編號?
brneUSART_RXD_COM_EAddr2;否,轉至非本USART端口編號處理
adiwEEPROM_AddrL,$01;EEPROM中的端口編號地址指針+1
decUSARTAI_TEMP3;端口編號字符串長度數值長度數值—1
brneUSART_RXD_COM_EAddr1;端口編號識別完否?未完,則繼續(xù)識別
rjmpUSART_RXD_COMM1
USART_RXD_COM_EAddr2:
rjmpUSART_RXD_COMM_NOADDR
USART_RXD_COMM1:
ldiZL,Low(USART_AskTX*2);置“向我方請求發(fā)送數據”命令地址指針
ldiZH,High(USART_AskTX*2)
ldiCTRLCOM_CNT,USARTAI_CMANI;置計數器初值=有效命令字長度數值
rcallCTRLCOMM_IdentifyCOM;對此條命令進行識別
cpiCCTSSDV_Right,CCTSSDV_RightI;命令是否為“向我方請求發(fā)送數據”?
brneUSART_RXD_COMM2;否,則繼續(xù)
rcallUSART_RX_COMM_AskTX;是,調用處理此條命令處理程序
rjmpUSART_RXD_COMM_RET
USART_RXD_COMM2:
ldiZL,Low(USART_DataOK*2);置“對方接收數據正確”命令地址指針
ldiZH,High(USART_DataOK*2)
ldiCTRLCOM_CNT,USARTAI_CMANI;置計數器初值=有效命令字長度數值
rcallCTRLCOMM_IdentifyCOM;對此條命令進行識別
cpiCCTSSDV_Right,CCTSSDV_RightI;命令是否為“對方接收數據正確”?
brneUSART_RXD_COMM3;否,則繼續(xù)
rcallUSART_RX_COMM_DataOK;是,調用處理此條命令處理程序
rjmpUSART_RXD_COMM_RET
USART_RXD_COMM3:
ldiZL,Low(USART_REPTX*2);置“要求我方重新發(fā)送”命令地址指針
ldiZH,High(USART_REPTX*2)
ldiCTRLCOM_CNT,USARTAI_CMANI;置計數器初值=有效命令字長度數值
rcallCTRLCOMM_IdentifyCOM;對此條命令進行識別
cpiCCTSSDV_Right,CCTSSDV_RightI;命令是否為“要求我方重新發(fā)送”?
brneUSART_RXD_COMM4;否,則繼續(xù)
rcallUSART_RX_COMM_REPTX;是,調用處理此條命令處理程序
rjmpUSART_RXD_COMM_RET
USART_RXD_COMM4:
ldiZL,Low(USART_DCOMTX*2);置“要求我方發(fā)送指定數據”命令地址指針
ldiZH,High(USART_DCOMTX*2)
ldiCTRLCOM_CNT,USARTAI_CMANI;置計數器初值=有效命令字長度數值
rcallCTRLCOMM_IdentifyCOM;對此條命令進行識別
cpiCCTSSDV_Right,CCTSSDV_RightI;命令是否為“要求我方發(fā)送指定數據”?
brneUSART_RXD_COMM5;否,則繼續(xù)
rcallUSART_RX_COMM_DCOMTX;是,調用處理此條命令處理程序
rjmpUSART_RXD_COMM_RET
USART_RXD_COMM5:
ldiZL,Low(USART_OKRX*2);置“允許我方發(fā)送數據”命令地址指針
ldiZH,High(USART_OKRX*2)
ldiCTRLCOM_CNT,USARTAI_CMANI;置計數器初值=有效命令字長度數值
rcallCTRLCOMM_IdentifyCOM;對此條命令進行識別
cpiCCTSSDV_Right,CCTSSDV_RightI;命令是否為“允許我方發(fā)送數據”?
brneUSART_RXD_COMM6;否,則繼續(xù)
rcallUSART_RX_COMM_OKRX;是,調用處理此條命令處理程序
rjmpUSART_RXD_COMM_RET
USART_RXD_COMM6:
ldiZL,Low(USART_REPINI*2);置“要求我方重新初始化”命令地址指針
ldiZH,High(USART_REPINI*2)
ldiCTRLCOM_CNT,USARTAI_CMANI;置計數器初值=有效命令字長度數值
rcallCTRLCOMM_IdentifyCOM;對此條命令進行識別
cpiCCTSSDV_Right,CCTSSDV_RightI;命令是否為“要求我方重新初始化”?
brneUSART_RXD_COMM7;否,則繼續(xù)
rcallUSART_RX_COMM_REPINI;是,調用處理此條命令處理程序
rjmpUSART_RXD_COMM_RET
USART_RXD_COMM7:
ldiZL,Low(USART_RINIOK*2);置“對方重新初始化完成”命令地址指針
ldiZH,High(USART_RINIOK*2)
ldiCTRLCOM_CNT,USARTAI_CMANI;置計數器初值=有效命令字長度數值
rcallCTRLCOMM_IdentifyCOM;對此條命令進行識別
cpiCCTSSDV_Right,CCTSSDV_RightI;命令是否為“對方重新初始化完成”?
brneUSART_RXD_COMM8;否,則繼續(xù)
rcallUSART_RX_COMM_RINIOK;是,調用處理此條命令處理程序
rjmpUSART_RXD_COMM_RET
USART_RXD_COMM8:
ldiZL,Low(USART_CTRLCOM*2);置“傳送控制操作指令”命令地址指針
ldiZH,High(USART_CTRLCOM*2)
ldiCTRLCOM_CNT,USARTAI_CMANI;置計數器初值=有效命令字長度數值
rcallCTRLCOMM_IdentifyCOM;對此條命令進行識別
cpiCCTSSDV_Right,CCTSSDV_RightI;命令是否為“傳送控制操作指令”?
brneUSART_RXD_COMM_Error;否,轉至接收錯誤處理
rcallUSART_RX_COMM_CTRLCOM;是,調用處理此條命令處理程序
rjmpUSART_RXD_COMM_RET
USART_RXD_COMM_Error:
rcallUSART_RXD_Error;調用接收錯誤處理子程序
rjmpUSART_RXD_COMM_RET
USART_RXD_COMM_NOADDR:
clrZL;清除接收作業(yè)己更新標志
stsUSARTAI_RXUPD,ZL
USART_RXD_COMM_RET:
ret;子程序返回
;***此段程序用于接收到[傳送控制操作指令]命令處理
USART_RX_COMM_CTRLCOM:
ldsZL,DataUPD_RXALW;接收數據是否己處理?
cpiZL,DataUPD_RALWI;是,繼續(xù)
breqUSART_RX_COMM_CTRLCOM_RET;否,返回,等待處理接收數據
ldsZL,USARTAI_TXEnd;發(fā)送作業(yè)是否全部結束?
cpiZL,USARTAI_TEndI;是,繼續(xù)
brneUSART_RX_COMM_CTRLCOM_RET;否,返回,等待發(fā)送作業(yè)結束
ldsZL,CTRLCOM_MALWS;是否有正在處理控制操作指令?
cpiZL,CTRLCOM_MALWSI;否,繼續(xù)
breqUSART_RX_COMM_CTRLCOM_RET;是,返回,等待處理控制操作指令結束
rcallUSART_TX_COMM_OKRX;向對方發(fā)送“允許對方發(fā)送”命令
clrZL;清除接收命令作業(yè)標志
stsUSARTAI_RXCOM,ZL
ldiZL,CTRLCOM_MALWSI;置允許處理控制操作指令標志值
stsCTRLCOM_MALWS,ZL
ldiZL,CCTSSDV_USARTI;置控制操作指令發(fā)送者標志值
stsCCOM_TSourceS,ZL;為USART端口送來控制操作指令
clrZL;清除接收作業(yè)己更新標志
stsUSARTAI_RXUPD,ZL
USART_RX_COMM_CTRLCOM_RET:
ret;子程序返回
;***此段程序用于接收到[重新初始化完成]命令處理
USART_RX_COMM_RINIOK:
clrZL;清除接收作業(yè)己更新標志
stsUSARTAI_RXUPD,ZL
ret;子程序返回
;***此段程序用于接收到[要求對方重新初始化]命令處理
USART_RX_COMM_REPINI:
ldiZH,(1<
inZL,UCSRB;接收結束中斷和數據寄存器空中斷
andZL,ZH
outUCSRB,ZL
;此處插入從頭開始重新進行數據處理操作程序
ldiZH,(1<
inZL,UCSRA;及奇偶校驗錯誤(UPE)標志
andZL,ZH
outUCSRA,ZL
ldiZH,(1<
orZL,ZH
outUCSRA,ZL
rcallUSART_AINT_INI;重新初始化USART異步中斷接收和發(fā)送
rcallUSART_TX_COMM_RINIOK;向對方發(fā)送“重新初始化完成”命令
ret;子程序返回
;***此段程序用于接收到[向對方請求發(fā)送]命令處理
USART_RX_COMM_AskTX:
ldsZL,DataUPD_RXALW;接收數據是否己處理?
cpiZL,DataUPD_RALWI;是,繼續(xù)
breqUSART_RX_COMM_AskTX_RET;否,返回,等待處理接收數據
ldsZL,USARTAI_TXEnd;發(fā)送作業(yè)是否全部結束?
cpiZL,USARTAI_TEndI;是,繼續(xù)
brneUSART_RX_COMM_AskTX_RET;否,返回,等待發(fā)送作業(yè)結束
rcallUSART_TX_COMM_OKRX;向對方發(fā)送“允許對方發(fā)送”命令
clrZL;清除接收命令作業(yè)標志
stsUSARTAI_RXCOM,ZL
ldiZL,DataUPD_RALWI;置允許處理接收數據標志值
stsDataUPD_RXALW,ZL
clrZL;清除接收作業(yè)己更新標志
stsUSARTAI_RXUPD,ZL
USART_RX_COMM_AskTX_RET:
ret;子程序返回
;***此段程序用于接收到[允許對方發(fā)送]命令處理
USART_RX_COMM_OKRX:
ldsZL,DataUPD_TXALW;發(fā)送數據是否己更新?
cpiZL,DataUPD_TALWI;是,繼續(xù)
breqUSART_RX_COMM_OKRX_RET;否,返回,等待更新發(fā)送數據
ldsZL,USARTAI_TXEnd;發(fā)送作業(yè)是否全部結束?
cpiZL,USARTAI_TEndI;是,繼續(xù)
brneUSART_RX_COMM_OKRX_RET;否,返回,等待發(fā)送作業(yè)結束
clrZL;清除發(fā)送命令作業(yè)標志
stsUSARTAI_TXCOM,ZL
rcallUSART_AINT_TXINI;啟動發(fā)送數據
clrZL;清除接收作業(yè)己更新標志
stsUSARTAI_RXUPD,ZL
USART_RX_COMM_OKRX_RET:
ret;子程序返回
;***此段程序用于接收到[要求對方重新發(fā)送]命令處理
USART_RX_COMM_REPTX:
ldsZL,USARTAI_ERRNum;USART發(fā)生收發(fā)錯誤次數是否超過允許次數?
cpiZL,USARTAI_ENALWI;是,轉至USART通信發(fā)生錯誤處理
brloUSART_RX_COMM_REPTX1;否,繼續(xù)
rcallUSART_Error;調用USART通信發(fā)生錯誤處理程序
rjmpUSART_RX_COMM_REPTX_RET;返回
USART_RX_COMM_REPTX1:
ldsZL,USARTAI_TXEnd;發(fā)送作業(yè)是否全部結束?
cpiZL,USARTAI_TEndI;是,繼續(xù)
brneUSART_RX_COMM_REPTX_RET;否,返回,等待發(fā)送作業(yè)結束
rcallUSART_AINT_TXINI;重新啟動原發(fā)送作業(yè)
clrZL;清除接收作業(yè)己更新標志
stsUSARTAI_RXUPD,ZL
ldsZL,USARTAI_ERRNum;USART發(fā)生收發(fā)錯誤次數+1
incZL
stsUSARTAI_ERRNum,ZL
USART_RX_COMM_REPTX_RET:
ret;子程序返回
;***此段程序用于接收到[接收數據正確]命令處理
USART_RX_COMM_DataOK:
ldiZL,USARTAI_TCOMI;置發(fā)送命令作業(yè)標志值
stsUSARTAI_TXCOM,ZL
ldiZL,DataUPD_TALWI;置允許更新發(fā)送數據標志值
stsDataUPD_TXALW,ZL
clrZL;清除接收作業(yè)己更新標志
stsUSARTAI_RXUPD,ZL
ret;子程序返回
;***此段程序用于接收到[要求對方發(fā)送指定數據]命令處理
USART_RX_COMM_DCOMTX:
ldiZL,DataUPD_TALWI;置允許更新發(fā)送數據標志值
stsDataUPD_TXALW,ZL
clrZL;清除接收作業(yè)己更新標志
stsUSARTAI_RXUPD,ZL
USART_RX_COMM_DCOMTX_RET:
ret;子程序返回
;***此段程序用于“USART接收器錯誤”和“接收命令或數據錯誤”處理
USART_RXD_Error:
ldsZL,USARTAI_ERRNum;USART發(fā)生收發(fā)錯誤次數是否超過允許次數?
cpiZL,USARTAI_ENALWI;是,轉至USART通信發(fā)生錯誤處理
brloUSART_RXD_Error1;否,繼續(xù)
rcallUSART_Error;調用USART通信發(fā)生錯誤處理程序
rjmpUSART_RXD_Error_RET;返回
USART_RXD_Error1:
ldsZL,USARTAI_TXEnd;發(fā)送作業(yè)是否全部結束?
cpiZL,USARTAI_TEndI;是,繼續(xù)
brneUSART_RXD_Error_RET;否,返回,等待發(fā)送作業(yè)結束
rcallUSART_TX_COMM_REPTX;向對方發(fā)送“要求重新發(fā)送”命令
ldiZH,(1<
inZL,UCSRA;及奇偶校驗錯誤(UPE)標志
andZL,ZH
outUCSRA,ZL
ldiZL,USARTAI_REndI;置接收作業(yè)全部結束標志值
stsUSARTAI_RXEnd,ZL
clrZL;清除接收作業(yè)己更新標志
stsUSARTAI_RXUPD,ZL
ldsZL,USARTAI_ERRNum;USART發(fā)生收發(fā)錯誤次數+1
incZL
stsUSARTAI_ERRNum,ZL
USART_RXD_Error_RET:
ret;子程序返回
;*******************************************************************************
;*
;*從USART端口上接收到的數據處理子程序 - “USART_RXD_Data”
;*
;*說明:
;* 本子程序用于處理從USART端口上接收到的數據,本子程序中包含有數據循環(huán)
;*冗余檢測校驗子程序。
;* 本子程序要在主程序中不間斷循環(huán)查詢運行。
;*
;*SRAM中標志字節(jié)用法:
;* 入口標志:本子程序將檢查這三個標志,只有這三個標志置值后才允許處理數據。
;*允許處理接收數據(DataUPD_RXALW)=$03(DataUPD_RDALWI)
;*接收作業(yè)己更新(USARTAI_RXUPD)=$0a(USARTAI_RUPDI)
;*接收作業(yè)全部結束(USARTAI_RXEnd)=$0f(USARTAI_REndI)
;* 出口標志:接收數據處理操作得到執(zhí)行后,將對下面這兩個標志置值。
;*允許處理接收數據(DataUPD_RXALW)=$00
;*接收作業(yè)己更新(USARTAI_RXUPD)=$00
;*
;*******************************************************************************
USART_RXD_Data:
ldsZL,DataUPD_RXALW;檢查是否允許處理接收數據?
cpiZL,DataUPD_RALWI;是,則繼續(xù)
brneUSART_RXD_Data_RET;否,直接返回
ldsZL,USARTAI_RXUPD;檢查接收作業(yè)是否己更新?
cpiZL,USARTAI_RUPDI;是,則繼續(xù)
brneUSART_RXD_Data_RET;否,直接返回
ldsZL,USARTAI_TXEnd;發(fā)送作業(yè)是否全部結束?
cpiZL,USARTAI_TEndI;是,繼續(xù)
brneUSART_RXD_Data_RET;否,返回,等待發(fā)送作業(yè)結束
ldsZL,USARTAI_RXEnd;檢查接收作業(yè)是否全部結束?
cpiZL,USARTAI_REndI;是,則繼續(xù)
brneUSART_RXD_Data_Error;否,轉至接收錯誤處理
USART_RXD_Data_Check:
ldiZL,Low(USARTAI_RXDAA);Z指針指向接收數據的首字節(jié)
ldiZH,High(USARTAI_RXDAA)
ldsDCRC2B_DLength,USARTAI_RXDAA;置校驗的數據長度初值
callDataCheck_CRC2B;校驗接收的數據是否正確?
orYL,YH;是,繼續(xù)
brneUSART_RXD_Data_Error;否,轉至接收錯誤處理
rcallUSART_TX_COMM_DataOK;向對方發(fā)送“接收數據正確”命令
ldiZL,USARTAI_RCOMI;置接收命令作業(yè)標志值
stsUSARTAI_RXCOM,ZL
rcallUSART_RXData_Process;調用接收數據處理子程序
clrZL;清除接收作業(yè)己更新標志
stsUSARTAI_RXUPD,ZL
clrZL;清除允許處理接收數據標志
stsDataUPD_RXALW,ZL
rjmpUSART_RXD_Data_RET;返回
USART_RXD_Data_Error:
rcallUSART_RXD_Error;調用接收錯誤處理子程序
USART_RXD_Data_RET:
ret;子程序返回
;***此段程序用于對從USART端口上接收到的數據進行處理操作
USART_RXData_Process:
;此處插入接收數據處理程序
ret;子程序返回
;*******************************************************************************
;*
;*向USART端口上發(fā)送數據更新子程序 - “USART_TXD_Data”
;*
;*說明:
;* 本子程序用于更新向USART端口上上發(fā)送數據,本子程序中包含有數據循環(huán)
;*冗余檢測校驗子程序。
;* 本子程序要在主程序中不間斷循環(huán)查詢運行。
;*
;*SRAM中標志字節(jié)用法:
;* 入口標志:本子程序將檢查這個標志,只有這個標志置值后才允許更新數據。
;*允許更新發(fā)送數據(DataUPD_TXALW)=$c0(DataUPD_TALWI)
;* 出口標志:更新發(fā)送數據操作得到執(zhí)行后,將對下面這個標志置值。
;*允許更新發(fā)送數據(DataUPD_TXALW)=$00
;*
;*******************************************************************************
USART_TXD_Data:
ldsZL,DataUPD_TXALW;檢查是否允許更新發(fā)送數據?
cpiZL,DataUPD_TALWI;是,則繼續(xù)
brneUSART_TXD_Data_RET;否,直接返回
ldsZL,USARTAI_TXEnd;發(fā)送作業(yè)是否全部結束?
cpiZL,USARTAI_TEndI;是,繼續(xù)
brneUSART_TXD_Data_RET;否,返回,等待發(fā)送作業(yè)結束
rcallUSART_TX_COMM_AskTX;發(fā)送“向對方請求發(fā)送”命令
rcallUSART_TXData_Process;調用更新發(fā)送數據子程序
USART_TXD_Data_Check:
ldsZL,USARTAI_TXDAA;取發(fā)送的數據長度值
adiwZL,$03;發(fā)送的總長度=發(fā)送的數據長度值+
stsUSARTAI_TXDAA,ZL;1個長度字符字節(jié)+2個校驗字節(jié)
MOV USARTAI_TEMP2,ZL
ldiZL,Low(USARTAI_TXDAA-2);發(fā)送數據的校驗字節(jié)在發(fā)送數據序列
ldiZH,High(USARTAI_TXDAA-2);尾部后兩個字節(jié)
clrUSARTAI_TEMP
addZL,USARTAI_TEMP2;Z指針指向發(fā)送數據的校驗字節(jié)
adcZH,USARTAI_TEMP
clrUSARTAI_TEMP
stZ+,USARTAI_TEMP;清除發(fā)送數據的尾部后兩個字節(jié)
stZ+,USARTAI_TEMP;的校驗字節(jié)值
ldiZL,Low(USARTAI_TXDAA);Z指針指向發(fā)送數據首個字節(jié)
ldiZH,High(USARTAI_TXDAA)
ldsDCRC2B_DLength,USARTAI_TXDAA;置校驗的數據長度初值
callDataCheck_CRC2B;生成發(fā)送數據序列的CRC碼
clrZL;清除允許更新發(fā)送數據標志
stsDataUPD_TXALW,ZL
USART_TXD_Data_RET:
ret;子程序返回
;***此段程序用于向USART端口上發(fā)送數據的更新操作
USART_TXData_Process:
;此處插入更新發(fā)送數據程序
;此段程序為示例數據的更新操作
MOV USARTAI_TEMP,r3
ldiUSARTAI_TEMP2,$fc
stsUSARTAI_TXDAA,USARTAI_TEMP2
ldiYL,Low(USARTAI_TXDAA+1);置接收作業(yè)地址指針為
ldiYH,High(USARTAI_TXDAA+1);首個接收數據地址指針
USART_TXData_Process1:
stY+,USARTAI_TEMP
incUSARTAI_TEMP
decUSARTAI_TEMP2
brneUSART_TXData_Process1
incr3
;示例程序結束
ret;子程序返回
;*******************************************************************************
;*
;*USART通信發(fā)生錯誤處理子程序?。 癠SART_Error”
;*
;*說明:
;* 本子程序用于當USART通信發(fā)生錯誤時的處理。
;*
;*******************************************************************************
USART_Error:
pushZL;壓入寄存器中的數值到堆棧
pushZH
inZL,SREG;壓狀態(tài)寄存器中的標志值到堆棧
pushZL
ldiZH,(1<
inZL,UCSRB;接收結束中斷和數據寄存器空中斷
andZL,ZH
outUCSRB,ZL
;此處插入錯誤處理程序
;此處插入從頭開始重新進行數據處理操作程序
ldiZH,(1<
inZL,UCSRA;及奇偶校驗錯誤(UPE)標志
andZL,ZH
outUCSRA,ZL
ldiZH,(1<
orZL,ZH
outUCSRA,ZL
callUSART_AINT_INI;重新初始化USART異步中斷接收和發(fā)送
callUSART_TX_COMM_REPINI;向對方發(fā)送“要求其重新初始化”命令
USART_Error_RET:
popZL
outSREG,ZL;彈出堆棧中的標志值到狀態(tài)寄存器
popZH;彈出堆棧中的數值到寄存器
popZL
ret;子程序返回
;*******************************************************************************
;*
;*所有通信協(xié)議命令開頭標識字符串?。 癈OMAgreement_Head”
;*
;*******************************************************************************
COMAgreement_Head:
.DB$03,"COM";通信協(xié)議命令開頭標識字符(COM)
;││
;│通信協(xié)議命令開頭標識字符(COM)
;本指令字符串字符長度數值(不包括自已在內共3個字符)
;*******************************************************************************
;*
;*向對方請求發(fā)送命令字符串?。 癠SART_AskTX”
;*
;*******************************************************************************
USART_AskTX:
.DB"ATX";向對方請求發(fā)送命令字符串(ATX)
;*******************************************************************************
;*
;*允許對方發(fā)送命令字符串 - “USART_OKRX”
;*
;*******************************************************************************
USART_OKRX:
.DB"YET";允許對方發(fā)送命令字符串(YET)
;*******************************************************************************
;*
;*要求對方重新發(fā)送命令字符串?。 癠SART_REPTX”
;*
;*******************************************************************************
USART_REPTX:
.DB"RPT";要求對方重新發(fā)送命令字符串(RPT)
;*******************************************************************************
;*
;*接收數據正確命令字符串?。 癠SART_DataOK”
;*
;*******************************************************************************
USART_DataOK:
.DB"OKD";接收數據正確命令字符串(OKD)
;*******************************************************************************
;*
;*要求對方發(fā)送指定數據的命令字符串 - “USART_DCOMTX”
;*
;*******************************************************************************
USART_DCOMTX:
.DB"STD";要求對方發(fā)送指定數據的命令字符串(STD)
;*******************************************************************************
;*
;*要求對方重新初始化USART端口狀態(tài)命令字符串?。 癠SART_REPINI”
;*
;*******************************************************************************
USART_REPINI:
.DB"RII";要求對方重新初始化狀態(tài)命令字符串(RII)
;*******************************************************************************
;*
;*重新初始化USART端口狀態(tài)完成命令字符串?。 癠SART_RINIOK”
;*
;*******************************************************************************
USART_RINIOK:
.DB"YRI";重新初始化狀態(tài)完成命令字符串(YRI)
;*******************************************************************************
;*
;*從USART端口傳送控制操作指令命令字符串?。 癠SART_CTRLCOM”
;*
;*******************************************************************************
USART_CTRLCOM:
.DB"CIT";從端口傳送控制操作指令命令字符串(CIT)
;*******************************************************************************
;*
;*USART異步通信中斷接收與發(fā)送協(xié)議命令和數據處理子程序?。 癠SART_INT_ACOM”
;*
;*說明:
;* 本子程序用于USART異步通信中斷接收與發(fā)送協(xié)議命令和數據處理。
;* 本子程序要在主程序中不間斷地循環(huán)運行。
;*
;*******************************************************************************
USART_INT_ACOM:
inZL,SREG;壓狀態(tài)寄存器中的標志值到堆棧
pushZL
callUSART_RXD_COMM;接收通信協(xié)議命令處理程序
callUSART_RXD_Data;調用接收數據處理程序
callUSART_TXD_Data;調用更新發(fā)送數據程序
popZL;彈出堆棧中的標志值到狀態(tài)寄存器
outSREG,ZL
ret;子程序返回
;*******************************************************************************
;*
;*定時器/計數器0溢出中斷處理子程序?。 癟C0_Timer_OVFINT”
;*
;*說明:
;* 本子程序用于約束接收作業(yè)全部完成(指從接收第一個數據到最后一個數據之間)
;*的時間范圍,如果在規(guī)定的時間內沒有接收作業(yè)全部完成,則強制結束此次接收作業(yè),
;*以便下次接收作業(yè)正確操作。此程序主要用于檢查第一個的數據長度字節(jié)的數值與所接
;*收到的數據幀數是否匹配,避免由于不匹配而產生的錯誤死循環(huán)。也用于接收端受干擾
;*后能夠及時恢復正確操作接收作業(yè)標志值。
;*
;*注意:
;* 本子程序在多次執(zhí)行到T/C0計數溢出次數超出設置數值后,將禁止定時器/計
;*數器0溢出中斷。
;*
;*SRAM中標志字節(jié)用法:
;* 出口標志:
;* 接收作業(yè)己更新(USARTAI_RXUPD)=$0a(USARTAI_RUPDI)
;*
;*******************************************************************************
TC0_Timer_OVFINT:
pushZL;壓入寄存器中的數值到堆棧
pushZH
inZL,SREG;壓狀態(tài)寄存器中的標志值到堆棧
pushZL
ldiZL,USARTAI_T0CNTI;置T/C0定時參數的預定計數比例值
outTCNT0,ZL
ldsZL,USARTAI_T0VNum;檢查T/C0計數溢出次數是否超出設置值?
cpiZL,USARTAI_T0NumI;是,執(zhí)行超出次數處理操作
brloTC0_Timer_OVFINT1;否,轉至繼續(xù)
ldiZL,USARTAI_RUPDI;置接收作業(yè)己更新標志值
stsUSARTAI_RXUPD,ZL
ldiZH,(1<
inZL,TIMSK;器中的此項設置,對于其他T/C
andZL,ZH;中斷狀態(tài)保留原來設置
outTIMSK,ZL
rjmpTC0_Timer_OVFINT_RET;返回
TC0_Timer_OVFINT1:
incZL;T/C0計數溢出次數+1
stsUSARTAI_T0VNum,ZL
TC0_Timer_OVFINT_RET:
popZL
outSREG,ZL;彈出堆棧中的標志值到狀態(tài)寄存器
popZH;彈出堆棧中的數值到寄存器
popZL
reti;中斷返回





