;RETURN TO THE MORSE CODE ALARM CLOCK PAGE.
;Copy and paste into your assemble.
;Copyright 2004 Richard Cappels, projects@cappels.org
;Program Name: Send Morse
;Version morclk041204A Corrected reversed code for the letter "D".
;Mores code message for alarm clock
;Pin 20 + 5V.
;Pin 15 High Z speaker return. Anti-phase of signal on pin 14
;Pin 14 High Z speaker output. Tone with message.
;Pin 13 Normally high, goes low during message.
;Pin 12 Normally low, goes high during message.
;Pin 10 Ground.
;Pin 6 - Message starts on negative edge on this pin.
;Pins 4 and 5 - crystal oscialltor per datasheet.
;Pin 1 may be grounded to terminate message.
;Key subroutines:
; dottime - set of delay loops to set basic dot time. Interacts with
interupt routine.
;The dot time is set by adjusting the value loaded into temp at the
start of the routine.
;Loading 100 into temp gives 1 wpm. Loading 1 into temp gives 100 wmp.
Loadign 20 gets 5 wpm.
;sendromstring -send a string from Flash ROM. See TypeGreeting for
example of use.
;sendSerialMorse - sends ASCII Data via serial port and as Morse Code.
; ldi temp,'A'
; rcall sendSerialMorse
;sendnumberMorseASCII -Sends binary nummber in temp as a 3 digit number
via serial port and as Morse Code.
; ldi temp,123
;Send the nummber, 123
; rcall sendnumberMorseASCII
;interword - Delays one inter-word delay period
; rcall interword
.include "2313def.inc" ;Include
file in same directory as project.
;03e7
;Interrupt timer parameters
.equ intcountlow
=$E7 ;Low byte of number of clocks between
interrupts.
.equ intcounthigh
=$03 ;High byte of number of clocks between
interrupts.
;UART baud rate calculation
.equ clock = 4000000 ;clock
frequency
.equ baudrate = 9600
;choose a baudrate
.equ baudconstant = (clock/(16*baudrate))-1
.def delaycount =
r2 ;Counter for delay generation
.def dotlength =
r3 ;Number of 1/100 seconds for dot time.
.def temp =
r16 ;General purpose scratch register.
.def temp2 =
r17 ;General purpose scratch register.
.def h =
r22 ;Binary to decimal conversion.
.def t =
r23 ;Binary to decmial conversion.
.def u =
r24 ;Binary to decimal conversion.
.def flagreg =
r25 ;Flags.
;definiton of flagreg bit assignments
;0 Status of code out bit last sent (memory used to
toggle)
;1 True enables toggling of code output
;2
;3
;4
;5
;6
;7
.equ codeport = PORTB
.equ codeout =
DDRB
.equ codebit = 2
.equ pulsebit = 3
;definition of I/O
;B0 + comparitor input (Reserved)
;B1 - comparitor input (Reserved)
;B2 Tone (code) output
;B3 Anti-phase of signal on B2.
;B4 (not assigned - configure as INPUT with weak
pullup)
;B5 (not assigned - configure as INPUT with weak
pullup)
;B6 (not assigned - configure as INPUT with weak
pullup)
;B7 (not assigned - configure as INPUT with weak
pullup)
;D0 Reserved FOR UART RECEIVE
;D1 Reserved FOR UART TRANSMIT -input has weak pullup.
;D2 (not assigned - configure as INPUT with weak
pullup)
;D3 (not assigned - configure as INPUT with weak
pullup)
;D4 (not assigned - configure as INPUT with weak
pullup)
;D5 (not assigned - configure as INPUT with weak
pullup)
;D6 (not assigned - configure as INPUT with weak
pullup)
;D7 (not assigned - configure as INPUT with weak
pullup)
.cseg
.ORG $0000
;Initializaton code
rjmp start
.ORG $0001
rjmp int0service
.ORG $0004
rjmp
timerservice ;Timer/counter compare interrupt handler
start:
ldi r16,RAMEND
;Initialize Stack Pointer.
out spl,r16
;Set PORTD.
ldi
temp,0b00000000
out DDRD,temp
ldi temp,0b10111111
out PORTD,temp
;Set PORTB.
ldi
temp,0b00001111
out DDRB,temp
ldi temp,0b11110010
out PORTB,temp
ldi temp,$40
out GIMSK,temp
sei
ldi temp,$38
out MCUCR,temp
sleep
waithere:
rjmp start
;Added so it would repeat if interrupt repeated.
int0service: ;Alarm has gone off, so wake up
clr temp
out GIMSK,temp
out MCUCR,temp
clr flagreg
;Clear flagreg (flag register).
;TIMER 1 SETUP.
ldi temp,$09
;Set timer 1 to reset 0000 after compare match.
Prescaler = 1X.
out TCCR1B,temp
ldi
temp,intcounthigh ;Set compare register to establish
interrupt frequency.
out OCR1AH,temp
ldi temp,intcountlow
out OCR1AL,temp
ldi temp,$40
;Enable interrupt on compare match.
out TIMSK,temp
sbi PORTB,0
cbi PORTB,1
sei
;Enable interrupts.
ldi temp,20
;Set for 10 words per minute
mov dotlength,temp
rcall
TypeMessage ;Send message
three times
rjmp start
;added so it would repeat message
each time interrupted.
rcall
TypeMessage ;Send message
three times
rcall
TypeMessage ;Send message
three times
rcall
TypeMessage ;Send message
three times
rcall
TypeMessage ;Send message
three times
rcall
TypeMessage ;Send message
three times
rcall
TypeMessage ;Send message
three times
rcall
TypeMessage ;Send message
three times
rcall
TypeMessage ;Send message
three times
rcall
TypeMessage ;Send message
three times
rcall
TypeMessage ;Send message
three times
rcall
TypeMessage ;Send message
three times
rcall
TypeMessage ;Send message
three times
rcall
TypeMessage ;Send message
three times
rcall
TypeMessage ;Send message
three times
rcall
TypeMessage ;Send message
three times
rcall
TypeMessage ;Send message
three times
rcall
TypeMessage ;Send message
three times
rcall
TypeMessage ;Send message
three times
rcall
TypeMessage ;Send message
three times
rjmp start
;Go back to sleep
TypeMessage:
;Type greeting
push ZL
push ZH
ldi
ZH,high(2*Message) ;Load high part of byte address
into ZH
ldi
ZL,low(2*Message) ;Load low part of byte address into
ZL
rcall
sendromstring ;Send it
pop ZH
pop ZL
ret
Message:
.db "WAKE UP " "
.db $0A,$0D
.db $00,$00
sendromstring:
;call with location of string in Z.
push ZL
;Save Z on stack.
push ZH
srs1:
lpm
;Load byte from program memory
into r0.
tst
r0 ;Check if we've reached the end
of the message.
breq
finishsendstering;If so, return.
mov
temp,r0
rcall sendSerialMorse ;Send via
serial link and as Morse Code.
adiw
ZL,1 ;Increment Z registers
rjmp srs1
finishsendstering:
pop ZH
;Pop Z from stack.
pop ZL
rcall interword
ret
sendcodedcode: ;Send Coded Morse Code
;Shift out morse code from coded
character.
;Enter with code for character in
temp.
;Description of data format from David Robinson's web page:
;"At this point I was reminded of the N1KDO NHRC-2 repeater controller
published
;in February 97 QST that had Morse ID. Investigation of the assembler
listing (1)
;revealed a simple conversion scheme, where all morse characters are
encoded in a
;single Byte, bitwise, LSB to MSB.; ì0î = dit,
ì1î = dah. The Byte is shifted out
;to the right, until only a ì1î remains. As an example 3
is encoded as binary 00111000,
;which translates to 38 in hexadecimal. "
morecode:
cpi temp,0b00000001
breq codedcodesent
clc
ror temp
brcs senddash
;Send a dash if lsb was a one
rcall dot
;Send a dot if lsb was not a one
rjmp morecode
senddash:
rcall dash
rjmp morecode
codedcodesent:
;Finished sending the coded code.
ret
SendMorseAscii: ;Look up coded Morse code and send,
followed by rcall to interchar.
;Enter with ASCII character in
temp. Upper-case, don't process
;control characters.
push ZL
push ZH
cpi temp,$20
;If space character, do interword delay.
brne SMA1
rcall interword
rjmp lookupdone
SMA1:
cpi temp,$5B
brmi upperacse
andi temp,$5F
;Make upper-case
upperacse:
cpi temp,$2A
brmi lookupdone
;Set up pointer into codechart.
ldi
ZH,high(2*codechart) ;Load high part of byte address
into ZH.
ldi
ZL,low(2*codechart) ;Load low part of byte address
into ZL.
subi temp,$2A
;Removed offset from ASCII value in temp.
add ZL,temp
;Add the value to the index.
clr temp
adc ZH,temp
lpm
;Fetch the value from the table.
mov temp,r0
rcall
sendcodedcode ;Send as Morse Code
rcall interchar
;Dealy one interchar time
lookupdone:
pop ZH
pop ZL
ret
;Return
dot: ;Send dot, wait one dot time.
sbr
flagreg,0b00000010 ;Set flag to send tone.
rcall dottime
cbr
flagreg,0b00000010 ;Clear flag to send tone.
rcall dottime
ret
dash: ;Send dash, wait one dot
time.
sbr
flagreg,0b00000010 ;Set flag to send tone.
rcall dottime
rcall dottime
rcall dottime
cbr
flagreg,0b00000010 ;Clear flag to send tone.
rcall dottime
ret
interchar: ;Wait interchear period with output off -3
dot times
rcall dottime
rcall dottime
rcall dottime
ret
interword: ;Wait interword period with output off-6
dot times
rcall dottime
rcall dottime
rcall dottime
rcall dottime
rcall dottime
rcall dottime
rcall dottime
ret
dottime: ;Delay
one dot time.
;reload values for 100 wmp with 4 MHz Crystal:
;temp = 1
;temp2 = 20
;dealycount = 0 (cleared)
;With these interrupt reload values:
;.equ intcountlow =$E7
;.equ intcounthigh =$03
;Using dotlength = 20 (decmimal), dot time is 83.37 milliseconds.
;Using dotlength = 200 (decimal), dot time is 833.64 milliseconds
push temp
push temp2
mov temp,dotlength
;<= vary this from 1 to 100 to get 100 to 1 wpm.
20 = 5 wpm; 100 = 1
moretime3:
clr delaycount
moretime2:
ldi temp2,20
moretime1:
dec temp2
brne moretime1
dec delaycount
brne moretime2
dec temp
brne moretime3
pop temp2
pop temp
ret
;go back
sendSerialMorse: ;Send ASCII Character via serial
port and via Morse Code.
;Enter with
char in temp.
push temp
pop temp
rcall SendMorseAscii
ret
codechart: ;Coded Morse Code look up table. Use ASCII
value -$30, so zero = 0, "A" = $11, etc.
;Note: Some ASCII characters are silent, and are coded as 0b00000001
;Also note: BT (pause) is coded for ASCII "<" and SK (end of
contanct) is coded for ASCII "*",
;and End of Message is coded for ASCII "+".
; * (SK) + (End
of Message)
.db 0b01101000, 0b00101010
; ,(comma)
-
. /
.db 0b01110011,0b1011110,0b01111010,0b00101001
;
0
1
2 3
.db 0b00111111,0b00111110,0b00111100,0b00111000
;
4
5
6 7
.db 0b00110000,0b00100000,0b00100001,0b00100011
;
8
9
: ;
.db 0b00100111,0b00101111,0b01000111,0b01010101
; <
(BT)
=
> ?
.db 0b000110001,0b00000001,0b00000001,0b01001100
;
@
A
B C
.db 0b00000001,0b00000110,0b00010001,0b00010101
;
D
E
F G
.db 0b00001001,0b00000010,0b00010100,0b00001011
;
H
I
J K
.db 0b00010000,0b00000100,0b00011110,0b00001101
;
L
M
N 0
.db 0b00010010,0b00000111,0b00000101,0b00001111
;
P
Q
R S
.db 0b00010110,0b00011011,0b00001010,0b0001000
;
T
U
V W
.db 0b00000011,0b00001100,0b00011000,0b00001110
;
X
Y
Z [
.db 0b00011001,0b00011101,0b00010011,0b00000001
timerservice: ;Service Timer 1
push temp
in temp,sreg
push temp
sbrs flagreg,1
rjmp notoggle
;Toggle tone output
sbi
codeout,codebit ;Enable code
output pin.
mov temp,flagreg
;Toggle it, using flagreg 0 as memory of last one.
andi temp,0b00000001
inc temp
andi temp,0b00000001
brne codehigh
cbi codeport,codebit
sbi codeport,pulsebit
andi flagreg,0b11111110
rjmp toggledone
codehigh:
sbi codeport,codebit
cbi codeport,pulsebit
ori flagreg,0b00000001
toggledone:
pop temp
out sreg,temp
pop temp
reti
;Return from interrupt.
notoggle: ;Don't toggle port, but delay to equalize
interrupt time toggling and not toggling.
cbi
codeout,codebit ;Disable code out
pin.
nop
nop
nop
nop
nop
nop
rjmp toggledone
.exit
Liability Disclaimer and intellectual property notice
(Summary: No warranties, use these pages at your own risk. You may use
the information provided here for personal and educational purposes but
you may not republish or use this information for any commercial
purpose without explicit
permission.) I neither express nor imply any warranty for the quality,
fitness
for any particular purpose or use,or freedom from patents or other
restrictions
on the rights of use of any software, firmware, hardware, design,
service,information,
or advice provided, mentioned,or made reference to in these pages. By
utilizing
or relying on software, firmware, hardware, design,
service,information,
or advice provided, mentioned, or made reference to in these pages, the
user
takes responsibility to assume all risk and associated with said
activity
and hold Richard Cappels harmless in the event of any loss or expense
associated
with said activity. The contents of this web site, unless otherwise
noted,
is copyrighted by Richard Cappels. Use of information presented on this
site
for personal, nonprofit educational and noncommercial use is
encouraged,
but unless explicitly stated with respect to particular material, the
material
itself may not be republished or used directly for commercial purposes.
For
the purposes of this notice, copying binary data resulting from program
files,
including assembly source code and object (hex) files into
semiconductor
memories for personal, nonprofit educational or other noncommercial use
is
not considered republishing. Entities desiring to use any material
published
in this pages for commercial purposes should contact the respective
copyright
holder(s).
;RETURN TO THE MORSE CODE ALARM CLOCK PAGE.