;USER YOUR BROWSER'S BACK BUTTON TO GO BACK.
;Copy this text directly into your assembler editor.
;The code was writtent with AVR Studio 3.5.x
;Copyright 2003 Richard Cappels, projects(at)cappels.org,
; http://www.projects.cappels.org
;*********************************
;2313 waveform capture control and LED display firmware
;*********************************
.include "2313def.inc"
;This program is meant to simulate an ASCII serial terminal for the purpose of displaying
;control panel information from the Waveform Capture controller on a 4 digit LED display
;and accepting input from a set of user input buttons on the cotnrol panel.
;I/O is connected as follows:
;LED display is a 4 character common cathode display.
;LED display segment definition is below:
; AAAAAA
; F B
; F B
; GGGGGG
; E C
; E C
; DDDDDD DP
;ledlut: ;LED Look-Up Table, Segent codes for 0..9 on 7 segment display
; 0 1 2 3 4 5 6 7 8 9 blank minus
;.db $3F,$06,$5B,$4F,$66,$6D,$7d,$07,$7F, $6F, $00, $40
;The look-up table above is only used as a reference.
;PB0 through 1 K resistor to LED segment A
;PB1 through 1 K resistor to LED segment B
;PB2 through 1 K resistor to LED segment C
;PB3 through 1 K resistor to LED segment D
;PB4 through 1 K resistor to LED segment E
;PB5 through 1 K resistor to LED segment F
;PB6 through 1 K resistor to LED segment G
;PB7 through 1 K resistor to LED decimal point (though not used in this firmware)
;PD5 connects to cathode 1 (left-most digit)
;PD4 connects to cathode 2
;PD3 connects to cathdoe 3
;PD2 connects to cathdoe 4 (right-most digit)
;Push button connections are as follows:
;Six bottons are connected from PB0 thorought PB5. The remaining terminal of each
;button is connected to a common conductor that is connected to ground through
;a 1K resistor.
;PD6 is not used.
;UART baud rate calculation
.equ clock = 4000000 ;clock frequency
.equ baudrate = 9600 ;choose a baudrate
.equ baudconstant = (clock/(16*baudrate))-1
;Assign LED Connections
.equ segmentA = 0 ;Port B
.equ segmentB = 1 ;Port B
.equ segmentC = 2 ;Port B
.equ segmentD = 3 ;Port B
.equ segmentE = 4 ;Port B
.equ segmentF = 5 ;Port B
.equ segmentG = 6 ;Port B
.equ decimalpoint = 7;Port B
.equ cathode1 = 5 ;Port D
.equ cathode2 = 4 ;Port D
.equ cathode3 = 3 ;Port D
.equ cathode4 = 2 ;Port D
;Assign working registers
.def temp = r16 ;general purpose variable
.def char1 = r17 ;bit pattern for left-most LED character
.def char2 = r18 ;bit pattern for LED char 2
.def char3 = r19 ;bit pattern for LED char 3
.def char4 = r20 ;bit pattern for right-most LED character
.def buttonimage = r21 ;captured button bit pattern
.def scratch = r22 ;second general purpose variable
.def interruptcount = r23 ;round robin multitask counter
;Assignment of flag bits in waveform capture chip and sent after adding the value $50 to it.
;bit 0 if set, indicates that display is to be erased before being rewritten
;bit 1 if set, allows sampling of analog signal
;bit 2 if set, selects for triggering on positive edge of trigger signal
;bit 3 if set, selects for free run (non-triggered operation)
;bit 4
;bit 5
;bit 6
;bit 7
.org $000
rjmp init ;Reset handler.
.org $006
rjmp timerservice ;Timer interrupt handler.
init:
ldi temp,low(ramend)
out spl,temp ;Set lowe byte of stack pointer (there is no high byte)..
ldi temp,$FF ;Make all I/O poins outputs
out ddrd,temp
out ddrb,temp
ldi temp,baudconstant
out ubrr,temp ;Load baudrate.
sbi ucr,rxen ;Enable WAUT receive (also sets PD0 to input)
sbi ucr,txen ;Enable UART Transmit
ldi temp, $03 ;Use temp to initaize timer prescaler..
out TCCR0, temp
ldi temp,$00 ;Use temp to initialize counter.
out TCNT0,temp
ldi temp, $02 ;Use temp to initialize TIMSK.
out TIMSK,temp
clr interruptcount
sei ;ENABLE THE TIMER INTERRUPTS HERE
ldi char1,$FF
ldi char2,$FF
ldi char3,$40 ;Char 3 is always a minus sign
ldi char4,$FF
loop: ;Main loop checks UART for incoming character and updates display accordingly
;Get char from UART into temp
sbis usr,rxc ;Skip if no char in UART
rjmp nc1
in temp,udr ;Read byte
;Interpret byte
cpi temp,$30 ;Compare incoming byte with timebase codes and
brne n30 ;write the pattern that makes the right display.
rjmp code30
n30:
cpi temp,$31
brne n31
rjmp code31
n31:
cpi temp,$32
brne n32
rjmp code32
n32:
cpi temp,$33
brne n33
rjmp code33
n33:
cpi temp,$34
brne n34
rjmp code34
n34:
cpi temp,$35
brne n35
rjmp code35
n35:
cpi temp,$36
brne n36
rjmp code36
n36:
cpi temp,$37
brne n37
rjmp code37
n37:
cpi temp,$38
brne n38
rjmp code38
n38:
cpi temp,$39
brne n39
rjmp code39
n39:
cpi temp,$3A
brne n3A
rjmp code3A
n3A:
cpi temp,$3B
brne n3B
rjmp code3B
n3B:
cpi temp,$3C
brne n3C
rjmp code3C
n3C:
nc1:
rjmp loop ;Do forever
; These are short routines to write the necessary bit patterns to the LED timebase display.
code30: ;1us
ldi char1,$00
ldi char2,$06
ldi char4,$7D
rjmp loop
code31: ;2us
ldi char1,$00
ldi char2,$5B
ldi char4,$7D
rjmp loop
code32: ;5us
ldi char1,$00
ldi char2,$6D
ldi char4,$7D
rjmp loop
code33: ;10us
ldi char1,$06
ldi char2,$3F
ldi char4,$7D
rjmp loop
code34: ;20us
ldi char1,$5B
ldi char2,$3F
ldi char4,$7D
rjmp loop
code35: ;50us
ldi char1,$6D
ldi char2,$3F
ldi char4,$7D
rjmp loop
code36: ;100us
ldi char1,$00
ldi char2,$06
ldi char4,$66
rjmp loop
code37: ;200us
ldi char1,$00
ldi char2,$5B
ldi char4,$66
rjmp loop
code38: ;500us
ldi char1,$00
ldi char2,$6D
ldi char4,$66
rjmp loop
code39: ;1ms
ldi char1,$00
ldi char2,$06
ldi char4,$4F
rjmp loop
code3A: ;2ms
ldi char1,$00
ldi char2,$5B
ldi char4,$4F
rjmp loop
code3B: ;5ms
ldi char1,$00
ldi char2,$6D
ldi char4,$4F
rjmp loop
code3C: ;10ms
ldi char1,$06
ldi char2,$3F
ldi char4,$4F
rjmp loop
buttest: ;Used by interrupt service routine
sca1:
rcall buttoncap ;Return if no buttons down
cpi buttonimage,$FF
brne buttonisdown
ret
buttonisdown:
mov scratch,buttonimage
sd1: rcall buttoncap
cpi buttonimage,$FF
brne sd1
cpi scratch,$EF
brne notef
ldi temp,$41
rjmp sendit
notef:
cpi scratch,$DF
brne notdf
ldi temp,$46
rjmp sendit
notdf:
cpi scratch,$F7
brne notf7
ldi temp,$44
rjmp sendit
notf7:
cpi scratch,$FB
brne notfb
ldi temp,$49
rjmp sendit
notfb:
cpi scratch,$FE
brne notfe
ldi temp,$45
rjmp sendit
notfe:
cpi scratch,$FD
brne notfd
ldi temp,$43
rjmp sendit
notfd:
ret
sendit: rcall emitchar
ret
buttoncap: ;Capture status of buttons into buttonimage.
;Leave Port D and B as inputs
ldi temp,$00
out DDRD,temp ;Make PORT D inputs.
out DDRB,temp ;Make PORT B inputs.
ldi temp,$FF
out PORTB,temp ;Turn on pullups on port B.
ldi temp,$00 ;Wait for lines to settle.
dl1: dec temp
brne dl1
in buttonimage,PINB ;Capture button state.
ldi temp,$00
out PORTB,temp ;Write $00 to port B. (leave Port D as inputs)
ret
emitchar: ;Send character from temp via UART
sbis usr,udre ;wait until the register is cleared
rjmp emitchar
out udr,temp ;send the byte
ret
receivechar: ;Get char from UART into temp
sbis usr,rxc ;Check for byte in UART from terminal
rjmp receivechar
in temp,udr ;Read byte
ret
timerservice: ;service timer interrupt
;round-robin multitasking, different task on each interrupt.
;Here are the tasks:
;display digit1
;display digit2
;display digit3
;display digit4
;check buttons
push temp
lds temp,$5F ;Push status register onto stack.
push temp
inc interruptcount ;Point to the next task.
cpi interruptcount,$05 ;Only 5 tasks allowed, the wrap around to first.
brne cne1
ldi interruptcount,$00
cne1:
ldi temp,$00 ;Turn off display
out ddrd,temp
; Round-robin starts here
cpi interruptcount,$00
breq showchar1
cpi interruptcount,$01
breq showchar2
cpi interruptcount,$02
breq showchar3
cpi interruptcount,$03
breq showchar4
cpi interruptcount,$04
breq checkbuttons
rjmp endoftimerservice ;This jump should not execute if things are going well.
showchar1:
out portb,char1
ldi temp,$00
out portd,temp
sbi ddrd,5
ldi temp,$FF
out ddrb,temp
rjmp endoftimerservice
showchar2:
out portb,char2
ldi temp,$00
out portd,temp
sbi ddrd,4
ldi temp,$FF
out ddrb,temp
rjmp endoftimerservice
showchar3:
out portb,char3
ldi temp,$00
out portd,temp
sbi ddrd,3
ldi temp,$FF
out ddrb,temp
rjmp endoftimerservice
showchar4:
out portb,char4
ldi temp,$00
out portd,temp
sbi ddrd,2
ldi temp,$FF
out ddrb,temp
rjmp endoftimerservice
checkbuttons:
in temp,udr ;Read byte in UART to clear char from buffer
rcall buttest
rjmp endoftimerservice
endoftimerservice:
pop temp
sts $5F,temp ;restore status register
pop temp
reti
;
;This is example code and is neither warranted
to be useful for any particular purpose, nor to be safe to any degree.
;See http://www.projects.cappels.org for intellectual property and non-liability
statement.
;
; /////END OF DOCUMENT\\\\\\