MSP430 CountDown / CountUp, Tastergesteuert

Über ein MOS4511 (7-Segment Treiber) wird eine 7-Segment-Anzeige angesteuert. In diesem Beispiel-Programm wird ein Count-Down/Count-Up programmiert, der aktuelle Wert wird über die Segmentanzeige angezeigt. Welcher Modus laufen soll (Count-Down/Count-Up) wird über ein Taster gesteuert. Ein weiteres Testprogramm für ein größeres Projekt.

Schaltplan

7seg_countdownup_circuit

Bild & Video

7seg_countdownup

ASM-Programm

FILE: main.asm

;***********************************************
;     ___       _             _     
;    |   |_ _ _| |___ ___   _| |___
;    | | |_'_| . | -_|  _|_| . | -_|
;    |___|_,_|___|___|___|_|___|___|
;
; FILE:     main.asm
; Author:   declis (xdec.de)
;***********************************************

    .cdecls "msp430g2231.h"
    .ref init_TimerA,ISR_TimerA,P13_ISR,left_rotate,output
    .global main
    .text

main:
    mov.w #0x280,SP                ;initialize stack pointer
    mov.w #WDTPW+WDTHOLD,&WDTCTL   ;stop watchdog timer

    bis.b #0xF0,&P1DIR             ;P1.7,P1.6,P1.5,P1.4 -> output
    bic.b #0xF0,&P1OUT             ;start with "0" (segment output)
    bic.b #BIT3,&P1DIR             ;P1.3 (S2) -> input
    bis.b #BIT3,&P1IE              ;enable P1.3 interrupt

    mov.w #0,R4                    ;segment output value in R4
                                   ;(shift to MSB on Port 1)
    mov.w #0,R5                    ;intern value (0-9) for segment
    mov.w #0,R14                   ;P1.3 interrupt flag
    mov.w #0,R15                   ;TimerA interrupt flag

    call #init_TimerA              ;initialize TimerA
    EINT                           ;interrupt enable

loop:
    cmp.w #1,R15                   ;if TimerA interrupt flag high -> output
    jz count_up_or_down
    jmp loop                       ;wait for interrupt

count_up_or_down:
    cmp.w #1,R14                   ;if P1.3 interrupt flag high -> countdown
    jz countdown                   ;else countup

countup:
    call #output                   ;call output routine
    inc.w R5                       ;increment intern segment value
    cmp.w #10,R5                   ;if R5>9, reset to zero
    jz reset_zero
    mov.w #0,R15                   ;reset TimerA flag
    jmp loop

countdown:
    call #output                   ;call output routine
    dec.w R5                       ;decrement intern segment value
    cmp.w #-1,R5                   ;if R5<0, reset to nine
    jz reset_nine
    mov.w #0,R15                   ;reset TimerA flag
    jmp loop

reset_zero:
    mov.w #0,R5                    ;reset intern value to zero
    mov.w #0,R4                    ;reset real output value to zero
    mov.w #0,R15                   ;reset TimerA flag
    jmp loop                       ;wait for next interrupt

reset_nine:
    mov.w #9,R5                    ;reset intern value to 9
    mov.w R5,R4                    ;copy intern value to R4
    call #left_rotate              ;calculate real value for output
    mov.w #0,R15                   ;reset TimerA flag
    jmp loop                       ;wait for next interrupt

    .sect TIMERA0_VECTOR           ;0xFFF2 Timer A CC0 (".int09")
    .word ISR_TimerA               ;interrupt service routine for TimerA
    .sect PORT1_VECTOR             ;0xFFE4 Port 1 (".int02")
    .word P13_ISR                  ;interrupt service routine for P1.3
    .end

FILE: lib_func.asm

;***********************************************
;     ___       _             _     
;    |   |_ _ _| |___ ___   _| |___
;    | | |_'_| . | -_|  _|_| . | -_|
;    |___|_,_|___|___|___|_|___|___|
;
; FILE:     lib_func.asm
; Author:   declis (xdec.de)
;***********************************************

    .cdecls "msp430g2231.h"
    .def init_TimerA,ISR_TimerA,P13_ISR,left_rotate,output
cycles .equ 62500u                 ;500ms
    .text
;------------------------------------------
; Name:         output
; Description:  output routine for 7-segment
;               display
; Input:        R4
; Returns:      nothing
; Destroys:     R4
;------------------------------------------
output:
    mov.w R5,R4                    ;copy intern value to R4
    call #left_rotate              ;rotate R4
    mov.b R4,&P1OUT                ;move R4 to Port1
    ret

;------------------------------------------
; Name:         left_rotate
; Description:  inputs from MOS4511 (A,B,C,D)
;               are on P1.7 to P1.4 (P1.7 = MSB)
;               so, the BCD code must be
;               rotate to P1.7 to P1.4
;               example:
;               before: 9=00001001
;               after:  9=10010000
; Input:        R4
; Returns:      nothing
; Destroys:     R4
;------------------------------------------
left_rotate:
    rla.w R4
    rla.w R4
    rla.w R4
    rla.w R4
    ret

;------------------------------------------
; Name:         init_TimerA
; Description:  initialize Timer A
;               cycles=(seconds*10^6Hz)/8
;               seconds=(8*cycles)/10^6Hz
;               62500 cycles = 500ms
;               SMCLK=~1MHz
; Input:        nothing
; Returns:      nothing
; Destroys:     nothing
;------------------------------------------
init_TimerA:
    bis.w #TASSEL_2+ID_3,&TACTL    ;SMCLK, 8x divider
    mov.w #cycles,&TACCR0
    bis.w #CCIE,&TACCTL0           ;enable TimerA interrupt
    bis.w #MC_1,&TACTL             ;start timer in up-mode
    ret

;------------------------------------------
; Name:         ISR_TimerA
; Description:  Interrupt Service Routine TA
; Input:        nothing
; Returns:      nothing
; Destroys:     R15
;------------------------------------------
ISR_TimerA:
    mov.w #1,R15                   ;set timer interrupt flag
    reti

;------------------------------------------
; Name:         ISR_TimerA
; Description:  Interrupt Service Routine P1.3
; Input:        nothing
; Returns:      nothing
; Destroys:     R14
;------------------------------------------
P13_ISR:
    xor.w #1,R14                   ;toggle R14
    bic.b #BIT3,&P1IFG             ;clear P1IFG
    reti

    .end

Leave a Reply

Your email address will not be published.

This site is protected by reCAPTCHA and the Google Privacy Policy and Terms of Service apply.

This site uses Akismet to reduce spam. Learn how your comment data is processed.