⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 通用同步和异步串行接收器和转发器(usart).txt

📁 USART在单片机里的通用c程序
💻 TXT
📖 第 1 页 / 共 5 页
字号:
    cpi CCTSSDV_Right,CCTSSDV_RightI;命令是否为“允许我方发送数据”?
    brne USART_RXD_COMM6              ;否,则继续
    rcall USART_RX_COMM_OKRX          ;是,调用处理此条命令处理程序
    rjmp USART_RXD_COMM_RET
USART_RXD_COMM6:
    ldi ZL,Low(USART_REPINI*2)      ;置“要求我方重新初始化”命令地址指针
    ldi ZH,High(USART_REPINI*2)
    ldi CTRLCOM_CNT,USARTAI_CMANI   ;置计数器初值=有效命令字长度数值
    rcall CTRLCOMM_IdentifyCOM      ;对此条命令进行识别
    cpi CCTSSDV_Right,CCTSSDV_RightI;命令是否为“要求我方重新初始化”?
    brne USART_RXD_COMM7              ;否,则继续
    rcall USART_RX_COMM_REPINI        ;是,调用处理此条命令处理程序
    rjmp USART_RXD_COMM_RET
USART_RXD_COMM7:
    ldi ZL,Low(USART_RINIOK*2)      ;置“对方重新初始化完成”命令地址指针
    ldi ZH,High(USART_RINIOK*2)
    ldi CTRLCOM_CNT,USARTAI_CMANI   ;置计数器初值=有效命令字长度数值
    rcall CTRLCOMM_IdentifyCOM      ;对此条命令进行识别
    cpi CCTSSDV_Right,CCTSSDV_RightI;命令是否为“对方重新初始化完成”?
    brne USART_RXD_COMM8              ;否,则继续
    rcall USART_RX_COMM_RINIOK        ;是,调用处理此条命令处理程序
    rjmp USART_RXD_COMM_RET
USART_RXD_COMM8:
    ldi ZL,Low(USART_CTRLCOM*2)     ;置“传送控制操作指令”命令地址指针
    ldi ZH,High(USART_CTRLCOM*2)
    ldi CTRLCOM_CNT,USARTAI_CMANI   ;置计数器初值=有效命令字长度数值
    rcall CTRLCOMM_IdentifyCOM      ;对此条命令进行识别
    cpi CCTSSDV_Right,CCTSSDV_RightI;命令是否为“传送控制操作指令”?
    brne USART_RXD_COMM_Error         ;否,转至接收错误处理
    rcall USART_RX_COMM_CTRLCOM       ;是,调用处理此条命令处理程序
    rjmp USART_RXD_COMM_RET
USART_RXD_COMM_Error:
    rcall USART_RXD_Error           ;调用接收错误处理子程序
    rjmp USART_RXD_COMM_RET
USART_RXD_COMM_NOADDR:
    clr ZL                          ;清除接收作业己更新标志
    sts USARTAI_RXUPD,ZL
USART_RXD_COMM_RET:
    ret                             ;子程序返回


;*** 此段程序用于接收到[传送控制操作指令]命令处理
USART_RX_COMM_CTRLCOM:
    lds ZL,DataUPD_RXALW            ;接收数据是否己处理?
    cpi ZL,DataUPD_RALWI              ;是,继续
    breq USART_RX_COMM_CTRLCOM_RET    ;否,返回,等待处理接收数据
    lds ZL,USARTAI_TXEnd            ;发送作业是否全部结束?
    cpi ZL,USARTAI_TEndI              ;是,继续
    brne USART_RX_COMM_CTRLCOM_RET    ;否,返回,等待发送作业结束
    lds ZL,CTRLCOM_MALWS            ;是否有正在处理控制操作指令?
    cpi ZL,CTRLCOM_MALWSI             ;否,继续
    breq USART_RX_COMM_CTRLCOM_RET    ;是,返回,等待处理控制操作指令结束
    rcall USART_TX_COMM_OKRX        ;向对方发送“允许对方发送”命令
    clr ZL                          ;清除接收命令作业标志
    sts USARTAI_RXCOM,ZL
    ldi ZL,CTRLCOM_MALWSI           ;置允许处理控制操作指令标志值
    sts CTRLCOM_MALWS,ZL
    ldi ZL,CCTSSDV_USARTI           ;置控制操作指令发送者标志值
    sts CCOM_TSourceS,ZL              ;为 USART 端口送来控制操作指令
    clr ZL                          ;清除接收作业己更新标志
    sts USARTAI_RXUPD,ZL
USART_RX_COMM_CTRLCOM_RET:
    ret                             ;子程序返回

;*** 此段程序用于接收到[重新初始化完成]命令处理
USART_RX_COMM_RINIOK:
    clr ZL                          ;清除接收作业己更新标志
    sts USARTAI_RXUPD,ZL
    ret                             ;子程序返回

;*** 此段程序用于接收到[要求对方重新初始化]命令处理
USART_RX_COMM_REPINI:
    ldi ZH,(1<<RXCIE)|(1<<UDRIE)|(1<<RXEN)|(1<<TXEN)
    com ZH                          ;禁止接收器和发送器,禁止 USART 
    in ZL,UCSRB                       ;接收结束中断和数据寄存器空中断
    and ZL,ZH
    out UCSRB,ZL


;此处插入从头开始重新进行数据处理操作程序


    ldi ZH,(1<<FE)|(1<<DOR)|(1<<PE)
    com ZH                          ;清除帧错误(FE)、数据溢出(DOR)
    in ZL,UCSRA                       ;及奇偶校验错误(UPE)标志
    and ZL,ZH
    out UCSRA,ZL
    ldi ZH,(1<<UDRE)
    in ZL,UCSRA                     ;置数据寄存器空(UDRE)标志
    or ZL,ZH
    out UCSRA,ZL
    rcall USART_AINT_INI            ;重新初始化 USART 异步中断接收和发送
    rcall USART_TX_COMM_RINIOK      ;向对方发送“重新初始化完成”命令
    ret                             ;子程序返回

;*** 此段程序用于接收到[向对方请求发送]命令处理
USART_RX_COMM_AskTX:
    lds ZL,DataUPD_RXALW            ;接收数据是否己处理?
    cpi ZL,DataUPD_RALWI              ;是,继续
    breq USART_RX_COMM_AskTX_RET      ;否,返回,等待处理接收数据
    lds ZL,USARTAI_TXEnd            ;发送作业是否全部结束?
    cpi ZL,USARTAI_TEndI              ;是,继续
    brne USART_RX_COMM_AskTX_RET      ;否,返回,等待发送作业结束
    rcall USART_TX_COMM_OKRX        ;向对方发送“允许对方发送”命令
    clr ZL                          ;清除接收命令作业标志
    sts USARTAI_RXCOM,ZL
    ldi ZL,DataUPD_RALWI            ;置允许处理接收数据标志值
    sts DataUPD_RXALW,ZL
    clr ZL                          ;清除接收作业己更新标志
    sts USARTAI_RXUPD,ZL
USART_RX_COMM_AskTX_RET:
    ret                             ;子程序返回

;*** 此段程序用于接收到[允许对方发送]命令处理
USART_RX_COMM_OKRX:
    lds ZL,DataUPD_TXALW            ;发送数据是否己更新?
    cpi ZL,DataUPD_TALWI              ;是,继续
    breq USART_RX_COMM_OKRX_RET       ;否,返回,等待更新发送数据
    lds ZL,USARTAI_TXEnd            ;发送作业是否全部结束?
    cpi ZL,USARTAI_TEndI              ;是,继续
    brne USART_RX_COMM_OKRX_RET       ;否,返回,等待发送作业结束
    clr ZL                          ;清除发送命令作业标志
    sts USARTAI_TXCOM,ZL
    rcall USART_AINT_TXINI          ;启动发送数据
    clr ZL                          ;清除接收作业己更新标志
    sts USARTAI_RXUPD,ZL
USART_RX_COMM_OKRX_RET:
    ret                             ;子程序返回

;*** 此段程序用于接收到[要求对方重新发送]命令处理
USART_RX_COMM_REPTX:
    lds ZL,USARTAI_ERRNum           ;USART 发生收发错误次数是否超过允许次数?
    cpi ZL,USARTAI_ENALWI             ;是,转至 USART 通信发生错误处理
    brlo USART_RX_COMM_REPTX1         ;否,继续
    rcall USART_Error               ;调用 USART 通信发生错误处理程序
    rjmp USART_RX_COMM_REPTX_RET    ;返回
USART_RX_COMM_REPTX1:
    lds ZL,USARTAI_TXEnd            ;发送作业是否全部结束?
    cpi ZL,USARTAI_TEndI              ;是,继续
    brne USART_RX_COMM_REPTX_RET      ;否,返回,等待发送作业结束
    rcall USART_AINT_TXINI          ;重新启动原发送作业
    clr ZL                          ;清除接收作业己更新标志
    sts USARTAI_RXUPD,ZL
    lds ZL,USARTAI_ERRNum           ;USART 发生收发错误次数+1
    inc ZL
    sts USARTAI_ERRNum,ZL
USART_RX_COMM_REPTX_RET:
    ret                             ;子程序返回

;*** 此段程序用于接收到[接收数据正确]命令处理
USART_RX_COMM_DataOK:
    ldi ZL,USARTAI_TCOMI            ;置发送命令作业标志值
    sts USARTAI_TXCOM,ZL
    ldi ZL,DataUPD_TALWI            ;置允许更新发送数据标志值
    sts DataUPD_TXALW,ZL
    clr ZL                          ;清除接收作业己更新标志
    sts USARTAI_RXUPD,ZL
    ret                             ;子程序返回

;*** 此段程序用于接收到[要求对方发送指定数据]命令处理
USART_RX_COMM_DCOMTX:
    ldi ZL,DataUPD_TALWI            ;置允许更新发送数据标志值
    sts DataUPD_TXALW,ZL
    clr ZL                          ;清除接收作业己更新标志
    sts USARTAI_RXUPD,ZL
USART_RX_COMM_DCOMTX_RET:
    ret                             ;子程序返回

;*** 此段程序用于“USART 接收器错误”和“接收命令或数据错误”处理
USART_RXD_Error:
    lds ZL,USARTAI_ERRNum           ;USART 发生收发错误次数是否超过允许次数?
    cpi ZL,USARTAI_ENALWI             ;是,转至 USART 通信发生错误处理
    brlo USART_RXD_Error1             ;否,继续
    rcall USART_Error               ;调用 USART 通信发生错误处理程序
    rjmp USART_RXD_Error_RET        ;返回
USART_RXD_Error1:
    lds ZL,USARTAI_TXEnd            ;发送作业是否全部结束?
    cpi ZL,USARTAI_TEndI              ;是,继续
    brne USART_RXD_Error_RET          ;否,返回,等待发送作业结束
    rcall USART_TX_COMM_REPTX       ;向对方发送“要求重新发送”命令
    ldi ZH,(1<<FE)|(1<<DOR)|(1<<PE)
    com ZH                          ;清除帧错误(FE)、数据溢出(DOR)
    in ZL,UCSRA                       ;及奇偶校验错误(UPE)标志
    and ZL,ZH
    out UCSRA,ZL
    ldi ZL,USARTAI_REndI            ;置接收作业全部结束标志值
    sts USARTAI_RXEnd,ZL
    clr ZL                          ;清除接收作业己更新标志
    sts USARTAI_RXUPD,ZL
    lds ZL,USARTAI_ERRNum           ;USART 发生收发错误次数+1
    inc ZL
    sts USARTAI_ERRNum,ZL
USART_RXD_Error_RET:
    ret                             ;子程序返回


;*******************************************************************************
;*
;* 从 USART 端口上接收到的数据处理子程序 - “USART_RXD_Data”
;*
;* 说明:
;*   本子程序用于处理从 USART 端口上接收到的数据,本子程序中包含有数据循环
;* 冗余检测校验子程序。
;*   本子程序要在主程序中不间断循环查询运行。
;*
;* SRAM 中标志字节用法:
;*   入口标志:本子程序将检查这三个标志,只有这三个标志置值后才允许处理数据。
;*               允许处理接收数据(DataUPD_RXALW)= $03(DataUPD_RDALWI)
;*               接收作业己更新(USARTAI_RXUPD)  = $0a(USARTAI_RUPDI)
;*               接收作业全部结束(USARTAI_RXEnd)= $0f(USARTAI_REndI)
;*   出口标志:接收数据处理操作得到执行后,将对下面这两个标志置值。
;*               允许处理接收数据(DataUPD_RXALW)= $00
;*               接收作业己更新(USARTAI_RXUPD)  = $00
;*
;*******************************************************************************
USART_RXD_Data:
    lds ZL,DataUPD_RXALW            ;检查是否允许处理接收数据?
    cpi ZL,DataUPD_RALWI              ;是,则继续
    brne USART_RXD_Data_RET           ;否,直接返回
    lds ZL,USARTAI_RXUPD            ;检查接收作业是否己更新?
    cpi ZL,USARTAI_RUPDI              ;是,则继续
    brne USART_RXD_Data_RET           ;否,直接返回
    lds ZL,USARTAI_TXEnd            ;发送作业是否全部结束?
    cpi ZL,USARTAI_TEndI              ;是,继续
    brne USART_RXD_Data_RET           ;否,返回,等待发送作业结束
    lds ZL,USARTAI_RXEnd            ;检查接收作业是否全部结束?
    cpi ZL,USARTAI_REndI              ;是,则继续
    brne USART_RXD_Data_Error         ;否,转至接收错误处理
USART_RXD_Data_Check:
    ldi ZL,Low(USARTAI_RXDAA)       ;Z 指针指向接收数据的首字节
    ldi ZH,High(USARTAI_RXDAA)
    lds DCRC2B_DLength,USARTAI_RXDAA;置校验的数据长度初值
    call DataCheck_CRC2B            ;校验接收的数据是否正确?
    or YL,YH                          ;是,继续
    brne USART_RXD_Data_Error         ;否,转至接收错误处理
    rcall USART_TX_COMM_DataOK      ;向对方发送“接收数据正确”命令

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -