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

📄 196a.cod

📁 mcs51,2051,x86系列MCU
💻 COD
📖 第 1 页 / 共 4 页
字号:
cseg at 2030h
tx_vector:     dcw  transmit
     $$end$
     $$if$ INT_MASK.6
cseg at 200Ch
serial_vector:  dcw  serial_isr
     $$end$     

     $$if$ INT_MASK1.0 || INT_MASK.6
TRANSMIT_BUF_SIZE   set  20
     $$end$
     $$if$ INT_MASK1.1 || INT_MASK.6
RECEIVE_BUF_SIZE    set  20
     $$end$
     $$if$ INT_MASK1.0 || INT_MASK.6

; transmit buffer and it's indexes

dseg
trans_buff:    dsb  TRANSMIT_BUF_SIZE

rseg
begin_trans_buff:   dsb  1
end_trans_buff:     dsb  1
     $$end$
     $$if$ INT_MASK1.1 || INT_MASK.6

; receive buffer and it's indexes

dseg
receive_buff:  dsb  RECEIVE_BUF_SIZE

rseg
end_rec_buff:       dsw 1
begin_rec_buff:     dsw 1
     $$end$

cseg
     $$if$ INT_MASK1.0 || INT_MASK.6

transmit:                            ;serial interrupt routine
     pusha
     push  tmpreg

; image sp_status into sp_status_image

     _ReadSFR  tmpreg,  sp_stat
     orb   sp_status_image, tmpreg

; transmitt a character if there is a character in the buffer
; else leave TI_BIT set in image for putchar to enable interrupts

     cmpb  begin_trans_buff,  end_trans_buff
     je    no_char_to_send
          $$if$ SP_CON.4

; If bit 8 needs to be set, then the following line needs to
; be inserted:
;     _SetSFR_bit  sp_con, SET_BIT_8

          $$end$
     ldbze tmpreg, begin_trans_buff
     ldb   tmpreg, trans_buff[tmpreg]
     incb  begin_trans_buff
     _WriteSFR  sbuf, tmpreg                 ;tranmit character

; The next statement makes the buffer circular by starting over when the
; index reaches the end of the buffer.

     cmpb  begin_trans_buff, #TRANSMIT_BUF_SIZE-1
     bnh   not_at_end_of_buffer
     clrb  begin_trans_buff
not_at_end_of_buffer:
     _ClrBitReg sp_status_image, TI_BIT         ;clear TI bit in sp_status_image.
no_char_to_send:
     pop   tmpreg
     popa
     ret

putchar:

; Remain in loop while the buffer is full.  This is done by checking
; the end of buffer index to make sure it does not overrun the
; beginning of buffer index. The while instruction checks the case
; when the end index is one less then the beginning index and at the
; end of the buffer when the beginning index may be equal to 0 and
; the end buffer index may be at the buffer end.

wait_for_buffer_ready:
     addb  tmpreg, end_trans_buff, #1
     cmpb  tmpreg, begin_trans_buff
     je    wait_for_buffer_ready
     cmpb  end_trans_buff, #TRANSMIT_BUF_SIZE-1
     jne   ready_to_send
     cmpb  begin_trans_buff, zero_reg
     je    wait_for_buffer_ready
ready_to_send:
     ldb   tmpreg, 2[sp]

; put character in buffer

     ldbze tmpreg+2, end_trans_buff
     stb   tmpreg, trans_buff[tmpreg + 2]
     incb  end_trans_buff

; make buffer circular.

     cmpb  end_trans_buff, #TRANSMIT_BUF_SIZE - 1
     bnh   not_at_end_of_buffer2
     clrb  end_trans_buff
not_at_end_of_buffer2:
     jbc   sp_status_image, TI_BIT, dont_set_interrupt

; if transmitt buffer was empty, then cause an interrupt
; to start transmitting.

     $$if$  INT_MASK1.0
     orb   int_pend1, #TXD_INTERRUPT  
     $$end$
     $$ifn$ INT_MASK1.0 && INT_MASK.6
     orb  int_pend, #SERIAL_INT
     $$end$ 
dont_set_interrupt:
     ret
     $$end$
     $$if$ INT_MASK1.1 || INT_MASK.6

receive:                              ;serial interrupt routine
     pusha
     push  tmpreg                    ;image sp_status into sp_status_image
     _ReadSFR  tmpreg,  sp_stat
     orb   sp_status_image, tmpreg

; If the input buffer is full, the last character can be handled
; as desired.

     add   tmpreg, end_rec_buff, #1
     cmp   tmpreg, begin_rec_buff
     je    handle_overrun
     cmp   end_rec_buff, #RECEIVE_BUF_SIZE-1
     jne   ready_to_receive
     cmpb  begin_rec_buff, zero_reg
     jne   ready_to_receive           ;not 0 so okay to receive
handle_overrun:                       ;input overrun code
    
ready_to_receive:

; The next statement makes the buffer circular by starting over when the
; index reaches the end of the buffer.

     inc   end_rec_buff

; Make a circular buffer.

     cmp   end_rec_buff, #RECEIVE_BUF_SIZE - 1
     bnh   not_at_end_rec_buffer
     clr   end_rec_buff
not_at_end_rec_buffer:
     _ReadSFR  tmpreg, sbuf
     stb  tmpreg, receive_buff[end_rec_buff]

; Check for errors.

     jbc  sp_status_image, FE_BIT, no_frame_error

     ; User code for framing error

     _ClrBitReg sp_status_image, FE_BIT     
no_frame_error:
     jbc  sp_status_image, OE_BIT, no_overrun_error

     ; User code for overrun error

     _ClrBitReg sp_status_image, OE_BIT 
no_overrun_error:
     $$if$ SP_CON.2
     jbc  sp_status_image, RPE_BIT, no_parity_error

     ; User code for Parity error

     _ClrBitReg sp_status_image, RPE_BIT 
no_parity_error:
     $$end$
     $$if$ SP_CON.4
     jbc  sp_status_image, RB8_BIT, no_8th_bit

     ; User code for Receiving BIT 8

     _ClrBitReg sp_status_image, RB8_BIT
no_8th_bit:
     $$end$
     _ClrBitReg sp_status_image,RI_BIT     ;clear RI bit in sp_status_image.
     pop  tmpreg
     popa
     ret

getchar:
     cmp  begin_rec_buff, end_rec_buff
     je   getchar
     inc  begin_rec_buff
     cmp  begin_rec_buff, #RECEIVE_BUF_SIZE - 1
     bne  not_at_end_rec_buf2

; Make buffer circular.

     clr  begin_rec_buff

; Return the character in buffer.

not_at_end_rec_buf2:
     ldb  tmpreg,  receive_buff[begin_rec_buff]
     ret
     $$end$
     $$if$  INT_MASK.6
          $$ifn$  INT_MASK1.0-1
;    The seperate txd and rxd interrupts can more efficiently process
;    the interrupts than the generic serial interrupt as this one 
;    does.
                 

serial_isr:
     pusha
     push  tmpreg                    ;image sp_status into sp_status_image
     _ReadSFR  tmpreg,  sp_stat
     orb   sp_status_image, tmpreg
     jbc   sp_status_image, RI_BIT, no_recieve
     call  receive
     br    done_serial
no_recieve:     
     jbc   sp_status_image, TI_BIT, no_transmit
     call  transmit
no_transmit:
done_serial:     
     pop  tmpreg,
     popa
     ret
          $$end$
          $$if$  INT_MASK1.0-1
;    The dedicated txd and rxd will service the serial interrupt,
;    therefore, this generic serial interrupt routine is not needed
;    and should be disabled.

serial_isr:
     ret

          $$end$          
    $$end$          
$$end$

cseg
init_serial:
; Baud rate generator configuration:
;   baud rate clock source = $%tbaud_rate.15$Fosc$t2clk pin$
;   baud rate  = @@BAUDRATE@
$$ifn$ sp_con.1 &! sp_con.0
;   baud_value = $%tbaud_rate.15$Fosc$t2clk$ / (baud rate$%tbaud_rate.15$ * 2) - 1$)$
$$end$
$$if$ sp_con.1 || sp_con.0
;   baud_value = $%tbaud_rate.15$Fosc$t2clk$ / (baud rate * $%tbaud_rate.15$16) - 1$8)$
$$end$

  _WriteSFR   baud_rate, #0@@BAUD_LO@h
  _WriteSFR   baud_rate, #0@@BAUD_HI@h

; Serial port configuration:
;   serial mode     = $%4sp_con.0-1$0$1$2$3$
$$if$ sp_con.0
;   even parity     = $%tsp_con.2$enabled$disabled$
$$end$
$$if$ sp_con.1 &! sp_con.0 
;   ninth data bit  = $%tsp_con.4$1$0$
$$end$
$$if$ sp_con.1 && sp_con.0 &! sp_con.2
;   ninth data bit  = $%tsp_con.4$1$0$
$$end$
;   serial receive  = $%tsp_con.3$enabled$disabled$
;   serial transmit = $%tIOC1.5$enabled$disabled$

  _$%tioc1.5$Set$Clr$SFR_bit ioc1, TXD_ENABLE
  _WriteSFR   sp_con, #0$$SP_CON$h

; Interrupts:
;   transmit interrupt = $%tINT_MASK1.0$enabled$disabled$
;   receive interrupt  = $%tINT_MASK1.1$enabled$disabled$
;   serial interrupt   = $%tINT_MASK.6$enabled$disabled$

$$if$  INT_MASK.6
  orb   int_mask, #SERIAL_INT
$$end$
$$if$ int_mask1.1 
  orb  int_mask1, #RI_INTERRUPT
$$end$
$$if$ int_mask1.0
  orb  int_mask1, #RI_INTERRUPT
$$end$
  ret

$$if$ INT_MASK1.0-1 || INT_MASK.6
     $$if$  INT_MASK1.1 || INT_MASK.6
     clr   end_rec_buff      ;init buffer pointers
     clr   begin_rec_buff
     $$end$
     $$if$  INT_MASK1.0 || INT_MASK.6
     clrb end_trans_buff
     clrb begin_trans_buff
     $$end$
$$end$
     ldb  sp_status_image, #20h   ; Init for initial transmittion
     ret

cseg at 02080h
main_serial:
     ld   sp, #STACK
     call init_serial
$$if$ INT_MASK1.0-1 || INT_MASK.6
     ei                          ;global interrupt enable
     $$if$ INT_MASK1.1 || INT_MASK.6

; The following lines will loop until the letter 'Q' is
; received.

look_for_Q:
     call getchar
     cmpb tmpreg, #'Q'
     jne  look_for_Q
     $$end$
     $$if$ INT_MASK1.0 || INT_MASK.6


; Example of sending out buffered data.

     push #'H'                      ;example sequence to send 'Hello'
     call putchar
     add  sp, #2
     push #'e'
     call putchar
     add  sp, #2
     push #'l'
     call putchar
     add  sp, #2
     push #'l'
     call putchar
     add  sp, #2
     push #'o'
     call putchar
     add  sp, #2
     $$end$
     br   $
$$end$
$$ifn$ INT_MASK1.0-1 &! INT_MASK.6
     $$if$ IOC1.5 && SP_CON.3
do_forever:
     call getchar
     push tmpreg
     call putchar
     add  sp, #2
     br   do_forever                ;transmitt the character received
     $$end$
     $$if$ IOC1.5 &! SP_CON.3
     push #041h                     ;pass the 'A' character
     call putchar                   ;transmitt a character
     add  sp, #2
     br   $
     $$end$
     $$ifn$ IOC1.5 && SP_CON.3
do_while_not_Q
     call getchar
     cmpb tmpreg, #051h           ;check for letter 'Q'
     bne  do_while_not_Q
     br   $
     $$end$
$$end$
end
##80C194 Timer1#
##80C198 Timer1#
##80C196KB Timer1#
##80C196KC Timer1#
##80C196KD Timer1#
##80C194 Timer2#
##80C198 Timer2#
##80C196KB Timer2#
##80C196KC Timer2#
##80C196KD Timer2#
$include (80c196kd.inc)

T1OVF_DETECTION         equ   2
TOVF_INT                equ   0
T2OVF_INT               equ   4
T2CAPTURE_INT           equ   3
T2OVF_DETECTION         equ   3
T2_CLOCK_INTERNAL       equ   0

; Timer $$TIMER_NUMBER$ configuration:
$$if$ (TIMER_NUMBER == 1)
;   overflow detection         = $%tioc1.2$enabled$disabled$
$$end$
$$if$ (TIMER_NUMBER == 2)
;   overflow detection         = $%tioc1.3$enabled$disabled$
$$if$ ioc3.0
;   clock source               = Internal - Fosc/16
$$end$
$$ifn$ ioc3.0
;   clock source               = External - $%tioc0.7$HSI1 pin$T2CLK pin$
$$end$
;   counting direction         = $%tioc2.1$determined by T2UPDN pin$up$
;   external reset             = $%tioc0.3$enabled$disabled$
    $$if$ ioc0.3
;   reset source               = $%tioc0.5$HSI0 pin$T2RST pin$
    $$end$
;   reset each write           = $%tioc0.1$enabled$disabled$
;   clock speed                = $%tioc2.0$fast increment$normal$ mode
;   overflow boundary          = $%tioc2.5$7fffh/0000h$ffffh/0000h$
$$end$

cseg
init_timer$$TIMER_NUMBER$:
$$if$ (TIMER_NUMBER == 2)
  $$if$ ioc0.7 || ioc0.5 || ioc0.3 || ioc0.1
  _ReadSFR  tmpreg, ioc0
    $$ifn$ ioc0.1
  andb tmpreg, #0FDh    ;   /*  clear ioc0.1 since reads as 1 */
    $$end$
  orb  tmpreg, # 0$%Xioc0 & 0xAA$h;
  _WriteSFR  ioc0, tmpreg
  $$end$
  $$if$ ioc2.5 || ioc2.1 || ioc2.0
  _ReadSFR  tmpreg, ioc2
  andb tmpreg, #07Fh    ;   /*  clear ioc2.7 since reads as 1 */
  orb  tmpreg, # 0$%Xioc2 & 0x23$h;
  _WriteSFR  ioc0, tmpreg
  $$end$
  $$if$ ioc3.0
  _SetSFR_bit  ioc3, T2_CLOCK_INTERNAL
  $$end$
  _$%tioc1.3$Set$Clr$SFR_bit ioc1, T$$TIMER_NUMBER$OVF_DETECTION
$$end$
$$if$ (TIMER_NUMBER == 1)
  _$%tioc1.2$Set$Clr$SFR_bit ioc1, T$$TIMER_NUMBER$OVF_DETECTION
$$end$


; Interrupts:
;   timer overflow interrupt   = $%tint_mask.0$enabled$disabled$
$$if$ (TIMER_NUMBER == 2)
;   timer 2 overflow interrupt = $%tint_mask1.4$enabled$disabled$
$$end$

$$if$ (TIMER_NUMBER == 2)
  _$%tint_mask1.4$Set$Clr$SFR_bit int_mask1, T2OVF_INT
  _$%tint_mask1.3$Set$Clr$SFR_bit int_mask1, T2CAPTURE_INT
$$end$
$$if$ (TIMER_NUMBER == 1)
  _$%tint_mask.0$Set$Clr$SFR_bit int_mask, TOVF_INT
$$end$
  ret

cseg at 2080h
main_timer$$TIMER_NUMBER$:
  call init_timer$$TIMER_NUMBER$
  br   $
end

##80C194 HSI0#
##80C198 HSI0#
##80C196KB HSI0#
##80C196KC HSI0#
##80C196KD HSI0#
##80C194 HSI1#
##80C198 HSI1#
##80C196KB HSI1#
##80C196KC HSI1#
##80C196KD HSI1#
##80C194 HSI2#
##80C198 HSI2#
##80C196KB HSI2#
##80C196KC HSI2#
##80C196KD HSI2#
##80C194 HSI3#
##80C198 HSI3#
##80C196KB HSI3#
##80C196KC HSI3#
##80C196KD HSI3#
$include (80c196kd.inc)

HSI0_EXT_INT        equ    10h
HSI0_PIN_ENABLE     equ    0
HSI1_PIN_ENABLE     equ    2
HSI2_PIN_ENABLE     equ    4
HSI3_PIN_ENABLE     equ    6
HSI_DATA_AVAIL_INT  equ    4h
SELECT_INT_VECTOR   equ    7
HSI_FIFO_FULL_INT   equ    40h
HSI_FIFO_4_INT      equ    4h


cseg 
init_hsi$$HSI_NUMBER$:
; HSI $$HSI_NUMBER$ module configuration:
$$if$  (HSI_NUMBER == 0)
;   input capture mode = $%4hsi_mode.0-1$eight positive transitions$each positive transition$each negative transition$every transistion$
;   hsi 0 external pin = $%tioc0.0$enabled$disabled$
;
  _$%thsi_mode.1$Set$Clr$SFR_bit hsi_mode, 1
  _$%thsi_mode.0$Set$Clr$SFR_bit hsi_mode, 0
   
  _$%tioc0.0$Set$Clr$SFR_bit ioc0, HSI$$HSI_NUMBER$_PIN_ENABLE
$$end$
$$if$  (HSI_NUMBER == 1)
;   input capture mode = $%4hsi_mode.2-3$eight positive transitions$each positive transition$each negative transition$every transistion$
; 
  _$%thsi_mode.3$Set$Clr$SFR_bit hsi_mode, 3
  _$%thsi_mode.2$Set$Clr$SFR_bit hsi_mode, 2

  _$%tioc0.2$Set$Clr$SFR_bit ioc0, HSI$$HSI_NUMBER$_PIN_ENABLE
$$end$
$$if$  (HSI_NUMBER == 2)
;   input capture mode = $%4hsi_mode.4-5$eight positive transitions$each positive transition$each negative transition$every transistion$
; 
  _$%thsi_mode.5$Set$Clr$SFR_bit hsi_mode, 5
  _$%thsi_mode.4$Set$Clr$SFR_bit hsi_mode, 4

  _$%tioc0.4$Set$Clr$SFR_bit ioc0, HSI$$HSI_NUMBER$_PIN_ENABLE
$$end$
$$if$  (HSI_NUMBER == 3)
;   input capture mode = $%4hsi_mode.6-7$eight positive transitions$each positive transition$each negative transition$every transistion$
; 
  _$%thsi_mode.7$Set$Clr$SFR_bit hsi_mode, 7
  _$%thsi_mode.6$Set$Clr$SFR_bit hsi_mode, 6

  _$%tioc0.6$Set$Clr$SFR_bit ioc0, HSI$$HSI_NUMBER$_PIN_ENABLE
$$end$


; Interrupts
;   sixth fifo int vector  = $%tioc1.7$hsi fifo full$hsi data available$
$$if$ (HSI_NUMBER == 0)
;   hsi 0 pin interrupt    = $%tint_mask.4$enabled$disabled$
$$end$
;   hsi data available int = $%tint_mask.2$enabled$disabled$
;   hsi fifo full int      = $%tint_mask1.6$enabled$disabled$  
;   hsi fifo 4 int         = $%tint_mask1.2$enabled$disabled$

  _$%tioc1.7$Set$Clr$SFR_bit ioc1, SELECT_INT_VECTOR
$$if$ (hsi_number != 0)
  _$%tint_mask.2$Set$Clr$SFR_bit int_mask, HSI_DATA_AVAIL_INT
$$end$
$$if$ (hsi_number == 0)
  $$if$ int_mask.4 && int_mask.2
  _OrSFR  int_mask, #(HSI0_EXT_INT+HSI_DATA_AVAIL_INT)
  $$end$
  $$ifn$ int_mask.4 &! int_mask.2
  _AndSFR int_mask, #not(HSI0_EXT_INT+HSI_DATA_AVAIL_INT)
  $$end$
  $$if$ int_mask.4 &! int_mask.2
  _$%tint_mask.2$Set$Clr$SFR_bit  int_mask, 2 ;  /* hsi data available */
  _$%tint_mask.4$Set$Clr$SFR_bit  int_mask, 4 ;  /* hsi0 external interrupt */
  $$end$
  $$ifn$ int_mask.4 && int_mask.2
  _$%tint_mask.2$Set$Clr$SFR_bit  int_mask, 2 ;  /* hsi data available */

⌨️ 快捷键说明

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