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

📄 i2c_eemem.s43

📁 MSP430 I2C模块与EEPROM的接口汇编程序
💻 S43
📖 第 1 页 / 共 2 页
字号:
            sub.b   #39,RXTXData        ; Yes, convert numbers A-F to binary
Test_end    and.b   #0Fh,RXTXData       ; Blank upper nibble by logical AND
                                        ; with '0000 1111' binary
Test_ret    ret

Get3digits  call    #RX                 ; Get first byte of address     
            call    #Test_Blck          ; Test if indicates memory block 0 or 1
Get2digits  call    #RX                 ; Get Byte = 1st byte of address within
                                        ; block, or 1st data byte to write
            call    #Test_Num           ; Convert to Binary
            rla     RXTXData            ; Rotate byte up to recieve next byte 
            rla     RXTXData            ;    "         "       "       " 
            rla     RXTXData            ;    "         "       "       "
            rla     RXTXData            ;    "         "       "       "
            push.b  RXTXData            ; Save upper byte on stack  
            call    #RX                 ; Get byte = 2nd byte of address or data   
            call    #Test_Num           ; Convert to Binary
            add.b   @SP+,RXTXData       ; Add upper byte back to form word
            ret

;-------------------------------------------------------------------------------
TX_String;  Set up and transmit ASCII strings, R11 used as pointer
;           Note: End of a string in quotes is read as null character = 0
;-------------------------------------------------------------------------------
TX_S1       mov.b  @R11+,RXTXData       ; Move string start to data buffer
            call   #TX_Byte             ; Set up to send string
            tst.b  0(R11)               ; Test if next character in string = 0,
                                        ; R11 autoincremented above
            jnz    TX_S1                ; If not "0" then loop again (see note)
            ret                         ; String complete, return 
            
;-------ASCII strings to diplay on PC-------------------------------------------
String0     DB CR,LF,"If address < 100 hex use leading 0 (ex.= 0ff)"
String1     DB CR,LF,CR,LF,"r/w? "
String2     DB "000-1ff? "
String4     DB "w?"
String5     DB "= "
            
            EVEN 
;-------------------------------------------------------------------------------
TX_Byte_ASCII; Convert and TX byte from DataConv in two ASCII bytes
;-------------------------------------------------------------------------------
            push   DataConv             ; Save current value to stack
            call   #NUM_ASCIR           ; Convert value to ASCII
            push   DataConv             ; Save value again, cleaned off below
            call   #NUM_ASCIA          
            ret                         

NUM_ASCIR;  Convert Numbers 0 to f into ASCII left aligned  @ 2(SP)
            rrc    2(SP)                ; 1st pass - value pushed to stack is 
            rrc    2(SP)                ; rotated to move upper nibble in place 
            rrc    2(SP)                ; of lower nibble
            rrc    2(SP)                ;

NUM_ASCIA;    
            and    #0fh,2(SP)           ; AND with 0000 1111 = clear high nibble
            add    #030h,2(SP)          ; Add 30 hex to convert to ASCII (0-9)
            cmp    #03ah,2(SP)          ; Value = 0 to 9 decimal? 
            jlo    NUM_End              ; Yes, jump next instruction
            add    #039,2(SP)           ; No, adjust for hex values A to F 
NUM_End     mov    2(SP),RXTXData       ; load TX buffer, sent in TX_Byte below
            mov    @SP+,0(SP)           ; Clean up top of stack
                                        
;-------------------------------------------------------------------------------
TX_Byte;    Set up CCR0 to send byte via UART
;           Note: Program loops until all bits sent via TA0_ISR
;-------------------------------------------------------------------------------
            mov    #TX_Count,BitCnt     ; Routine labels (in TX_Count)->Pointer
            push   &TAR                 ; Save current Timer_A count to stack
            add    #Bitime,0(SP)        ; Add next bit offset to value on stack
            pop    &CCR0                ; Load adjusted next bit offset to CCR0
            mov    #OUTMOD2+OUTMOD0+CCIE,&CCTL0  ; Set up mode and interrupt,
                                                 ; TX space = start bit 
TX_Wait     bit    #CCIE,&CCTL0         ; TX complete? CCIE cleared in TA0_ISR
            jnz    TX_Wait              ; No, loop again 
            ret                         
                                        
;-------------------------------------------------------------------------------
RX_Ready;   Subroutine that readies UART to RX byte into RXTXData buffer.
;-------------------------------------------------------------------------------
            mov    #RX_Count,BitCnt     ; Routine labels (in RX_Count)->Pointer
            mov    #CCIS0+CM1+CCIE+CAP+OUT,&CCTL0  ; Set up mode and interrupt
            ret 
                                    
;-----------UART Subroutines end-------------------------------------------------                                        
            
                                        
;-------------------------------------------------------------------------------
TA0_ISR;    CCR0/UART interrupt service routine - each interrupt transmits or 
;           receives one bit from the PC until all 8 bits of a byte are complete
;-------------------------------------------------------------------------------
            add    #Bitime,&CCR0        ; Add offset for next bit
            br     @BitCnt+             ; Branch to next routine in 
                                        ; RX_count or TX_count table, set above
TX_Bit      rra.b  RXTXData             ; LSB is shifted to carry
            jc     TX_Mark              ; Jump if bit = 1
TX_Space    bis    #OUTMOD2,&CCTL0      ; TX space to PC 
            reti                        
TX_Comp     bic    #CCIE,&CCTL0         ; All Bits TX, disable interrupt 
TX_Mark     bic    #OUTMOD2,&CCTL0      ; TX mark to PC 
            reti                        
RX_Edge     bic    #CAP,&CCTL0          ; Switch to compare mode
            add    #Bitime_5,&CCR0      ; First databit 1.5 bits from edge
            mov    #CPUOFF+GIE,0(SP)    ; CPU off (LPM0)& enable interrupts bits
                                        ; set in status register contents stored
                                        ; on stack. Use LPM0 since need DCO on  
            reti                        
RX_Bit      bit    #SCCI,&CCTL0         ; Get bit waiting in SCCI
            rrc.b  RXTXData             ; Store received bit
            reti
            
RX_Comp     bic    #CCIE,&CCTL0         ; All bits RX, disable interrupt 
            mov    #GIE,0(SP)           ; Enable interrupts in SR value on stack
            reti                        
            
;-------------------------------------------------------------------------------
; Table of routines moved into BitCnt and used to branch within the Timer A ISR
;-------------------------------------------------------------------------------
            EVEN
RX_Count    DW     RX_Edge              ; Set up Timer_A for RX
            DW     RX_Bit               ; RX first data bit
            DW     RX_Bit               ;    second
            DW     RX_Bit               ;    third
            DW     RX_Bit               ;    fourth
            DW     RX_Bit               ;    fifth
            DW     RX_Bit               ;    sixth
            DW     RX_Bit               ;    seventh
            DW     RX_Bit               ; RX eighth (last) data bit
            DW     RX_Comp              ; RX complete, process RX data
TX_Count    DW     TX_Bit               ; TX first data bit
            DW     TX_Bit               ;    second
            DW     TX_Bit               ;    third
            DW     TX_Bit               ;    fourth
            DW     TX_Bit               ;    fifth
            DW     TX_Bit               ;    sixth
            DW     TX_Bit               ;    seventh
            DW     TX_Bit               ; TX eighth (last) data bit
            DW     TX_Mark              ; TX stop bit = mark
TX_End      DW     TX_Comp              ; TX complete 
                                        
;-------------------------------------------------------------------------------
Init_Sys;   Initialize System Peripherals  
;-------------------------------------------------------------------------------
            mov    #WDTPW+WDTHOLD,&WDTCTL ; Stop watchdog timer, not used
SetupTA     mov    #TASSEL1+TACLR,&TACTL  ; Clear TAR & set TAR source = SMCLK
SetupBC     mov.b  #XTOFF+DIVA1+RSEL2+RSEL0,&BCSCTL1   ; ACLK/4  RSEL=5
SetupC0     mov    #OUT,&CCTL0          ; TXD idle as mark 
SetupP1_2   bis.b  #TXD,&P1SEL          ; P1.1 to output TA0 for TXD to PC
            bis.b  #TXD,&P1DIR          ; P1.1 set to output for TXD
            bis.b  #RXD,&P2SEL          ; P2.2 to input TA0 for RXD from PC
            bic.b  #SCL+SDA,&P2OUT      ; SCL & SDA data = 0, low when = outputs
            bis    #MC1,&TACTL          ; Start Timer_A in continous mode
            call   #Delay               ; Delay for crystal stabalization                  
            call   #Set_DCO             ; Calibrate DCO to 1228800 hz 
            eint                        ; General interrupt enable
            ret                         
                                        
;------------------------------------------------------------------------------- 
Delay;      Software delay
;------------------------------------------------------------------------------- 
            push   #0FFFFh              ; Delay to top of stack
L1          dec    0(SP)                ; Decrement value on top of stack
            jnz    L1                   ; Loop if value not = 0
            incd   SP                   ; Clean top of stack
            ret                         

;------------------------------------------------------------------------------- 
Set_DCO;    Subroutine: Sets DCO to selected frequency based on 'Delta' value.
;           R14 and R15 are temporarily used, they could also be used
;           elsewhere in the program. ACLK = 32768/4, Timer_A clocked by DCO
;------------------------------------------------------------------------------- 
            clr     R15                 ; Clear register
Setup_CC2   mov     #CCIS0+CM0+CAP,&CCTL2 ; Define CCR2=ACLK,CAP mode,pos. edge
Test_DCO    bit     #CCIFG,&CCTL2       ; Test flag, capture occured?
            jz      Test_DCO            ; No, loop until captured
            bic     #CCIFG,&CCTL2       ; Yes, clear interrupt flag
AdjDCO      mov     &CCR2,R15           ; Move captured SMCLK to R15
            sub     R14,R15             ; SMCLK difference into R15
            mov     &CCR2,R14           ; Save SMCLK to R14 in case another loop
                                        ; is needed to complete calibration
            cmp     #Delta,R15          ; Delta = SMCLK/(32768/4)?
            jlo     IncDCO              ; Jump if lower to increment DCO
            jeq     DoneDCO             ; Jump if equal to done
DecDCO      dec.b   &DCOCTL             ; If neither, then decrement DCO 
            jmp     Test_DCO            ; Loop to test again
IncDCO      inc.b   &DCOCTL             ; Increment DCO speed
            jmp     Test_DCO            ; Loop to test again 
DoneDCO     clr     &CCTL2              ; Calibration complete stop CCR2 
            ret

;-------------------------------------------------------------------------------
            RSEG   INTVEC               ; MSP430x11x1 interrupt vectors
;-------------------------------------------------------------------------------
            ORG     TIMERA0_VECTOR
            DW      TA0_ISR             ; Timer_A - Capture/Compare 0
            ORG     RESET_VECTOR
            DW      RESET               ; POR, ext. Reset, Watchdog

;-------------------------------------------------------------------------------
            END

⌨️ 快捷键说明

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