Ü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
Bild & Video
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
.endFILE: 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

