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

📄 isr.s03

📁 embed in keil
💻 S03
📖 第 1 页 / 共 2 页
字号:
;                               SERIAL PORT COMMUNICATIONS                               |
;                                                                                        |
; void Serial(void)                                                                      |
;                                                                                        |
; This module is the serial port Interrupt Service Routine. It follows the standard uC/OS|
; procedure of interrupt handling:                                                       |
;                                                                                        |
;  - machine registers saving                                                            |
;  - OS entry notification (OSIntEnter)                                                  |
;  - interrupt handling (application specific)                                           |
;  - OS exit notification (may result in a context switch)                               |
;  - machine registers restoration.                                                      |
;                                                                                        |
; In this application, receive and transmit interrupts are handled as follows:           |
;                                                                                        |
; - Receive interrupt: We test for a flag bit that denotes whether or not we are in a    | 
;                      code transfer. If so, we call procedure "Load_Code". If not in a  |
;                      code transfer, we check if character received is a 'CR' (Carriage |
;                      Return), which would signal the end of a data block. In this case |
;                      we call the OS procedure to signal the communications semaphore   |
;                      ("OSSemPost()"). This in turn will awaken the "Communications Ma- |
;                      nager" task, which is pending on this semaphore. This task will   |
;                      look at the communications receive buffer, and will act on.       |
;                                                                                        |
;                      If character is not a 'CR', it is simply stored in the buffer, and|
;                      the buffer pointer is incremented accordingly.                    |
;                                                                                        |
; - Transmit interrupt: We test a flag bit that signals whether this was the last byte   |
;                       in a block to be transmitted. If it is, (flag cleared) the block |
;                       has been sent, and this is the indication. We simply reset the   |
;                       block pointers. If it is not (flag set), we get the next byte in |
;                       the block, and send it.                                          |
;----------------------------------------------------------------------------------------+
         MODULE   SERIAL            ;Module name
         RSEG     CODE              ;Relocatable segment

;<---[ Symbols available for other modules: ]-------------------------------------------->

         PUBLIC    Serial           ;Handles microcontroller serial port
         
;<---[ Symbols referenced, in other modules: ]------------------------------------------->
         
         EXTERN   OSSemPost         ;Module: Function to signal a semaphore 
         EXTERN   OSIntEnter        ;Module: Notify OS that interrupt is being serviced
         EXTERN   OSIntExit         ;Module: Notify OS that interrupt is being exited

         EXTERN   Comm_Sem          ;Address of the serial port semaphore handle
;<--------------------------------------------------------------------------------------->
Serial:                             ;Module entry point
 
         push    PSW                        ;Save PSW
         push    ACC                        ;Save accumulator
         push    b                          ;Save B register
         push    Bk0_r0                     ;Save Bank #0 R0
         push    Bk0_r1                     ;Save Bank #0 R1
         push    Bk0_r2                     ;Save Bank #0 R2
         push    Bk0_r3                     ;Save Bank #0 R3
         push    Bk0_r4                     ;Save Bank #0 R4
         push    Bk0_r5                     ;Save Bank #0 R5
         push    Bk0_r6                     ;Save Bank #0 R6
         push    Bk0_r7                     ;Save Bank #0 R7
         push    DPH                        ;Save Pointer high
         push    DPL                        ;Save Pointer low
         push    XSP                        ;Save xstack base pointer high
         push    XSP+1                      ;Save xstack base pointer low         
         lcall   OSIntEnter                 ;Read-modify-write increment of OSIntNesting

         jbc     TI, xmt_on                 ;Skip if transmit interrupt
         clr     RI                         ;It's a receive interrupt: clear bit
         mov     a, SBUF                    ;Get character
         jnb     COD_FLAG, ser_01           ;If we're not in the middle of a code download, get out
     ;    call    Load_Code                  ;We are: Load Code (call procedure...)
         sjmp    ser_00                     ;..and return to caller

xmt_on:  jnb     XMT_FLAG, ser_00           ;If there is no transmission, we're done
         mov     a, Bk2_r0                  ;Get pointer high to next byte to send
         cjne    a, Bk2_r2, not_yet         ;Compare with top of block (h)
         mov     a, Bk2_r1                  ;Get pointer low to next byte to send
         cjne    a, Bk2_r3, not_yet         ;Compare with top of block (l)
         clr     XMT_FLAG                   ;Block transmitted: we're done
         sjmp    ser_00                     ;..and get out

not_yet: mov     DPH, Bk2_r0                ;Point to next byte (h)
         mov     DPL, Bk2_r1                ;..idem (l)
         movx    a, @dptr                   ;Get next byte to send
         inc     dptr                       ;Increment pointer
         mov     Bk2_r0, DPH                ;Save data pointer in the registers
         mov     Bk2_r1, DPL                ;..of bank #2
         mov     SBUF, a                    ;And transmit the data byte
         sjmp    ser_00                     ;Return to code

ser_01:  cjne    a, #CR, ser_02             ;If not a "Carriage Return", go on
         mov     DPH, Bk3_r0                ;Load pointer to reception buffer (high)
         mov     DPL, Bk3_r1                ;Load pointer to reception buffer (low)
         clr     a                          ;Clear accumulator
         movx    @dptr, a                   ;Store block delimiter in reception buffer
         mov     Bk3_r0, #HIGH RCV_BUFF     ;Set the pointer to the reception buffer..
         mov     Bk3_r1, #LOW  RCV_BUFF     ;..pointing to the buffer base
         mov     R7, #01                    ;Parameter: pointer type (IAR specific)
         mov     dptr, #Comm_Sem + 1        ;Point to the semaphore handle (high)
         movx    a, @dptr                   ;Read pOS_EVENT high
         mov     R6, a                      ;Parameter: pointer high
         inc     dptr                       ;Increment pointer
         movx    a, @dptr                   ;Read pOS_EVENT low
         mov     R5, a                      ;Parameter: pointer low 
         call    OSSemPost                  ;Call procedure to signal semaphore                                       
         sjmp    ser_00                     ;Return to code
                                 
ser_02:  mov     b, a                       ;Save byte received in register B
         mov     a, Bk3_r0                  ;Load pointer to buffer (high)
         cjne    a, #HIGH XMT_BUFF, ser_03  ;Verify we do not overflow buffer
         mov     Bk3_r0, #HIGH RCV_BUFF     ;Error: Reset pointers to the communication buffer..
         mov     Bk3_r1, #LOW  RCV_BUFF     ;..to the base of buffer
   ;      mov     ERR_BUFF, #OVERFLOW        ;Log the error
         sjmp    ser_00                     ;And return to code

ser_03:  mov     DPH, a                     ;Load pointer to reception buffer (high)
         mov     DPL, Bk3_r1                ;Load pointer to reception buffer (low)
         mov     a, b                       ;Retrieve character received
         movx    @dptr, a                   ;Pass byte to buffer
         inc     dptr                       ;Point to next location in buffer
         mov     Bk3_r0, DPH                ;Save new pointer high
         mov     Bk3_r1, DPL                ;Save new pointer low
         mov     SBUF, a                    ;Echo character to host

ser_00:  lcall   OSIntExit                  ;Decrement OSIntNesting
         pop     XSP+1                      ;Restore xstack base pointer low
         pop     XSP                        ;Restore xstack base pointer high
         pop     DPL                        ;Restore pointer low
         pop     DPH                        ;Restore pointer high
         pop     Bk0_r7                     ;Restore Bank #0 R7
         pop     Bk0_r6                     ;Restore Bank #0 R6
         pop     Bk0_r5                     ;Restore Bank #0 R5
         pop     Bk0_r4                     ;Restore Bank #0 R4
         pop     Bk0_r3                     ;Restore Bank #0 R3
         pop     Bk0_r2                     ;Restore Bank #0 R2
         pop     Bk0_r1                     ;Restore Bank #0 R1
         pop     Bk0_r0                     ;Restore Bank #0 R0    
         pop     b                          ;Restore register B
         pop     ACC                        ;Restore accumulator
         pop     PSW                        ;Restore PSW
         reti                               ;Jump to execute scheduled task

         END

⌨️ 快捷键说明

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