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

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

📁 USART在单片机里的通用c程序
💻 TXT
📖 第 1 页 / 共 5 页
字号:
    ldi ZL,(1<<RXEN)|(1<<TXEN)|(1<<RXCIE)|(1<<UDRIE)
    out UCSRB,ZL                    ;接收器与发送器使能和接收结束中断、
                                      ;与 USART 数据寄存器空中断使能
    ret                             ;子程序返回


;*******************************************************************************
;*
;* 向 USART 端口发送通信协议命令子程序清单
;*
;* 说明:
;*   本子程序用于向 USART 端口发送通信协议命令。调用这些子程序后,将立即
;* 启动该命令的发送作业。共包括下列这些独立的子程序。
;*
;*   向端口发送[向对方请求发送]命令 --------- “USART_TX_COMM_AskTX”
;*   向端口发送[允许对方发送]命令 ----------- “USART_TX_COMM_OKRX”
;*   向端口发送[要求对方重新发送]命令 ------- “USART_TX_COMM_REPTX”
;*   向端口发送[接收数据正确]命令 ----------- “USART_TX_COMM_DataOK”
;*   向端口发送[要求对方发送指定数据]命令 --- “USART_TX_COMM_DCOMTX”
;*   向端口发送[要求对方重新初始化]命令 ----- “USART_TX_COMM_REPINI”
;*   向端口发送[重新初始化完成]命令 --------- “USART_TX_COMM_RINIOK”
;*
;*******************************************************************************


;*** 此段程序用于发送[重新初始化完成]命令 - “USART_TX_COMM_RINIOK”
USART_TX_COMM_RINIOK:
    rcall USART_TXD_COMM_Head       ;将开头字符串和端口编号复制到 SRAM 中
    ldi ZL,Low(USART_RINIOK*2)      ;置 Z 指针为重新初始化完成命令字符串,
    ldi ZH,High(USART_RINIOK*2)       ;在 FLASH 中的存储地址
    rcall USART_TXD_COMM_COM        ;将命令字符串复制到 SRAM 的发送地址中,
                                      ;并置发送命令作业标志值
    rcall USART_AINT_TXINI          ;发送本命令字符串
    ret                             ;子程序返回

;*** 此段程序用于发送[要求对方重新初始化]命令 - “USART_TX_COMM_REPINI”
USART_TX_COMM_REPINI:
    rcall USART_TXD_COMM_Head       ;将开头字符串和端口编号复制到 SRAM 中
    ldi ZL,Low(USART_REPINI*2)      ;置 Z 指针为要求对方重新初始化命令字符串,
    ldi ZH,High(USART_REPINI*2)       ;在 FLASH 中的存储地址
    rcall USART_TXD_COMM_COM        ;将命令字符串复制到 SRAM 的发送地址中,
                                      ;并置发送命令作业标志值
    rcall USART_AINT_TXINI          ;发送本命令字符串
    ret                             ;子程序返回

;*** 此段程序用于发送[向对方请求发送]命令 - “USART_TX_COMM_AskTX”
USART_TX_COMM_AskTX:
    rcall USART_TXD_COMM_Head       ;将开头字符串和端口编号复制到 SRAM 中
    ldi ZL,Low(USART_AskTX*2)       ;置 Z 指针为向对方请求发送命令字符串,
    ldi ZH,High(USART_AskTX*2)        ;在 FLASH 中的存储地址
    rcall USART_TXD_COMM_COM        ;将命令字符串复制到 SRAM 的发送地址中,
                                      ;并置发送命令作业标志值
    rcall USART_AINT_TXINI          ;发送本命令字符串
    ret                             ;子程序返回

;*** 此段程序用于发送[允许对方发送]命令 - “USART_TX_COMM_OKRX”
USART_TX_COMM_OKRX:
    rcall USART_TXD_COMM_Head       ;将开头字符串和端口编号复制到 SRAM 中
    ldi ZL,Low(USART_OKRX*2)        ;置 Z 指针为向对方请求发送命令字符串,
    ldi ZH,High(USART_OKRX*2)         ;在 FLASH 中的存储地址

    rcall USART_TXD_COMM_COM        ;将命令字符串复制到 SRAM 的发送地址中,
                                      ;并置发送命令作业标志值
    rcall USART_AINT_TXINI          ;发送本命令字符串
    ret                             ;子程序返回

;*** 此段程序用于发送[要求对方重新发送]命令 - “USART_TX_COMM_REPTX”
USART_TX_COMM_REPTX:
    rcall USART_TXD_COMM_Head       ;将开头字符串和端口编号复制到 SRAM 中
    ldi ZL,Low(USART_REPTX*2)       ;置 Z 指针为向对方请求发送命令字符串,
    ldi ZH,High(USART_REPTX*2)        ;在 FLASH 中的存储地址
    rcall USART_TXD_COMM_COM        ;将命令字符串复制到 SRAM 的发送地址中,
                                      ;并置发送命令作业标志值
    rcall USART_AINT_TXINI          ;发送本命令字符串
    ret                             ;子程序返回

;*** 此段程序用于发送[接收数据正确]命令 - “USART_TX_COMM_DataOK”
USART_TX_COMM_DataOK:
    rcall USART_TXD_COMM_Head       ;将开头字符串和端口编号复制到 SRAM 中
    ldi ZL,Low(USART_DataOK*2)      ;置 Z 指针为向对方请求发送命令字符串,
    ldi ZH,High(USART_DataOK*2)       ;在 FLASH 中的存储地址
    rcall USART_TXD_COMM_COM        ;将命令字符串复制到 SRAM 的发送地址中,
                                      ;并置发送命令作业标志值
    rcall USART_AINT_TXINI          ;发送本命令字符串
    ret                             ;子程序返回

;*** 此段程序用于发送[要求对方发送指定数据]命令 - “USART_TX_COMM_DCOMTX”
USART_TX_COMM_DCOMTX:
    rcall USART_TXD_COMM_Head       ;将开头字符串和端口编号复制到 SRAM 中
    ldi ZL,Low(USART_DCOMTX*2)      ;置 Z 指针为向对方请求发送命令字符串,
    ldi ZH,High(USART_DCOMTX*2)       ;在 FLASH 中的存储地址
    rcall USART_TXD_COMM_COM        ;将命令字符串复制到 SRAM 的发送地址中,
                                      ;并置发送命令作业标志值
    rcall USART_AINT_TXINI          ;发送本命令字符串
    ret                             ;子程序返回

;*** 此段程序用于发送命令开头字符串和端口编号 - “USART_TXD_COMM_Head”
USART_TXD_COMM_Head:
    ldi YL,Low(USARTAI_TXCOA)       ;置 Y 指针为发送命令 SRAM 中的地址
    ldi YH,High(USARTAI_TXCOA)
    ldi ZL,Low(COMAgreement_Head*2) ;置 Z 指针为向发送命令开头字符串,
    ldi ZH,High(COMAgreement_Head*2)  ;在 FLASH 中的存储地址
    lpm USARTAI_TEMP3,Z+            ;置循环计数器初值=开头命令字长度数值
USART_TXD_COMM_Head1:
    lpm USARTAI_TEMP,Z+             ;从 FLASH 中取出发送命令开头字符串
    st Y+,USARTAI_TEMP              ;装入 SRAM 的发送命令地址中
    dec USARTAI_TEMP3               ;命令字长度数值 — 1
    brne USART_TXD_COMM_Head1       ;装入完成否?
USART_TXD_COMM_HeadDN:
    ldi EEPROM_AddrL,Low(CC_EEPROM_DNAr)
    ldi EEPROM_AddrH,High(CC_EEPROM_DNAr)
                                    ;置在 EEPROM 中的本端口编号地址指针
    ldi USARTAI_TEMP3,CTRLCDN_CharNI;置循环计数器初值=本端口编号长度数值
USART_TXD_COMM_HeadDN1:
    call EEPROM_ReadSingle          ;读取 EEPROM 中的本 USART 端口编号
    mov USARTAI_TEMP2,EEPROM_Data
    st Y+,USARTAI_TEMP2             ;装入 SRAM 的发送命令地址中
    adiw EEPROM_AddrL,$01           ; EEPROM 中的端口编号地址指针 + 1
    dec USARTAI_TEMP3               ;端口编号字符串长度数值长度数值 — 1
    brne USART_TXD_COMM_HeadDN1     ;端口编号装入完否?未完,则继续装入
    ret                             ;子程序返回

;*** 此段程序用于发送命令字符串公共子程序 - “USART_TXD_COMM_COM”
USART_TXD_COMM_COM:
    lpm USARTAI_TEMP,Z+             ;从 FLASH 中取出首个发送命令字符
    st Y+,USARTAI_TEMP              ;装入 SRAM 的发送命令地址中
    lpm USARTAI_TEMP,Z+             ;从 FLASH 中取出下一个发送命令字符
    st Y+,USARTAI_TEMP              ;装入 SRAM 的发送命令地址中
    lpm USARTAI_TEMP,Z+             ;从 FLASH 中取出下一个发送命令字符
    st Y+,USARTAI_TEMP              ;装入 SRAM 的发送命令地址中
    ldi USARTAI_TEMP,USARTAI_TCOMI  ;置发送命令作业标志值
    sts USARTAI_TXCOM,USARTAI_TEMP
    ret                             ;子程序返回


;*******************************************************************************
;*
;* 从 USART 端口上接收到的通信协议命令处理子程序 - “USART_RXD_COMM”
;*
;* 说明:
;*   本子程序用于从 USART 端口上接收到的通信协议命令处理。
;*   本子程序要在主程序中不间断循环查询运行。
;*
;*******************************************************************************

USART_RXD_COMM:
    lds ZL,USARTAI_RXUPD            ;检查接收作业是否己更新?
    cpi ZL,USARTAI_RUPDI              ;否,直接返回
    breq USART_RXD_COMMTO1            ;是,则继续
    rjmp USART_RXD_COMM_RET
USART_RXD_COMMTO1:
    lds ZL,USARTAI_RXCOM            ;检查接收作业是否为接收命令?
    cpi ZL,USARTAI_RCOMI              ;否,直接返回
    breq USART_RXD_COMMTO2            ;是,则继续
    rjmp USART_RXD_COMM_RET
USART_RXD_COMMTO2:
    lds ZL,USARTAI_RXEnd            ;检查接收作业是否全部结束?
    cpi ZL,USARTAI_REndI              ;否,转至接收错误处理
    breq USART_RXD_COM_CAHead         ;是,则继续
    rjmp USART_RXD_COMM_Error
USART_RXD_COM_CAHead:
    ldi YL,Low(USARTAI_RXCOA)       ;置首个接收命令字符地址指针
    ldi YH,High(USARTAI_RXCOA)
    ldi ZL,Low(COMAgreement_Head*2) ;置通信协议命令开头标识字符串地址指针
    ldi ZH,High(COMAgreement_Head*2)
    lpm USARTAI_TEMP,Z+             ;置循环计数器初值=开头命令字长度数值
    mov CTRLCOM_CNT,USARTAI_TEMP
    rcall CTRLCOMM_IdentifyCOM      ;识别通信协议命令开头标识字符串
    mov USARTAI_TEMP,CCTSSDV_Right 
    cpi USARTAI_TEMP,CCTSSDV_RightI ;检查接收字节是否为命令开头标识字符?
    breq USART_RXD_COM_EAddr          ;是,则继续
    rjmp USART_RXD_COMM_Error         ;否,转至接收错误处理
USART_RXD_COM_EAddr:
    ldi ZL,Low(COMAgreement_Head*2) ;置通信协议命令开头标识字符串地址指针
    ldi ZH,High(COMAgreement_Head*2)
    lpm USARTAI_TEMP2,Z+            ;读取开头命令字长度数值
    clr USARTAI_TEMP
    add YL,USARTAI_TEMP2            ;置 Y 指针为本端口编号字符串的地址指针
    adc YH,USARTAI_TEMP
    ldi USARTAI_TEMP3,CTRLCDN_CharNI;置循环计数器初值=本端口编号长度数值
    ldi EEPROM_AddrL,Low(CC_EEPROM_DNAr)
    ldi EEPROM_AddrH,High(CC_EEPROM_DNAr)
                                    ;置在 EEPROM 中的本端口编号地址指针
USART_RXD_COM_EAddr1:
    call EEPROM_ReadSingle          ;读取 EEPROM 中的本 USART 端口编号
    mov USARTAI_TEMP2,EEPROM_Data
    ld USARTAI_TEMP,Y+
    cp USARTAI_TEMP,USARTAI_TEMP2   ;检查是否为本 USART 端口编号?
    brne USART_RXD_COM_EAddr2         ;否,转至非本 USART 端口编号处理
    adiw EEPROM_AddrL,$01           ; EEPROM 中的端口编号地址指针 + 1
    dec USARTAI_TEMP3               ;端口编号字符串长度数值长度数值 — 1
    brne USART_RXD_COM_EAddr1       ;端口编号识别完否?未完,则继续识别
    rjmp USART_RXD_COMM1
USART_RXD_COM_EAddr2:
    rjmp USART_RXD_COMM_NOADDR
USART_RXD_COMM1:
    ldi ZL,Low(USART_AskTX*2)       ;置“向我方请求发送数据”命令地址指针
    ldi ZH,High(USART_AskTX*2)
    ldi CTRLCOM_CNT,USARTAI_CMANI   ;置计数器初值=有效命令字长度数值
    rcall CTRLCOMM_IdentifyCOM      ;对此条命令进行识别
    cpi CCTSSDV_Right,CCTSSDV_RightI;命令是否为“向我方请求发送数据”?
    brne USART_RXD_COMM2              ;否,则继续
    rcall USART_RX_COMM_AskTX         ;是,调用处理此条命令处理程序
    rjmp USART_RXD_COMM_RET
USART_RXD_COMM2:
    ldi ZL,Low(USART_DataOK*2)      ;置“对方接收数据正确”命令地址指针
    ldi ZH,High(USART_DataOK*2)
    ldi CTRLCOM_CNT,USARTAI_CMANI   ;置计数器初值=有效命令字长度数值
    rcall CTRLCOMM_IdentifyCOM      ;对此条命令进行识别
    cpi CCTSSDV_Right,CCTSSDV_RightI;命令是否为“对方接收数据正确”?
    brne USART_RXD_COMM3              ;否,则继续
    rcall USART_RX_COMM_DataOK        ;是,调用处理此条命令处理程序
    rjmp USART_RXD_COMM_RET
USART_RXD_COMM3:
    ldi ZL,Low(USART_REPTX*2)       ;置“要求我方重新发送”命令地址指针
    ldi ZH,High(USART_REPTX*2)
    ldi CTRLCOM_CNT,USARTAI_CMANI   ;置计数器初值=有效命令字长度数值
    rcall CTRLCOMM_IdentifyCOM      ;对此条命令进行识别
    cpi CCTSSDV_Right,CCTSSDV_RightI;命令是否为“要求我方重新发送”?
    brne USART_RXD_COMM4              ;否,则继续
    rcall USART_RX_COMM_REPTX         ;是,调用处理此条命令处理程序
    rjmp USART_RXD_COMM_RET
USART_RXD_COMM4:
    ldi ZL,Low(USART_DCOMTX*2)      ;置“要求我方发送指定数据”命令地址指针
    ldi ZH,High(USART_DCOMTX*2)
    ldi CTRLCOM_CNT,USARTAI_CMANI   ;置计数器初值=有效命令字长度数值
    rcall CTRLCOMM_IdentifyCOM      ;对此条命令进行识别
    cpi CCTSSDV_Right,CCTSSDV_RightI;命令是否为“要求我方发送指定数据”?
    brne USART_RXD_COMM5              ;否,则继续
    rcall USART_RX_COMM_DCOMTX        ;是,调用处理此条命令处理程序
    rjmp USART_RXD_COMM_RET
USART_RXD_COMM5:
    ldi ZL,Low(USART_OKRX*2)        ;置“允许我方发送数据”命令地址指针
    ldi ZH,High(USART_OKRX*2)
    ldi CTRLCOM_CNT,USARTAI_CMANI   ;置计数器初值=有效命令字长度数值
    rcall CTRLCOMM_IdentifyCOM      ;对此条命令进行识别

⌨️ 快捷键说明

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