📄 fet440_lcd_05.s43
字号:
;******************************************************************************
; MSP-FET430P440 Demo - LCD, Display Real-Time Clock on a Static LCD
;
; Description: This program maintains a real-time clock and
; displays the current time on a 3.5 digit static LCD. The colon between
; the minutes and seconds toggles on or off each second to indicate that
; the clock is running. The digits of the display are only rewritten
; each minute once the elapsed seconds roll over from 60 back to 0.
; The fourth digit is automatically blank for hours 1-9. The software
; is totally interrupt driven. It only comes out of low power mode 3
; and executes code when a Basic Timer interrupt occurs, once each
; second.
; ACLK = LFXT1 = 32768Hz, MCLK = SMCLK = default DCO = 32 x ACLK = 1048576Hz
; //* An external watch crystal between XIN & XOUT is required for ACLK *//
;
;
; Connections MSP430 -> LCD
; -------------------------
;
; T.I. Varitronix
; MSP430x4xx MCU 3.5 digit, static LCD
; # VI-302-DP-S
; --------------- --------------
; | COM0 |-----|1,40 COM |
; | SEG0 |-----|21 |
; | SEG1 |-----|20 |
; | SEG2 |-----|19 |
; | SEG3 |-----|18 |
; | SEG4 |-----|17 |
; | SEG5 |-----|22 |
; | SEG6 |-----|23 |
; | SEG7 |-----|38 (low batt) |
; | SEG8 |-----|25 |
; | SEG9 |-----|24 |
; | SEG10|-----|15 |
; | SEG11|-----|14 |
; | SEG12|-----|13 |
; | SEG13|-----|26 |
; | SEG14|-----|27 |
; | SEG15|-----|28 (L) COLON |
; | SEG16|-----|30 |
; | SEG17|-----|29 |
; | SEG18|-----|11 |
; | SEG19|-----|10 |
; ---|R03 SEG20|-----|9 |
; | | SEG21|-----|31 |
; | | SEG22|-----|32 |
; \|/ | SEG23|-----|3 (B-C) = |
; GND | | | .5 digit ="1"|
; --------------- --------------
;
; NOTE: Pin R03 on the MSP430 must be connected to GND
;
; G. Morton
; Texas Instruments Inc.
; Feb 2005
; Built with IAR Embedded Workbench Version: 3.21A
;******************************************************************************
#include <msp430x44x.h>
;-----------CPU registers used-------------------------------------------------
;;;;;;; R13, R14, R15 ; Used as temporary registers, can
; be reused
;-----------RAM bytes used for variables---------------------------------------
SEC EQU 0200h ; Byte for counting seconds
MIN EQU 0201h ; Byte for counting minutes
HOUR EQU 0202h ; Byte for counting hours
COLON EQU 0203h ; Temporary storage to flash colon
;--------RAM words used for variables------------------------------------------
LCDTEMP EQU 0204h ; Temporary storage in LCD routine
;------------------------------------------------------------------------------
ORG 0E000h ; Program reset
;------------------------------------------------------------------------------
RESET mov #300h,SP ; Initialize stack pointer
call #Setup ; Setup
Mainloop bis #LPM3,SR ; Set SR bits to wait in LPM3
;------------------------------------------------------------------------------
; Increment clock values every second
;------------------------------------------------------------------------------
Clock setc ; Entry every second
dadc.b SEC ; Increment seconds, add carry bit
cmp.b #060h,SEC ; One minute elapsed?
jlo End_CLK ; No, (C = 0) w/o LCD update
clr.b SEC ; Yes, clear seconds (C = 1)
Clock1 dadc.b MIN ; Increment minutes if set carry
cmp.b #060h,MIN ; Sixty minutes elapsed?
jlo Dis_Clock ; No, jump to update time display
clr.b MIN ; Yes, clear minutes
dadc.b HOUR ; Increment hour
cmp.b #013h,HOUR ; 12 hours elapsed?
jlo Dis_Clock ; No, jump to update time display
mov.b #01h,HOUR ; Yes, set hours back to 1 &
; Fall through to display time
;------------------------------------------------------------------------------
; Display clock values contained in RAM Bytes MIN & HOUR.
; CPU Registers R15 and R13 used temporarily.
;------------------------------------------------------------------------------
Dis_Clock mov.b #LCDM1,R15; ; R15 points to first LCD location
mov.b MIN,R14 ; Minute BCD value to R14
call #Pass_Bytes ; Call routine to display minutes
mov.b HOUR,R14 ; Hour BCD value to R14
call #Pass_Bytes ; Call routine to display hours
End_CLK ret ; Return to Basic Timer ISR
Pass_Bytes mov.b R14,R13 ; Copy R14 to R13 (save R14)
call #ToLCD ; Call to display 1st digit
mov.b R14,R13 ; Copy R14 to R13 (save R14)
rra.b R13 ; Right shift R13 4 times to
rra.b R13 ; move 2nd nibble to lower 4 bits
rra.b R13 ;
rra.b R13 ;
call #ToLCD ; Call to display 2nd digit
ret ; Return to Dis_Clock routine
;------------------------------------------------------------------------------
; Display 1 digit on static LCD. CPU Registers R15, R14 and R13
; used temporarily
;------------------------------------------------------------------------------
ToLCD cmp #09Dh,R15 ; Pointer incremented for 4th
; digit = 1/2 digit position?
jeq Halfdigit ; Yes, jump to test/set leading 1
and #000Fh,R13 ; Blank upper 12 bits
add R13,R13 ; Double R13 since is word data
; where addresses = 2 bytes apart
add R13,R13 ; Double R13 again since 2 words
; per digit in static mode
mov LCD_Tab(R13),LCDTEMP ; Low word into temp memory
mov.b LCDTEMP,0(R15) ; Low byte of low word to LCD
swpb LCDTEMP ; Swap bytes in temp memory
mov.b LCDTEMP,1(R15) ; High byte of low word to LCD
incd R13 ; Double increment to high word of
; digit
mov LCD_Tab(R13),LCDTEMP ; High word into temp memory
mov.b LCDTEMP,2(R15) ; Low byte of high word to LCD
swpb LCDTEMP ; Swap bytes in temp memory
mov.b LCDTEMP,3(R15) ; High byte of high word to LCD
add #4,R15 ; Increase R15 (LCD mem pointer)
; by 4 since 4 bytes per digit
EndLCD ret ; Return to Pass_Bytes routine
;------------------------------------------------------------------------------
; Test if 1 is to be displayed in 1/2 digit position and display it
; If leading zero then nothing is displayed
;------------------------------------------------------------------------------
Halfdigit cmp.b #1,R13 ; Digit to display = 1?
jne EndHalf ; No, jump to not display digit
bis.b #10h,-1(R15) ; Yes, set h bit in 12th byte(0-11)
; = 1/2 digit (leading 1) bit
EndHalf mov.b #LCDM1,R15 ; Set pointer to start of LCD mem
ret ; Return to Pass_Bytes routine
;------------------------------------------------------------------------------
Setup ; Configure modules and control registers
;------------------------------------------------------------------------------
StopWDT mov #WDTPW+WDTHOLD,&WDTCTL ; Stop Watchdog Timer
SetupFLL2 bis.b #XCAP18PF,&FLL_CTL0 ; Set load capacitance for xtal
mov #10000,R15 ;
Xtal_Wait dec R15 ; Delay for 32 kHz crystal to
jnz Xtal_Wait ; stabilize
SetupLCD mov.b #LCDP1+LCDP0+LCDSTATIC+LCDON,&LCDCTL
; Static LCD, segments S0-S23
SetupBT mov.b #BT_ADLY_1000,&BTCTL ; Basic Timer interrupt = 1 second
bis.b #BTFRFQ1+BTFRFQ0,&BTCTL ; Set freqLCD = ACLK/256
mov.b #BTIE,&IE2 ; Enable Basic Timer interrupt
SetupPorts mov.b #0FFh,&P1DIR ; Set port to outputs
SetupPx mov.b #0FFh,&P2DIR ; Set port to outputs
mov.b #0FFh,&P3DIR ; Set port to outputs
mov.b #0FFh,&P4DIR ; Set port to outputs
mov.b #0FFh,&P5DIR ; Set port to outputs
mov.b #0FFh,&P6DIR ; Set port to outputs
ClearRAM bis.b #10h,COLON ; Set bit used to flash colon
mov.b #59h,SEC ; Preload SEC # rolls over
mov.b #59h,MIN ; Preload MIN # to 12:00 @
mov.b #11h,HOUR ; Preload HOUR # 1st second
ClearLCD mov #15,R15 ; 15 LCD memory bytes to clear
Clear1 mov.b #0,LCDM1(R15) ; Write zeros in LCD RAM locations
; to clear display
dec R15 ; All LCD mem clear?
jc Clear1 ; More LCD mem to clear, use JC
; to get memory location 0
eint ; Enable interrupts
ret
;------------------------------------------------------------------------------
; Basic Timer generates 1 second interrupt. Mode bits changed on
; stack so CPU is returned in active upon return from the interrupt
;------------------------------------------------------------------------------
BT_ISR call #Clock ; Update hours and minutes each
; second even if not displayed
xor.b COLON,&LCDM8 ; Blink ":" between min and hour
reti
;------------------------------------------------------------------------------
; Define characters for VI-302 3.5 digit static LCD
;------------------------------------------------------------------------------
a EQU 0001h
b EQU 0010h
c EQU 0100h
d EQU 1000h
e EQU 0001h
f EQU 0010h
g EQU 0100h
h EQU 1000h ; Decimal point or special
; character
EVEN ; Align words on even boundry
LCD_Tab DW a+b+c+d ; Displays '0' low word
DW e+f ; Displays '0' high word
DW b+c ; Displays '1' low word
DW 0 ; Displays '1' high word (empty)
DW a+b+d ; Displays '2' low word
DW e+g ; Displays '2' high word
DW a+b+c+d ; Displays '3' low word
DW g ; Displays '3' high word
DW b+c ; Displays '4' low word
DW f+g ; Displays '4' high word
DW a+c+d ; Displays '5' low word
DW f+g ; Displays '5' high word
DW a+c+d ; Displays '6' low word
DW e+f+g ; Displays '6' high word
DW a+b+c ; Displays '7' low word
DW 0 ; Displays '7' high word (empty)
DW a+b+c+d ; Displays '8' low word
DW e+f+g ; Displays '8' high word
DW a+b+c+d ; Displays '9' low word
DW f+g ; Displays '9' high word
;------------------------------------------------------------------------------
; Interrupt Vectors
;------------------------------------------------------------------------------
ORG 0FFFEh ; RESET Vector
DW RESET
ORG 0FFE0h ; Basic Timer Vector
DW BT_ISR
END
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -