写: | Jon Wackley (VE3JTN) |
.include "2313def.inc"
;**********************************************
;* Equates *
;**********************************************
.equ clock = 10000000 ;10MHZ clock frequency
.equ STACKTOP = RAMEND - 100
;**********************************************
;* The following delay constants are based on *
;* an 10MHZ clock (CLK) *
;* Times are not exact. *
;**********************************************
.equ d15ms = $6e ;15ms CLK/1024
.equ d4x1ms = $d8 ;4.1ms CLK/1024
.equ d1ms = $64 ;1ms CLK/64
.equ d500us = $b2 ;500us CLK/64
.equ d100us = $f1 ;100us CLK/64
.equ d40us = $fa ;40us CLK/64
.equ TSTOP =0 ;Stop Timer/Counter
.equ TCK1 =1 ;Timer/Counter runs from CK
.equ TCK8 =2 ;Timer/Counter runs from CK / 8
.equ TCK64 =3 ;Timer/Counter runs from CK / 64
.equ TCK256 =4 ;Timer/Counter runs from CK / 256
.equ TCK1024 =5 ;Timer/Counter runs from CK / 1024
.equ TEXF =6 ;Timer/Counter runs from external falling edge
.equ TEXR =7 ;Timer/Counter runs from external rising edge
.equ LCDE =5 ;PORTB bit used for the LCD E signal
.equ LCDDat =6 ;PORTB bit used for the LCD serial data
.equ LCDClk =7 ;PORTB bit used for the LCD serial data clock
;**********************************************
;* Registers used *
;**********************************************
.def SaveSREG = r15 ;used in Delay
.def AReg = r16 ;working reg, like the 68HC11 A register
.def BReg = r17 ;working reg, like the 68HC11 B register
.def ScratchL = r18
.def ScratchH = r19
.def DelayVal = r20
;**********************************************
;* 100 bytes of data RAM are reserved by *
;* the program. Only 1 byte used. *
;**********************************************
.dseg
.org RAMEND - 99
ClkDiv: .byte 1
.cseg
.org $000 ;Reset Vector
rjmp Reset
;Interrupt vectors
.org INT0addr ;External Interrupt0 Vector
reti
.org INT1addr ;External Interrupt1 Vector
reti
.org ICP1addr ;Input Capture1 Interrupt Vector
reti
.org OC1addr ;Output Compare1 Interrupt Vector Address
reti
.org OVF1addr ;Overflow1 Interrupt Vector
reti
.org OVF0addr ;Overflow0 Interrupt Vector
rjmp Tim0int
.org URXCaddr ;UART Receive Complete Interrupt Vector
reti
.org UDREaddr ;UART Data Register Empty Interrupt Vector
reti
.org UTXCaddr ;UART Transmit Complete Interrupt Vector
reti
.org ACIaddr ;Analog Comparator Interrupt Vector
reti
Reset:
ldi AReg,low(STACKTOP)
out SPL,AReg ;set low byte for stack pointer
rcall Setup ;set up timer, LCD port bits and LCD
RPLoop:
ldi AReg,'H' ;send "Hello World" to the LCD
rcall LCDChr
ldi DelayVal,d1ms ;wait 1ms after each character is sent
rcall Delay
ldi AReg,'e'
rcall LCDChr
ldi DelayVal,d1ms
rcall Delay
ldi AReg,'l'
rcall LCDChr
ldi DelayVal,d1ms
rcall Delay
ldi AReg,'l'
rcall LCDChr
ldi DelayVal,d1ms
rcall Delay
ldi AReg,'o'
rcall LCDChr
ldi DelayVal,d1ms
rcall Delay
ldi AReg,' '
rcall LCDChr
ldi DelayVal,d1ms
rcall Delay
ldi AReg,'W'
rcall LCDChr
ldi DelayVal,d1ms
rcall Delay
ldi AReg,'o'
rcall LCDChr
ldi DelayVal,d1ms
rcall Delay
ldi AReg,'r'
rcall LCDChr
ldi DelayVal,d1ms
rcall Delay
ldi AReg,'l'
rcall LCDChr
ldi DelayVal,d1ms
rcall Delay
ldi AReg,'d'
rcall LCDChr
ldi DelayVal,d1ms
rcall Delay
rtr:
rjmp rtr
rjmp RPLoop ;wait here until something interesting happens
;**********************************************
;* Setup *
;* Initialize the timer, LCD port and LCD *
;**********************************************
Setup:
;** Timer setup **
ldi AReg,TCK64
sts ClkDiv,AReg
ldi AReg,TSTOP ;Timer 0 off (just in case)
out TCCR0,AReg ;Stop timer
ldi AReg,0b00000010 ;Enable Timer 0 interrupt
out TIMSK,AReg
sei ;enable interrupts
;** LCD port setup and HD44780 LCD setup **
sbi DDRB,LCDE ;DDRB bit 5 = 1 = output
sbi DDRB,LCDDat ;DDRB bit 6 = 1 = output
sbi DDRB,LCDClk ;DDRB bit 7 = 1 = output
cbi PORTB,LCDE ;set E low
cbi PORTB,LCDDat ;set Data bit low
cbi PORTB,LCDClk ;set Clk low
ldi BReg,TCK1024 ;switch to a 1024 clock divisor
sts ClkDiv,BReg
ldi DelayVal,d15ms ;15ms delay
rcall Delay
ldi AReg,$30
rcall LCDCmd
ldi DelayVal,d4x1ms ;4.1ms countdown
rcall Delay
ldi AReg,$30
rcall LCDCmd
ldi BReg,TCK64 ;switch to a 64 clock divisor
sts ClkDiv,BReg
ldi DelayVal,d100us
rcall Delay
ldi AReg,$30
rcall LCDCmd
ldi BReg,TCK1024 ;switch to a 1024 clock divisor
sts ClkDiv,BReg
ldi DelayVal,d4x1ms
rcall Delay
ldi AReg,$38 ;RS DB7 DB6 DB5 DB4 DB3 DB2 DB1 DB0
rcall LCDCmd ;0 0 0 1 1 1 0 x x
;8-bit operation, 1/16 duty cycle
;5x8 dot matrix
ldi BReg,TCK64 ;switch to a 64 clock divisor
sts ClkDiv,BReg
ldi DelayVal,d40us
rcall Delay
ldi AReg,$08 ;RS DB7 DB6 DB5 DB4 DB3 DB2 DB1 DB0
rcall LCDCmd ;0 0 0 0 0 1 0 0 0
;Display off, cursor off, blink off
ldi DelayVal,d40us
rcall Delay
ldi AReg,$01 ;RS DB7 DB6 DB5 DB4 DB3 DB2 DB1 DB0
rcall LCDcmd ;0 0 0 0 0 0 0 0 1
;Clear screen, cursor home
ldi DelayVal,d1ms
rcall Delay
rcall Delay
ldi AReg,$06 ;RS DB7 DB6 DB5 DB4 DB3 DB2 DB1 DB0
rcall LCDCmd ;0 0 0 0 0 0 1 1 0
;Increment cursor to the right when writing, don't shift screen
ldi DelayVal,d40us
rcall Delay
ldi AReg,$0c ;RS DB7 DB6 DB5 DB4 DB3 DB2 DB1 DB0
rcall LCDCmd ;0 0 0 0 0 0 1 1 0
;Display on, cursor off, blink off
ldi DelayVal,d40us
rcall Delay
ret
;**********************************************
;* Write byte to LCD bus *
;**********************************************
;**********************************************
;* PutByte clock byte into 74hc164. *
;* Data is in AReg *
;* BReg is used as acounter *
;**********************************************
PutByte:
ldi BReg,8 ;bit counter
ShiftB:
cbi PORTB,LCDDat ;set LCD Data bit to 0
lsl AReg ;shift bits in AReg into carry
brcc CLKBit ;if zero, clock it out
sbi PORTB,LCDDat ;if 1, set LCD Data bit to 1
CLKBit:
sbi PORTB,LCDClk ;bit clocks on rising edge
cbi PORTB,LCDClk ;bring clock back to 0
NextB:
dec BReg ;shift out 8 bits
brne ShiftB
ret
;**********************************************
;* LCDCmd - Send a command to the LCD *
;* data in AReg *
;**********************************************
LCDCmd:
rcall PutByte
cbi PORTB,LCDDat ;set RS low
sbi PORTB,LCDE ;set E High
cbi PORTB,LCDE ;set E low
ret
;**********************************************
;* LCDChr - Display a character on the LCD *
;* data in AReg *
;**********************************************
LCDChr:
rcall PutByte
sbi PORTB,LCDDat ;set RS High
sbi PORTB,LCDE ;set E High
cbi PORTB,LCDE ;set E low
ret
;**********************************************
;* Misc timing routines *
;**********************************************
;**********************************************
;* Timer0 overflow interrupt handler *
;**********************************************
Tim0int:
cli ;disable interrupts
set ;Set T flag
ldi ScratchH,TSTOP ;Stop Timer 0
out TCCR0,ScratchH
sei ;re-enable interrupts
reti
;**********************************************
;* Delay time in us based on CLK value *
;* DelayVal holds the delay value. *
;* ClkDiv has the prescaler value *
;**********************************************
Delay:
in SaveSREG,SREG ;Save status register
out TCNT0,DelayVal
clt ;Clear T
lds ScratchH,ClkDiv
out TCCR0,ScratchH ;Load prescaler and run timer
Dwait:
brtc Dwait ;Wait for timer 0 interrupt to set T
out SREG,SaveSREG
ret
;**********************************************
;* Code ends here. *
;**********************************************
文章评论(0条评论)
登录后参与讨论