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

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

📁 USART在单片机里的通用c程序
💻 TXT
📖 第 1 页 / 共 5 页
字号:
    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<<URSEL)|(1<<UPM1)|(1<<UPM0)|(1<<UCSZ1)|(1<<UCSZ0)
                                    ;设置帧格式: 8 个数据位, 1 个停止位,
                                      ;并使能奇校验。USART 异步模式
;    ldi ZL,(1<<URSEL)|(1<<UPM1)|(1<<UPM0)|(1<<USBS)|(1<<UCSZ1)|(1<<UCSZ0)
                                    ;设置帧格式: 8 个数据位, 2 个停止位,
                                      ;并使能奇校验。USART 异步模式
    out UCSRC,ZL
    ldi ZL,(1<<RXEN)|(1<<TXEN)|(1<<RXCIE)
    out UCSRB,ZL                    ;接收器与发送器使能和接收结束中断使能
    sei                             ;打开全局中断
    pop ZL
    out SREG,ZL                     ;弹出堆栈中的标志值到状态寄存器
    pop ZH                          ;弹出堆栈中的数值到寄存器
    pop ZL
    ret                             ;子程序返回


;*******************************************************************************
;*
;* USART 异步通信接收结束中断处理子程序 - “USART_RXCINT”
;*
;* 说明:
;*   本子程序用于 USART 异步通信接收结束中断处理。
;* 
;* SRAM 中标志字节用法:
;*   入口标志:本子程序将检查这些标志,依据这些标志置值来控制不同接收作业。
;*               接收作业全部结束(USARTAI_RXEnd)= $07(USARTAI_REndI)
;*                                                ≠ $07(USARTAI_REndI)
;*        r5 --- 接收作业次数(USARTAI_RXNum)
;*   出口标志:①.接收作业全部正确接收完成后,将对下面这两个标志置值。
;*               接收作业全部结束(USARTAI_RXEnd)= $0f(USARTAI_REndI)
;*               接收作业己更新(USARTAI_RXUPD)  = $0a(USARTAI_RUPDI)
;*        r5 --- 接收作业次数(USARTAI_RXNum)    = $00
;*             ②.接收作业开始后(正在进行中),将对下面这两个标志置值。
;*               接收作业全部结束(USARTAI_RXEnd)= $00
;*               接收作业己更新(USARTAI_RXUPD)  = $00
;*             ③.接收作业发生错误时,将对下面这两个标志置值。
;*               接收作业全部结束(USARTAI_RXEnd)= $00
;*               接收作业己更新(USARTAI_RXUPD)  = $0a(USARTAI_RUPDI)
;*
;*******************************************************************************

USART_RXCINT:
    push USARTAI_TEMP               ;压入寄存器中的数值到堆栈
    push ZL
    push ZH
    in USARTAI_TEMP,SREG            ;压状态寄存器中的标志值到堆栈
    push USARTAI_TEMP
    lds USARTAI_TEMP,USARTAI_RXEnd  ;检查接收作业是否己全部结束?
    cpi USARTAI_TEMP,USARTAI_REndI    ;否,则继续
    breq USART_RXCINT_First           ;是,就转至接收第一个字节处理
    ldi ZH,(1<<FE)|(1<<DOR)|(1<<PE) ;检查 USART 接收器是否有帧错误(FE)、
    in USARTAI_TEMP,UCSRA             ;数据溢出(DOR)及奇偶校验错误(UPE)
    and USARTAI_TEMP,ZH               ;否,则继续
    brne USART_RXCINT_Error           ;是,就转至接收错误处理
    lds ZL,USARTAI_RXAPL            ;置接收作业地址指针
    lds ZH,USARTAI_RXAPH
    in USARTAI_TEMP,UDR             ;从 USART 数据寄存器取出接收数据
    st Z,USARTAI_TEMP                 ;存储进 SRAM 中
    adiw ZL,$01                     ;接收作业地址指针 + 1 
    sts USARTAI_RXAPL,ZL              ;存储回 SRAM 中
    sts USARTAI_RXAPH,ZH
    dec USARTAI_RXNum               ;全部接收作业完毕否?
    breq USART_RXCINT_End             ;是,就转至结束处理
    rjmp USART_RXCINT_RET             ;否,转到中断返回
USART_RXCINT_End:
    ldi ZL,USARTAI_REndI            ;置接收作业全部结束标志值
    sts USARTAI_RXEnd,ZL
    ldi ZL,USARTAI_RUPDI            ;置接收作业己更新标志值
    sts USARTAI_RXUPD,ZL
    ldi ZH,(1<<TOIE0)               ;禁止T/C0计数溢出中断
    com ZH                            ;注:仅只改变T/C中断屏蔽寄存
    in ZL,TIMSK                       ;器中的此项设置,对于其他T/C
    and ZL,ZH                         ;中断状态保留原来设置
    out TIMSK,ZL
    rjmp USART_RXCINT_RET           ;转到中断返回
USART_RXCINT_Error:
    ldi ZH,(1<<TOIE0)               ;禁止T/C0计数溢出中断
    com ZH                            ;注:仅只改变T/C中断屏蔽寄存
    in ZL,TIMSK                       ;器中的此项设置,对于其他T/C
    and ZL,ZH                         ;中断状态保留原来设置
    out TIMSK,ZL
    in USARTAI_TEMP,UDR             ;读 USART 数据寄存器使 RXC 标志清除,
                                      ;以结束本次 USART 接收结束中断处理
    ldi ZL,USARTAI_RUPDI            ;置接收作业己更新标志值
    sts USARTAI_RXUPD,ZL
    rjmp USART_RXCINT_RET           ;转到中断返回
USART_RXCINT_First:
    clr ZL                          ;清除接收作业全部结束标志
    sts USARTAI_RXEnd,ZL
    sts USARTAI_T0VNum,ZL           ;定时器/计数器0溢出次数清 0
    in ZL,TIFR                      ;清除T/C0计数溢出标志
    ori ZL,(1<<TOV0)                  ;注:仅只清除T/C中断标志寄存
    out TIFR,ZL                       ;器中的此项标志,对于其他T/C
                                      ;中断标志保留原来状态
    ldi ZL,USARTAI_T0CNTI           ;置T/C0定时参数的预定计数比例值
    out TCNT0,ZL
    in ZL,TIMSK                     ;使能T/C0计数溢出中断
    ori ZL,(1<<TOIE0)                 ;注:仅只改变T/C中断屏蔽寄存
    out TIMSK,ZL                      ;器中的此项设置,对于其他T/C
                                      ;中断状态保留原来设置
    ldi ZL,(1<<CS00)|(0<<CS01)|(1<<CS02)
    out TCCR0,ZL                    ;按CK÷1024 预分频因子启动T/C0
    lds ZL,USARTAI_RXCOM            ;接收作业是否为接收命令
    cpi ZL,USARTAI_RCOMI              ;否,则为接收数据
    breq USART_RXCINT_FCOMM           ;是,就转至接收命令处理
USART_RXCINT_FData:
    ldi ZL,Low(USARTAI_RXDAA)       ;置接收作业地址指针为
    ldi ZH,High(USARTAI_RXDAA)        ;首个接收数据地址指针
    in USARTAI_TEMP,UDR             ;从 USART 数据寄存器取出接收数据
    st Z,USARTAI_TEMP                 ;存储进 SRAM 中
    adiw ZL,$01                     ;接收作业地址指针 + 1
    sts USARTAI_RXAPL,ZL              ;存储回 SRAM 中
    sts USARTAI_RXAPH,ZH
    mov USARTAI_RXNum,USARTAI_TEMP  ;置接收作业次数计数器初值
    dec USARTAI_RXNum               ;接收作业次数-1
    rjmp USART_RXCINT_RET           ;转到中断返回
USART_RXCINT_FCOMM:
    ldi ZL,Low(USARTAI_RXCOA)       ;置接收作业地址指针为
    ldi ZH,High(USARTAI_RXCOA)        ;首个接收命令地址指针
    in USARTAI_TEMP,UDR             ;从 USART 数据寄存器取出接收数据
    st Z,USARTAI_TEMP                 ;存储进 SRAM 中
    adiw ZL,$01                     ;接收作业地址指针 + 1
    sts USARTAI_RXAPL,ZL              ;存储回 SRAM 中
    sts USARTAI_RXAPH,ZH
    ldi USARTAI_TEMP,(USARTAI_CMATNI-1) 
                                    ;置接收作业次数计数器初值,
    mov USARTAI_RXNum,USARTAI_TEMP    ;第一个命令的字符串己接收
USART_RXCINT_RET:
    pop USARTAI_TEMP                ;弹出堆栈中的标志值到状态寄存器
    out SREG,USARTAI_TEMP
    pop ZH                          ;弹出堆栈中的数值到寄存器
    pop ZL
    pop USARTAI_TEMP
    reti                            ;中断返回


;*******************************************************************************
;*
;* USART 异步通信数据寄存器空中断发送处理子程序 - “USART_TXDREINT”
;*
;* 说明:
;*   本子程序用于 USART 异步通信数据寄存器空中断发送处理。
;* 
;* 注意:
;*   发送作业全部结束后,将禁止 USART 数据寄存器空中断操作。
;* 
;* SRAM 中标志字节用法:
;*   入口标志:本子程序将检查这些标志,依据这些标志置值来控制不同发送作业。
;*        r6 --- 发送作业次数(USARTAI_TXNum)
;*   出口标志:发送作业全部正确发送完成后,将对下面这两个标志置值。
;*               发送作业全部结束(USARTAI_TXEnd)= $f0(USARTAI_TEndI)
;*        r6 --- 发送作业次数(USARTAI_TXNum)    = $00
;*
;*******************************************************************************

USART_TXDREINT:
    push USARTAI_TEMP               ;压入寄存器中的数值到堆栈
    push ZL
    push ZH
    in USARTAI_TEMP,SREG            ;压状态寄存器中的标志值到堆栈
    push USARTAI_TEMP
    lds ZL,USARTAI_TXAPL            ;置发送作业地址指针
    lds ZH,USARTAI_TXAPH
    ld USARTAI_TEMP,Z               ;从 SRAM 中取出发送字节,
    out UDR,USARTAI_TEMP              ;送入 USART 数据寄存器
    adiw ZL,$01                     ;发送作业地址指针 + 1
    sts USARTAI_TXAPL,ZL              ;存储回 SRAM 中
    sts USARTAI_TXAPH,ZH
    dec USARTAI_TXNum               ;发送作业全部完毕否?
    brne USART_TXDREINT1              ;否,转到中断返回
    ldi USARTAI_TEMP,USARTAI_TEndI  ;置发送作业全部结束标志值
    sts USARTAI_TXEnd,USARTAI_TEMP
    cbi UCSRB,UDRIE                 ;禁止 USART 数据寄存器空中断
USART_TXDREINT1:
    pop USARTAI_TEMP                ;弹出堆栈中的标志值到状态寄存器
    out SREG,USARTAI_TEMP
    pop ZH                          ;弹出堆栈中的数值到寄存器
    pop ZL
    pop USARTAI_TEMP
    reti                            ;中断返回


;*******************************************************************************
;*
;* USART 异步通信数据寄存器空中断发送处理初始化子程序 - “USART_AINT_TXINI”
;*
;* 说明:
;*   本子程序用于初始化 USART 异步通信数据寄存器空中断发送处理。
;* 
;* 注意:
;*   1.在运行本程序前必须先运行“USART_AINT_INI”子程序。
;*   2.在运行本程序前必须先将要发送的数据块复制到 SRAM 相应的存储区中。
;*   3.本子程序运行后,将立即启动数据寄存器空中断,进行发送作业。
;*
;* SRAM 中标志字节用法:
;*   入口标志:本子程序将检查这些标志,依据这些标志置值来控制不同发送作业。
;*               发送命令作业(USARTAI_TXCOM)    = $e0(USARTAI_TCOMI)
;*   出口标志:本子程序运行后,将对下面这两个标志置值。
;*               发送作业全部结束(USARTAI_TXEnd)= $00
;*        r6 --- 发送作业次数(USARTAI_TXNum)    = 发送的首个字节
;* 
;*******************************************************************************

USART_AINT_TXINI:
    clr ZL                          ;清除全部数据发送结束标志
    sts USARTAI_TXEnd,ZL
    lds ZL,USARTAI_TXCOM            ;发送任务是否为发送命令
    cpi ZL,USARTAI_TCOMI              ;否,则为发送数据
    breq USART_AINT_TXINI1            ;是,就转至发送命令处理
    ldi ZL,Low(USARTAI_TXDAA)       ;置首个发送地址指针为发送数据初值
    ldi ZH,High(USARTAI_TXDAA)        ;发送的首个数据为本次发送作业次数
    sts USARTAI_TXAPL,ZL
    sts USARTAI_TXAPH,ZH
    ld USARTAI_TXNum,Z              ;置发送作业次数计数器初值
    rjmp USART_AINT_TXINI2
USART_AINT_TXINI1:
    ldi ZL,Low(USARTAI_TXCOA)       ;置首个发送地址指针为发送命令初值
    ldi ZH,High(USARTAI_TXCOA)        ;发送的首个命令为本次发送作业次数
    sts USARTAI_TXAPL,ZL
    sts USARTAI_TXAPH,ZH
    ldi USARTAI_TEMP,USARTAI_CMATNI ;置发送作业次数计数器初值
    mov USARTAI_TXNum,USARTAI_TEMP    ;注:发送命令作业为固定次数
USART_AINT_TXINI2:

⌨️ 快捷键说明

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