;******************************************************************************* ;* ;* 子程序名: USART_AINT.asm ;* 程序名称: 通用同步和异步串行接收器和转发器(USART) ;* 异步中断接收和发送通信程序 ;* 版本: 1.0 ;* 适用 MCU 型号: AVR所有型号 ;* 使用资源: r5,r6,r16,r17,r18,r19,r20,r28,r29,r30,r31 ;* 定时器/计数器0(溢出中断) ;* ;* 程序功能: ;*   本程序是通用同步和异步串行接收器和转发器(USART)在异步状态下使用中断 ;* 方式进行全双工接收和发送数据的通信程序。共包括下面列表中这四个子程序。这 ;* 四个子程序的具体使用方法请参考各自的说明。 ;* ┏───────────┳───────────────────────┓ ;* ┃ 子程序名称 ┃ 子程序功能描述 ┃ ;* ┣───────────╋───────────────────────┫ ;* ┃ USART_AINT_INI ┃ USART 异步通信中断接收和发送初始化 ┃ ;* ┣───────────╋───────────────────────┫ ;* ┃ USART_INT_ACOM ┃USART 异步通信中断接收与发送协议命令和数据处理┃ ;* ┣───────────╋───────────────────────┫ ;* ┃ USART_RXCINT ┃ USART 异步通信接收结束中断处理 ┃ ;* ┣───────────╋───────────────────────┫ ;* ┃ USART_TXDREINT ┃ USART 异步通信数据寄存器空中断发送处理 ┃ ;* ┗───────────┻───────────────────────┛ ;* ;* 注意: ;*   ①.r5 (USARTAI_RXNum)《接收作业次数寄存器》和 r6 (USARTAI_TXNum) ;* 《发送作业次数寄存器》为全局寄存器变量,不得被其他程序使用,否则将导致接收 ;* 和发送的数据错误。 ;*   ②.本程序共使用了3个中断向量,需在主程序中设置其中断向量转移地址,分 ;* 别为如下具体设置: ;* ┏─────────────┳───────┳─────────────┓ ;* ┃ 中断名称 ┃ 中断向量地址 ┃ 中断处理程序 ┃ ;* ┣─────────────╋───────╋─────────────┫ ;* ┃ USART 接收结束中断 ┃ URXCaddr ┃ USART_RXCINT ┃ ;* ┣─────────────╋───────╋─────────────┫ ;* ┃ USART 数据寄存器空中断 ┃ UDREaddr ┃ USART_TXDREINT ┃ ;* ┣─────────────╋───────╋─────────────┫ ;* ┃ T/C0溢出中断 ┃ OVF0addr ┃ TC0_Timer_OVFINT ┃ ;* ┗─────────────┻───────┻─────────────┛ ;* ;* 通信协议: ;*   ①.每次进行接收和发送的作业时均以协议命令来决定下一步操作方式,关于通信 ;* 协议命令的约定方法请见下述详细说明和命令字符串的具体定义。接收和发送的命令 ;* 的数据字节长度固定为 10 个字节,其格式定义如下:COM(命令起始标识字符串)+ ;* 设备编号(4 个字节)+ 命令字(3 个字节)。 ;*   ②.接收或发送的数据帧格式:“8 个数据位, 1 个停止位,使用奇校验”。注:如 ;* 需更改本程序的数据帧格式可在“USART_AINT_INI”子程序中进行修改。 ;*   ③.本程序约定双方通信的波特率为“ 115.2 Kbps ”。注:如需更改本程序的通 ;* 信波特率可在“波特率(bps)常数定义”中进行设置,但双方通信的波特率受定时器/ ;* 计数器0定时时间的约束,如果要修改最小双方通信波特率,则需修改定时器/计数器 ;* 0的定时时间(减小最小波特率需延长定时时间,增大则缩短定时时间)。定时器/计 ;* 数器0的定时时间应略大于在约定双方通信的波特率下接收完 255 个字节所用的时间 ;* 总和,也不宜取得过大,过大则影响双方通信的速度。 ;*   ④.接收和发送的数据时均以[命令>数据,命令>数据……]形式为作业方式进行 ;* 通信,但接收和发送的命令时可以任意形式进行通信。对于接收和发送的数据的校验方 ;* 法采用循环冗余检测(CRC)校验法,接收和发送的双方必须采用相同的校验算法,具 ;* 体的检测校验算法请参考子程序“Data_CRC_2Byte”中的具体说明。 ;*   ⑤.每次接收和发送的数据总长度均不超过 255 个字节。而且每次接收或发送数据 ;* 的第一个字节为本次接收或发送的数据长度字符,最后两个字节为循环冗余检测校验字 ;* 节,因此每次接收和发送的有效数据长度均不得超过 252 个字节。,其计算公式如下: ;* 数据长度数值 = 有效数据字节长度 + 3( 1 个长度字符本身 + 2 个校验字节) ;*   ⑥.在发送数据前要向对方先发送一请求发送数据命令字符串“COMXXXXATX”,等待 ;* 对方回应一允许发送命令字符串“COMXXXXYET”的握手信号后,方可接着进行发送数据。 ;*   ⑦.当接收到的数据或命令有错误时,可向对方发送要求重新发送命令字符串“CO ;* MXXXXRPT”,要求对方重新发送。对方在接收到此命令字符串后,依据上次发送的作业 ;* 类型来重新发送数据或命令。对于接收到的数据经循环冗余检测校验错误后,也可使用 ;* 重新发送一次允许发送命令字符串“COMXXXXYET”来要求对方重新发送数据。 ;*   ⑧.当接收到的数据(不包括命令)经循环冗余检测校验正确后,必须向对方发送 ;* 一接收数据正确命令字符串“COMXXXXOKD”,来结束本次接收数据操作。如果对方不发 ;* 送收到此命令字符串“COMXXXXOKD”错误的信息(即发回“COMXXXXRPT”),不允许多 ;* 次发送此命令字符串,否则将导致接收数据错误。 ;*   ⑨.本程序通信协议命令还包括了下面三个协议命令字符串,具体用法如下述: ;* “COMXXXXSTD”[要求对方发送指定数据],此命令用于启动双方对指定数据的收发 ;* 操作。 ;* “COMXXXXRII”[要求对方重新初始化 USART 端口状态],此命令用于当通信协议命令 ;* 混乱,致使收发作业操作无法正常运行时,向对方发出从头再重新开始收发作业请求。 ;* 此命令也可用于双方开始通信前向对方发送开始通信命令使用,使双方的 USART 端口 ;* 均处于起始状态。 ;* “COMXXXXYRI”[重新初始化 USART 端口状态完成],此命令用于通知对方,我方己可 ;* 以从头再重新开始收发作业。 ;*   ⑩.“COMXXXXCIT”[从 USART 端口传送控制操作指令],此命令用于通知对方下 ;* 面接着发送的数据为控制操作指令字符串,其字符串的第一个字节也为数据长度字符, ;* 但字符串的数值有无 CRC 校验码都可以,有 CRC 校验码时长度值相应也加 2 个。发送 ;* 和回应控制操作指令字符串的通信协议遵循发送数据方式。接收方在收到控制操作指令 ;* 字符串后,可能会发回三种回应协议命令: ;* ⑴.无法正确识别控制操作指令字符串的内容,表示接收到的指令错误或受到干扰,将 ;* 发回要求对方重新发送命令字符串“COMXXXXRPT”。 ;* ⑵.己经完成了控制操作指令字符串的内容指定的操作程序,将发回接收数据正确命令 ;* 字符串“COMXXXXOKD”。 ;* ⑶.控制操作指令字符串的内容为要求向其发送指定的数据,将发回请求发送数据命令 ;* 字符串“COMXXXXATX”。 ;* ;* 注释:  ;*   ①.定时器/计数器0用于约束接收作业全部完成(指从接收第一个数据到最后一 ;* 个数据之间)的时间范围,如果在规定的时间内没有接收作业全部完成,则强制结束 ;* 此次接收作业,以便下次接收作业正确操作。其定时时间应略大于在约定双方通信的 ;* 波特率下接收完 256 个字节所用的时间总和。 ;*   ②.当收发命令字符串“COMXXXXRPT”超过 16 次时,即双方接收和发送无论是数 ;* 据还是协议命令只要其错误总次数超过 16 次,那么就认为双方通信处于不同步状态, ;* 或通信协议命令混乱。系统将会首先重新初始化本身的 USART 端口状态和数据处理状 ;* 态,然后向对方发送要求对方重新初始化 USART 端口状态命令字符串“COMXXXXRII”, ;* 以使双方通信重新处于同步状态。 ;* ;* 编作者: ;* 编作者 E-Mail: PTZSW@163.COM ;* 编制日期: 2004年12月18日 ;* ;******************************************************************************* ;* ;* 指令条数: 1398 + return ;* 指令执行周期: 0 + return ;* 低位寄存器使用: 2 (r5,r6)(注:此两个为全局寄存器变量,不得被其他程序使用) ;* 高位寄存器使用: 5 (r16,r17,r18,r19,r20) ;* 指针寄存器使用: Y,Z ;* ;******************************************************************************* ;******** 本程序需调用的子程序定义: .include "DataCheck_CRC2B.asm" ;包括2字节数据循环冗余检测校验子程序 ;******** 依据硬件设置需修改的 SRAM 存储地址定义: .equ USARTAI_TXCOM = $0070 ;发送命令作业标志 .equ DataUPD_TXALW = $0071 ;允许更新发送数据标志 .equ USARTAI_TXEnd = $0072 ;发送作业全部结束标志 .equ USARTAI_TXAPL = $0074 ;发送地址指针低字节 .equ USARTAI_TXAPH = $0075 ;发送地址指针高字节 .equ USARTAI_TXCOA = $0076 ;首个发送命令字符地址 ;要再占用往下的 10 个字节位置 .equ USARTAI_TXDAA = $0080 ;首个发送数据地址 ;要再占用往下的 255 个字节位置 .equ USARTAI_RXCOM = $0182 ;接收命令作业标志 .equ DataUPD_RXALW = $0183 ;允许处理接收数据标志 .equ USARTAI_RXUPD = $0184 ;接收作业己更新标志 .equ USARTAI_RXEnd = $0185 ;接收作业全部结束标志 .equ USARTAI_RXAPL = $0186 ;接收作业地址指针低字节 .equ USARTAI_RXAPH = $0187 ;接收作业地址指针高字节 .equ USARTAI_RXCOA = $0188 ;首个接收命令字符地址 ;要再占用往下的 10 个字节位置 .equ USARTAI_RXDAA = $0192 ;首个接收数据地址 ;要再占用往下的 255 个字节位置 .equ USARTAI_ERRNum = $0293 ;USART 发生收发错误次数计数器 .equ USARTAI_T0VNum = $0294 ;定时器/计数器0溢出次数计数器 ;*** 波特率(bps)常数定义: ;下面波特率设置以单片机的时钟= 11.0592 MHz ,且不打开倍速的条件下进行定义。 ;波特率(bps) = 115.2 Kbps,误差 = 0.0% .equ USARTAI_UBRRL = $05 .equ USARTAI_UBRRH = 0 ;*** 定时器/计数器0定时 2 秒常数定义: ;下面定时器/计数器0定时参数设置以单片机的时钟= 11.0592 MHz ,且定时器/计数 ;器0的预分频因子 = 1024 进行的条件下定义。其计算公式如下: ;定时时间 = 1 ÷ 单片机的时钟频率 × 1024 × USARTAI_T0CNT × USARTAI_T0Num .equ USARTAI_T0CNTI = $80 ;定时器/计数器0计数预定比例值 .equ USARTAI_T0NumI = $03 ;定时器/计数器0溢出次数值 ;******************************************************************************* ;* ;* 通用同步和异步串行接收器和转发器(USART)异步中断接收和发送通信程序: ;* ;* “USART_AINT_INI” --- USART 异步通信中断接收和发送初始化子程序 ;* ;* “USART_RXCINT”------ USART 异步通信接收结束中断处理子程序。 ;* ;* “USART_TXDREINT”---- USART 异步通信数据寄存器空中断发送处理子程序。 ;* ;* “USART_INT_ACOM”---- USART 异步通信中断接收与发送协议命令和数据处理子程序 ;* ;******************************************************************************* ;******** 全局程序寄存器变量定义(不得被其他程序使用): .def USARTAI_RXNum = r5 ;接收作业次数寄存器 .def USARTAI_TXNum = r6 ;发送作业次数寄存器 ;******** 本程序寄存器变量定义: .def USARTAI_TEMP = r16 ;暂存寄存器 .def USARTAI_TEMP2 = r17 ;暂存寄存器2 .def USARTAI_TEMP3 = r18 ;暂存寄存器3 ;******** 本程序常数定义: .equ USARTAI_TCOMI = $e0 ;发送命令作业标志值(11100000) .equ DataUPD_TALWI = $c0 ;允许更新发送数据标志值(11000000) .equ USARTAI_TEndI = $f0 ;全部数据发送结束标志值(11110000) .equ USARTAI_RCOMI = $07 ;接收命令作业标志值(00000111) .equ DataUPD_RALWI = $03 ;允许处理接收数据标志值(00000011) .equ USARTAI_RUPDI = $0a ;接收作业己更新标志值(00001010) .equ USARTAI_REndI = $0f ;全部数据接收结束标志值(00001111) .equ USARTAI_ENALWI = $10 ;允许 USART 发生收发错误次数值(16次) .equ USARTAI_CMATNI = $0a ;收发命令的字符串总长度数值(10个) .equ USARTAI_CMANI = $03 ;收发命令的有效字符串长度数值(3个) ;******** 程序指令代码清单: ;******************************************************************************* ;* ;* USART 异步通信中断接收和发送初始化子程序 - “USART_AINT_INI” ;* ;* 说明: ;*   本子程序用于初始化 USART 异步中断接收和发送通信。本初始化子程序只打开了 ;* USART 的中断接收功能,没有打开中断发送功能。 ;*   本子程序只需在主程序中运行一次即可。除非释放 RXD 与 TXD 引脚功能作为其 ;* 他用途,如要再使用 USART 通信则需在主程序中再运行一次本子程序。 ;* ;******************************************************************************* USART_AINT_INI: push ZL ;压入寄存器中的数值到堆栈 push ZH in ZL,SREG ;压状态寄存器中的标志值到堆栈 push ZL ldi ZL,USARTAI_TEndI ;置发送作业全部结束标志值 sts USARTAI_TXEnd,ZL ldi ZL,USARTAI_TCOMI ;置发送命令作业标志值,首次发送一定为 sts USARTAI_TXCOM,ZL ;请求向对方发送或允许对方发送命令 clr ZL ;清除允许更新发送数据标志 sts DataUPD_TXALW,ZL ldi ZL,USARTAI_REndI ;置接收作业全部结束标志值 sts USARTAI_RXEnd,ZL ldi ZL,USARTAI_RCOMI ;置接收命令作业标志值,首次接收一定为 sts USARTAI_RXCOM,ZL ;对方请求发送或对方允许发送命令 clr ZL ;清除接收作业己更新标志 sts USARTAI_RXUPD,ZL clr ZL ;清除允许处理接收数据标志 sts DataUPD_RXALW,ZL clr ZL ;清除USART 发生收发错误次数计数器值 sts USARTAI_ERRNum,ZL clr ZL ;清除定时器/计数器0溢出次数计数器值 sts USARTAI_T0VNum,ZL cli ;禁止全局中断 ldi ZL,USARTAI_UBRRL ;设置通信波特率 out UBRRL,ZL ldi ZL,USARTAI_UBRRH out UBRRH,ZL ldi ZL,(1<