;************************************************************************** ; Program name : Morse ; Descriptions : This program is training tool for morse code. ; Date : 10th.August.2000 ; Author : Yoshio Kato (JH1AHY) ;************************************************************************* .include "2313def.inc" .device AT90S2313 .equ end_ele =$80 ;end pattern of morse code .equ upper_alpha =45 ;upper limit of alphanumeric table .equ upper_kana =53 ;upper limit of kana table .equ speed_adrs =$70 ;speed parameter address on EEPROM .equ alpha =$00 ;top address of alphanumeric table .equ kana =$30 ;top address of kana table .eseg ;********** Look up table of morse code on EEPROM .org alpha ;A B C D E F G H I J K L M N O P Q R S T U V W X Y Z .db $60,$88,$a8,$90,$40,$28,$d0,$08,$20,$78,$b0,$48,$e0,$a0,$f0,$68,$d8,$50,$10,$c0,$30,$18,$70,$98,$b8,$c8 .org alpha+26 ;? / . ( ) - = + , 1 2 3 4 5 6 7 8 9 0 .db $32,$94,$56,$b4,$b6,$86,$8c,$54,$ce,$7c,$3c,$1c,$0c,$04,$84,$c4,$e4,$f4,$fc,$00,$00,$00 .org kana .db $dc,$60,$30,$bc,$44,$48,$a4,$18,$b8,$f8,$ac,$d4,$ec,$74,$e8,$a0,$28,$68,$5c,$24,$50,$a8,$08,$d8,$38,$88,$cc .org kana+27 .db $c8,$c8,$40,$90,$98,$2c,$c0,$8c,$28,$70,$9c,$e0,$10,$d0,$b4,$f0,$58,$b0,$54,$20,$34,$6c,$52,$56,$b6,$4a,$00 .org speed_adrs .db $28,$00 ;intial value of morse speed parameter ;***** Global register variables .def temp =R16 ;temporary storage register .def morse_code =r17 ;morse code from EEPROM .def rand =r18 ;random number .def cnt1 =r19 ;counter in delay routine .def cnt2 =r20 ;counter in delay routine .def ele_len =r21 ;element length .def dot_len =r22 ;dot length .def low_byte =r23 ;speed change counter .def high_byte =r24 ;speed change counter .def sreg_save =r25 ;register save area .def speed_flg =r26 ;slow=0 fast=1 .def offset =r27 ;EEPROM offset .def limit =r28 ;end of lookup table .cseg ;code segment .org 0 ;*********** Define each handler ************************************** ;This program uses Reset,External interrupt and Timer overflow handler ;*********************************************************************** rjmp reset ;reset handler rjmp morse ;external interrupt routine reti ;external interrupt 1 reti ;timer/counter capture event reti ;timer/counter compare match reti ;timer1 overflow rjmp tm_ovf ;timer interrupt routine reti ;uart ,RX complete reti ;UART data register empty reti ;UART TX complete reti ;unused analogue interrupt ;******************************************************************** ; Main routine ;******************************************************************** reset: ldi temp,$d0 ;stack pointer bottom address out SPL,temp ;set stack pointer ldi temp,$ff ;portb all out out DDRB,temp ldi temp,$f1 ;initialize port D PD1,PD2,PD3 in out DDRD,temp ;PD2 extarnal interrupt PD0,PD1,PD2,PD3 in ldi temp,$0e ;port D pull up out portd,temp ;set pullup register ldi offset,alpha ;set offset value as alphanumeric ldi limit,upper_alpha ;set end of alphanumeric table sbis PinD,1 ;fast botton on ? set kana mode rjmp start ;alphanumeric mode ldi offset,kana ;set kana mode ldi limit,upper_kana ;set end of kana table start: ldi temp,$30 ; out MCUCR,temp ;down pulse interrupt on low level cli ;IQR disable clear interrupt flg ldi rand,$00 ldi temp,$00 out GIMSK,temp ;disable ext IRQ ldi temp,$05 ;1/1024 of master clock ;master clock is 10MHz out TCCR0,temp ;set TM0 ldi temp,$f6 ;1/10 out freq=976.6Hz 1ms out TCNT0,temp ; ldi temp,$02 ; out TIMSK,temp ;TM start ldi temp,$40 ;enable external interrupt out GIMSK,temp ; sei ;set interrupt clr low_byte ;clear low_byte clr high_byte ;clear high_byte r_sp: ;********* read speed parameter from EEPROM ************ sbic EECR,EEWE ;if EEWE not clear rjmp r_sp ;wait more ldi temp,speed_adrs ;set speed parameter address out EEAR,temp ;set EEPROM address sbi EECR,EERE ;strobe EEPROM in dot_len,EEDR ;read EEPROM main_loop: ;********* main loop ********************************** ldi temp,$02 ; out TIMSK,temp ;TM start ldi temp,$40 ;enable external interrupt out GIMSK,temp ; sbis PinD,1 ;slow botton on? rjmp slow ;slow botton on jump to slow sbis PinD,3 ;fast botton on? rjmp fast ;fast boton on jump to fast rjmp loop ;normal jump to top loop slow: ldi speed_flg,$00 ;set speed_flg as slow rjmp inc_low ;jump to increment low_byte fast: ldi speed_flg,$01 ;set speed_flg as fast inc_low: inc low_byte ;increment low_byte cpi low_byte,$ff ;is low_byte 255? breq inc_high ;brach to increment high_byte rjmp loop ;jump to top loop inc_high: clr low_byte ;clear low_byte inc high_byte ;increment high_byte cpi high_byte,$ff ;is high_byte 255? breq change ;branch to change parameter rjmp loop ;jump to top loop change: cpi speed_flg,$00 ;slow ? brne dec_dot ;not slow branch to fast inc dot_len ;slow increment dot_len rjmp w_eeprom dec_dot:dec dot_len ;fast decrement dot_len w_eeprom: ;*********** write dot_len to EEPROM sbic EECR,EEWE ;if EEWE not clear rjmp w_eeprom ;wait more ldi temp,speed_adrs ;load address of speed parameter out EEAR,temp ;set address to EEPROM out EEDR,dot_len ;output data sbi EECR,EEMWE ;set master write enable sbi EECR,EEWE ;set EEPROM write strobe rjmp main_loop ;jump to main_loop ;********** end of main routine *********************************** ;*************************************************************** ; Timer0 Overflow interrupt ; This routine is called every 10ms from timer overflow ;*************************************************************** tm_ovf: in sreg_save,SREG ;save SREG inc rand ;rand++ ldi temp,$f6 ;1/10 out TCNT0,temp ;Devide ration set cp rand,limit ;if loopcounter=100 1sec brlo rtn_tm ;if rand < upper return from interrupt clr rand ;clear rand out SREG,sreg_save ;restore SREG rtn_tm: reti ;return form tm0 interrupt ;***************** end of tm0 interrupt *********************** ;**************** hardware interrupt ********************************* ; Disable external and time interrupt ; Get morse code from EEPROM. Random value is used as EEPROM address ;********************************************************************* morse: ldi temp,$00 out GIMSK,temp ;disable external interrupt out TIMSK,temp ;diable timer interrupt add rand,offset ;offset table address eeread: sbic EECR,EEWE ;if EEWE not clear rjmp eeread ;wait more out EEAR,rand ;set EEPROM address sbi EECR,EERE ;strobe EEPROM in morse_code,EEDR ;read morse code from EEPROM next_ele: lsl morse_code ;logical shift left brcc dot ;not carry branch dot rcall one_ele ;out one element rcall one_ele ;out one element dot: rcall one_ele ;out one element rcall space ;out one space cpi morse_code,end_ele ;end($80) ? brne next_ele ;not end branch nexe_ele reti ;return from interrupt ;**************** end of external interrup ************************* one_ele:mov ele_len,dot_len ;move dot_len to ele_len oe_lp: sbi portb,0 ;out 1 to PB0 rcall delay ;0.5ms cbi portb,0 ;out 0 to PB0 rcall delay ;0.5ms dec ele_len ;decrement element length brne oe_lp ;ele_len != 0 ret space: mov ele_len,dot_len ;move dot_len to ele_len sp_lp: nop ;no opration rcall delay ;0.5ms nop ;no opration rcall delay ;0.5ms dec ele_len ;decrement element length brne sp_lp ;ele_len != 0 ret ;******************************************************************* ; This delay routine makes a half cycle time of tone signal. ; ((100*9)*100+100+100+100)*5+100+400=452500 ; 452.5us=0.4525ms=1.1KHz ; Master clock is 10MHz. ;******************************************************************* delay: ldi cnt1,5 ;100ns d_lp1: ldi cnt2,100 ;100ns d_lp2: nop ;100ns nop ;100ns nop ;100ns nop ;100ns nop ;100ns nop ;100ns nop ;100ns dec cnt2 ;100ns brne d_lp2 ;100ns dec cnt1 ;100ns brne d_lp1 ;100ns ret ;400ns ;******************* end of delay routine ************************