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. Required fields are marked *

Time limit is exhausted. Please reload CAPTCHA.