日本黄色一级经典视频|伊人久久精品视频|亚洲黄色色周成人视频九九九|av免费网址黄色小短片|黄色Av无码亚洲成年人|亚洲1区2区3区无码|真人黄片免费观看|无码一级小说欧美日免费三级|日韩中文字幕91在线看|精品久久久无码中文字幕边打电话

當前位置:首頁 > 單片機 > 單片機
[導讀] ;*******************************************************************************;*;*子程序名:USART_AINT.asm;*程序名稱:通用同步和異步串行接收器和轉發(fā)器(USART);*異步中斷接收和發(fā)送通信程序;*

;*******************************************************************************
;*
;*子程序名: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<;設置幀格式:8個數據位,1個停止位,
;并使能奇校驗。USART異步模式
;ldiZL,(1<;設置幀格式:8個數據位,2個停止位,
;并使能奇校驗。USART異步模式
outUCSRC,ZL
ldiZL,(1<outUCSRB,ZL;接收器與發(fā)送器使能和接收結束中斷使能
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<inUSARTAI_TEMP,UCSRA;數據溢出(DOR)及奇偶校驗錯誤(UPE)
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<comZH;注:僅只改變T/C中斷屏蔽寄存
inZL,TIMSK;器中的此項設置,對于其他T/C
andZL,ZH;中斷狀態(tài)保留原來設置
outTIMSK,ZL
rjmpUSART_RXCINT_RET;轉到中斷返回
USART_RXCINT_Error:
ldiZH,(1<comZH;注:僅只改變T/C中斷屏蔽寄存
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<outTIFR,ZL;器中的此項標志,對于其他T/C
;中斷標志保留原來狀態(tài)
ldiZL,USARTAI_T0CNTI;置T/C0定時參數的預定計數比例值
outTCNT0,ZL
inZL,TIMSK;使能T/C0計數溢出中斷
oriZL,(1<outTIMSK,ZL;器中的此項設置,對于其他T/C
;中斷狀態(tài)保留原來設置
ldiZL,(1<outTCCR0,ZL;按CK÷1024預分頻因子啟動T/C0
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<outUCSRB,ZL;接收器與發(fā)送器使能和接收結束中斷、
;與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<comZH;禁止接收器和發(fā)送器,禁止USART
inZL,UCSRB;接收結束中斷和數據寄存器空中斷
andZL,ZH
outUCSRB,ZL


;此處插入從頭開始重新進行數據處理操作程序


ldiZH,(1<comZH;清除幀錯誤(FE)、數據溢出(DOR)
inZL,UCSRA;及奇偶校驗錯誤(UPE)標志
andZL,ZH
outUCSRA,ZL
ldiZH,(1<inZL,UCSRA;置數據寄存器空(UDRE)標志
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<comZH;清除幀錯誤(FE)、數據溢出(DOR)
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<comZH;禁止接收器和發(fā)送器,禁止USART
inZL,UCSRB;接收結束中斷和數據寄存器空中斷
andZL,ZH
outUCSRB,ZL


;此處插入錯誤處理程序
;此處插入從頭開始重新進行數據處理操作程序


ldiZH,(1<comZH;清除幀錯誤(FE)、數據溢出(DOR)
inZL,UCSRA;及奇偶校驗錯誤(UPE)標志
andZL,ZH
outUCSRA,ZL
ldiZH,(1<inZL,UCSRA;置數據寄存器空(UDRE)標志
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<comZH;注:僅只改變T/C中斷屏蔽寄存
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;中斷返回

本站聲明: 本文章由作者或相關機構授權發(fā)布,目的在于傳遞更多信息,并不代表本站贊同其觀點,本站亦不保證或承諾內容真實性等。需要轉載請聯(lián)系該專欄作者,如若文章內容侵犯您的權益,請及時聯(lián)系本站刪除。
換一批
延伸閱讀

在這篇文章中,小編將對PLC的相關內容和情況加以介紹以幫助大家增進對它的了解程度,和小編一起來閱讀以下內容吧。

關鍵字: PLC 模塊化 程序

在這篇文章中,小編將為大家?guī)韱纹瑱C的相關報道。如果你對本文即將要講解的內容存在一定興趣,不妨繼續(xù)往下閱讀哦。

關鍵字: 單片機 AVR PIC

在現(xiàn)代工業(yè)和汽車領域,控制器局域網(CAN)總線作為一種可靠且高效的通信方式,廣泛應用于各種電子設備之間的數據傳輸。在 CAN 總線系統(tǒng)中,有一個看似毫不起眼卻至關重要的元件 ——120Ω 終端電阻。這個小小的電阻,對于...

關鍵字: 控制器局域網 總線 通信

8月14日消息,今天,國務院新聞辦公室舉行“高質量完成‘十四五’規(guī)劃”系列主題新聞發(fā)布會,國家數據局介紹“十四五”時期數字中國建設發(fā)展成就。

關鍵字: 算力 通信

北京2025年8月8日 /美通社/ -- 8月7日,浪潮信息發(fā)布面向萬億參數大模型的超節(jié)點AI服務器"元腦SD200"。該產品基于浪潮信息創(chuàng)新研發(fā)的多主機低延遲內存語義通信架構,以開放系統(tǒng)設計向上擴展...

關鍵字: 模型 節(jié)點 SD 通信

在現(xiàn)代通信技術的復雜網絡中,射頻(RF)濾波器猶如一位幕后英雄,雖鮮少被大眾提及,卻發(fā)揮著舉足輕重的作用。從我們日常使用的智能手機,到構建通信基礎設施的基站,再到新興的物聯(lián)網設備,RF 濾波器無處不在,默默保障著信號的順...

關鍵字: 射頻 濾波器 通信

在當今數字化時代,5G 通信技術以前所未有的速度改變著我們的生活,從高速的數據傳輸到實時的物聯(lián)網應用,5G 的影響力無處不在。然而,在這一系列令人矚目的技術背后,有一個常常被忽視卻至關重要的角色 —— 晶振。它如同幕后的...

關鍵字: 通信 數據傳輸 晶振

德國斯圖加特 2025年7月2日 /美通社/ -- 國際關鍵通信協(xié)會The Critical Communications Association (以下簡稱TCCA)宣布...

關鍵字: 通信 TETRA TC 測試流程

近日,歐洲統(tǒng)一專利法院曼海姆分庭更新的一則訴訟信息,引發(fā)了全球科技界震動——聯(lián)發(fā)科子公司HFI Innovation起訴了華為旗下五家子公司侵犯其LTE專利EP2689624。這場訴訟標志著兩家科技巨頭持續(xù)兩年的專利糾紛...

關鍵字: 通信

為了進一步推動電子通信半導體產業(yè)創(chuàng)新發(fā)展,“EIS 2025 中國電子通信半導體數智創(chuàng)新峰會", 以 “智聯(lián)萬物·芯創(chuàng)未來 ”為主題, 將于 2025 年 10月 24日在上海隆重舉辦。

關鍵字: 通信 半導體
關閉