Ü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 .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