| CODE |
.org.include "tn12def.inc";Note that no path is given for this file. .include "m8def.inc" ;Include file is in the same directory as the project. ;Interrupt timer parameters .equ a1wpmhigh =$12 ;High byte of number of clocks between interrupts. .equ a1wpmlow =$43 ;Low byte of number of clocks between interrupts. .equ a5wpmhigh =$03 ;High byte of number of clocks between interrupts. .equ a5wmplow =$A9 ;Low byte of number of clocks between interrupts. .equ a10wpmhigh =$01 ;High byte of number of clocks between interrupts. .equ a10wpmlow =$D4 ;Low byte of number of clocks between interrupts. .equ a25wpmhigh =$00 ;High byte of number of clocks between interrupts. .equ a25wpmlow =$BB ;Low byte of number of clocks between interrupts. .equ timer0rel1khz =254 ;Reload value for tone timer. 254 = 1 kHz. .equ timer0rel500hz =252 ;Reload value for tone timer. 252 = 500 Hz. ;UART baud rate calculation .equ clock = 4000000 ;clock frequency .equ baudrate = 9600 ;choose a baudrate .equ baudconstant = (clock/(16*baudrate))-1 ;ALLOCATE BUFFER(S) .equ rambot =$60 .equ lbuffsize = 80 ;Bytes allocated to line buffer .equ lbufftop = rambot+80 .equ lbuffbot = rambot;Top address (start of) line buffer .def opsel = r2 ;Option select bits .def termsel = r3 ;Options as selected by terminal .def tim0rel = r4 ;Timer 0 reload value .def EEchecksum = r5 ;Simple checksum of EEPROM from $60 to $FE .def temp = r16 ;General purpose scratch register. .def a1 = r17 ;Three byte number .def a2 = r18 ;Three byte number .def a3 = r19 ;Three byte number .def h = r20 ;Binary to decimal conversion. .def t = r21 ;Binary to decmial conversion. .def u = r22 ;Binary to decimal conversion. .def flagreg = r23 ;Flags. .def temp2 = r24 ;Intermediate results ;EEPROM Map ;$60 to $B0 Line Buffer ;$FE termsel byte ;$FF simple checksum ;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 ;defintion of opsel O(ption Select) bits ;0 lsb of code speed select (corresponds to port pin C4) ;1 msb of code speed select (correspoinds to port pin C5) ;2 lsb of A/D channels select (corrseponds to port p[in D2) ;3 msb of A/D channels select (corrseponds to port p[in D3) ;4 Tone Hi/low. 1 = 1 kHz; 0 = 500 Hz (corrsponds to port pin D4) ;5 Deault operation if 1 (corresponds to port pin D5) ;6 ;7 ;definition of termsel (terminal selection) bits -parameters set by RS-232 interface ;and stored in EEPROM. ;0 Terminal selections override user I/O selections when set. Can be over-ridden by groudning pin 11. ;1 Analog channel A on when set. ;2 Analog channel B on when set. ;3 Analog channel C on when set. ;4 Analog channel D on when set. ;5 lsb of code speed (corresponds to obsel bit 0). ;6 msb of code speed (corresponds to obsel bit 1). ;7 Tone Hi/low (corresponds to obsel bit 4). ;definition of I/O ;B0 + comparitor input (Reserved) ;B1 - comparitor input (Reserved) ;B2 Tone (Morse code) output ;B3 Morse code output ;B4 A/D channels 0 - configure as INPUT with weak pullup ;B5 A/D channels 1 - configure as INPUT with weak pullu ;B6 (not assigned - configure as INPUT with weak pullup) ;B7 (not assigned - configure as INPUT with weak pullup) .equ PORTBdata =0b11110000 ;Initial data .equ DDRBdata =0b00001100 ;Initial data .equ codeport = PORTB .equ codeout = DDRB .equ codebit = 2 ;Tone output .equ pulsebit = 3 ;Morse code output ;C0 A/D A configure as INPUT, with weak pullup when not used ;C1 A/D B configure as INPUT, with weak pullup when not used ;C2 A/D C configure as INPUT, with weak pullup when not used ;C3 A/D D configure as INPUT, with weak pullup when not used ;C4 Code Speed 0 - configure as INPUT with weak pullup ;C5 Code speed 1 - configure as INPUT with weak pullup ;C6 Reset pin - configure as INPUT with weak pullup ;C7 (does not exist - configure as INPUT with weak pullup) .equ PORTCdata =0b11110000 ;Initial data .equ DDRCdata =0b000000O0 ;Initial data ;D0 UART RECEIVE - configured with weak pullup ;D1 UART TRANSMIT ;D2 (not assigned - configure as INPUT with weak pullup) ;D3 (not assigned - configure as INPUT with weak pullup) ;D4 Tone Select - configure as INPUT with weak pullup) ;D5 Default Op - configure as INPUT with weak pullup) ;D6 (not assigned - configure as INPUT with weak pullup) ;D7 (not assigned - configure as INPUT with weak pullup) .equ PORTDdata =0b11111101 ;Initial data .equ DDRDdata =0b00000010 ;Initial data .cseg .ORG $0000 rjmp start .org $0009 rjmp timer0service ;Initializaton code start: ;Entry point after reset -initialize everything warm: ;Warm is actually a reset. ldi temp,DDRBdata ;Set PORTB. out DDRB,temp ldi temp,PORTBdata out PORTB,temp ldi temp,DDRCdata ;Set PORTC out DDRC,temp ldi temp,PORTcdata out PORTc,temp ldi temp,DDRDdata ;Set PORTD. out DDRD,temp ldi temp,PORTDdata out PORTD,temp ldi temp,high(ramend) ;Initialize 16 bit Stack Pointer out sph,temp ldi temp,low(ramend) out spl,temp clr flagreg ;Clear firmware flagreg (flag register). ;SET UP USART clr temp ; Set baud rate out UBRRH, temp ldi temp,baudconstant ;load computed value for baud rate out UBRRL, temp ;Enable Receiver and Transmitter ldi temp, (1<<RXEN)|(1<<TXEN) out UCSRB,temp ;Set frame format: 8data, 2stop bit ldi temp, (1<<URSEL)|(1<<USBS)|(3<<UCSZ0) out UCSRC,temp ;8 BIT TIMER 0 SETUP ldi temp,5 ;Set prescaler for clk/8 out TCCR0,temp ldi temp,timer0rel1khz ;Set number of pulses to count up after division by prescaler mov tim0rel,temp ;Default is for 1 kHz (4 MHz clock). out TCNT0,temp in temp,TIMSK ori temp,0b00000001 ;Enable timer 0 oveflow interrupt. out TIMSK,temp ;ITINITALIZE A TO D CONVERTER ldi temp,0b00010101 ;Set control and status register. 4 MHz clock.Clear int flag. out ADCSR,temp sei ;Enable interrupts. ;Now that interrups are on and there is a tone, send the greeting. ldi temp,0b11111100 ;25 words per minute mov opsel,temp rcall setdottime ;Set the dot period as a function of opsel bit 0,1 rcall crlf rcall crlf rcall crlf rcall crlf rcall Typeheader ;Type the header at 25 WPM. rcall Loadcommand ;Load EEPROM contents into RAM $60 to $FF rcall typestatus ;Type terminal control setup. rcall DumpLineBuffer ;Display line buffer contents rcall GetOptionBits ;Get jumper selectable options to opsel register ;Switch flow to Programmed Main if bit o in termsel is set, ;EEPROM checksum is valid, and opsel bit 5 is set. ldi temp,0b00100000 ;Check for jumper pin override. and temp,opsel breq DefaultMain ldi temp,0b00000001 ;Check for terminal program control bit set in termsel and temp,termsel breq DefaultMain clr YH ;Check EEProm checksum ldi YL,$FF ld temp,Y cp temp,EEChecksum brne DefaultMain rjmp ProgrammedMain DefaultMain: ;Main Loop rcall GetOptionBits ;Get jumper selectable options to opsel register rcall setdottime ;Set the dot period as a function of opsel bit 0,1 rcall ToggleTonepitch ;Set tone pitch based on opsel bit 4 rcall MeasureAndSendVolts rcall interword rcall OptionsEditor ;Check to see if Operator requested Options Editor. rjmp DefaultMain ToggleTonepitch: ;Set the interrupt period to 500 Hz or 1 Khz push temp ;based on opsel bit 4. mov temp,opsel andi temp,0b00010000 breq x22 ldi temp,timer0rel1khz rjmp x23 x22: ldi temp,timer0rel500hz x23: mov tim0rel,temp ;Set interrupt time for chosen tone frequ. pop temp ret GetOptionBits: ;Get jumper selectable options to opsel register push temp in temp,PINC ;Get Port C bits 4,5. andi temp,0b00110000 lsr temp lsr temp lsr temp lsr temp mov opsel,temp in temp,PIND ;Get Port D bits 2,3,4, and 5. andi temp,0b00111100 or opsel,temp pop temp ret crlf: ;Send Carrige return and line feed ($0D, $0A) push temp ldi temp,$0D rcall emitchar ldi temp,$0A rcall emitchar pop temp ret emitchar0D: ;Send outchar to terminal. Add line feed to carriage return. push temp rcall emitchar cpi temp,$0D ;Its a carraiage return, send a linefeed also brne notareturn ldi temp,$0A rcall emitchar notareturn: pop temp ret emitchar: ;Send character contained in temp. sbis UCSRA,UDRE ;Test for TX register empty rjmp emitchar ;Loop until TX empty out UDR,temp ;Send the byte ret getchar: sbis UCSRA,RXC ;Wait until a character has been received rjmp getchar in temp,UDR ;Read byte from the UART ret Typeheader: ;Type header push ZL push ZH ldi ZH,high(2*hellomessage) ;Load high part of byte address into ZH ldi ZL,low(2*hellomessage) ;Load low part of byte address into ZL rcall typeromstring ;Send it pop ZH pop ZL ret hellomessage: .db $0A,$0D .db $0A,$0D .db "morbecon050219A " .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 SendMorseAscii ;Send upper case ASCII Char as Morse Code. adiw ZL,1 ;Increment Z registers rjmp srs1 finishsendstering: pop ZH ;Pop Z from stack. pop ZL rcall interword ret MeasureAndSendVolts: ;Measure 1 to 4 A/D channels and send the values as Morse Code ;and via RS-232 accoding to obsel bits 2 and 3. ;Bit 3 Bit 2 Measure ;1 1 Channel A only (ADC 0) ;0 1 Channels A & B (ADC 0,1) ;1 0 Channels A,B & C (ADC 0,1,2) ;0 0 Channels A,B,C & D (ADC 0,1,2,3) push temp ldi temp,'A' rcall SendMorseAscii ldi temp,0 ;Channel A always sent, so do that first. rcall measure ;Measure it. rcall SendVolts ;Send out as Morse Code mov temp,opsel andi temp,0b00001100 cpi temp,0b00001100 ;If bit 2 and 3 are set, we're done. breq donemeas push temp ldi temp,$20 rcall SendMorseAscii ldi temp,'B' rcall SendMorseAscii ldi temp,1 ;Do Channel B. rcall measure ;Measure it. rcall SendVolts ;Send out as Morse Code pop temp cpi temp,0b00000100 breq donemeas ;If only bit 2 is set, we're done. push temp ldi temp,$20 rcall SendMorseAscii ldi temp,'C' rcall SendMorseAscii ldi temp,2 ;Do Channel C.. rcall measure ;Measure it. rcall SendVolts ;Send out as Morse Code pop temp cpi temp,0b00001000 breq donemeas ;If only bit 3 is set, we're done. ldi temp,$20 rcall SendMorseAscii ldi temp,'D' rcall SendMorseAscii ldi temp,3 ;Do Channel D.. rcall measure ;Measure it. rcall SendVolts ;Send out as Morse Code donemeas: ;We are done. ldi temp,$20 rcall SendMorseAscii ldi temp,$0A rcall SendMorseAscii ldi temp,$0D rcall SendMorseAscii pop temp ret Measure: ;Measure A/D channel. Enter with channel number in temp. Exit with data in YH:YL ;Allowed range is 0..5 push temp sbi ADCSR,ADEN ;Enable A/D converter. andi temp,0b00000011 ;Mask off upper bits to restrict range of channel selction. ori temp,0b01000000 ;Set reference voltage bit. out ADMUX,temp ;Select channel. sbi ADCSR,ADSC ;Start conversion. wfc: sbis ADCSR,ADIF ;Wait for bit to be set, indicating conversion complete. rjmp wfc sbi ADCSR,ADIF ;Clear interrupt flag. in YL,ADCL ;Get data into Y register. in YH,ADCH pop temp 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. " The code that follows is based on this technique. 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. rcall OptionsEditor ;Check to see if Operator requested Options Editor. push ZL ;Save registers push ZH push temp ;Save contents of temp. rcall emitchar0D ;Emit the char via UART. pop temp ;Restore value of temp. 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 ;Restore registers pop ZL ret ;Return dot: ;Send dot, wait one dot time. sbr flagreg,0b00000010 ;Set flag to send tone. sbi codeport,pulsebit ;Set on-off key pulse high. rcall dottime cbr flagreg,0b00000010 ;Clear flag to send tone. cbi codeport,pulsebit ;Set on-off key pulse low. rcall dottime ret dash: ;Send dash, wait one dot time. sbr flagreg,0b00000010 ;Set flag to send tone. sbi codeport,pulsebit ;Set on-off key pulse high. rcall dottime rcall dottime rcall dottime cbr flagreg,0b00000010 ;Clear flag to send tone. cbi codeport,pulsebit ;Set on-off key pulse low. 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 setdottime: push temp ;Load compare registers, OCR1AH,OCR1AL with values for ;dot rate as a function of opsel bits 0 and 1. ; ; bit1 bit0 Code Speed OCR1AH ORC1Al ; 1 1 10 WPM ; 1 0 1 WPM ; 0 1 5 WPM ; 0 0 25 WPM ; ;Note Code speed is calcualted using PARIS (50 spaces) ;send in 1 minute = 1 WPM. mov temp,opsel ;Get option select bits into temp. andi temp,0b00000011 ;Mask off all but two lsb. cpi temp,0 ;Test if 0. brne not0 ;If not 0 skip to next test. ldi temp,a25wpmhigh ;If 0 load parameters for 25 WPM. out OCR1AH,temp ldi temp,a25wpmlow out OCR1AL,temp rjmp speedset not0: cpi temp,1 ;Test for value = 1. brne not1 ldi temp,a5wpmhigh out OCR1AH,temp ldi temp,a5wmplow out OCR1AL,temp rjmp speedset not1: cpi temp,2 ;Test for value = 2 brne not2 ldi temp,a1wpmhigh out OCR1AH,temp ldi temp,a1wpmlow out OCR1AL,temp rjmp speedset not2: ldi temp,a10wpmhigh ;Its not 0,1, or 2, so it must be 3. out OCR1AH,temp ldi temp,a10wpmlow out OCR1AL,temp speedset: ;Come to here when speed has been set. pop temp ret dottime: ;Delay one dot time. push temp ldi temp,0b00001101 ;Set timer 1 to reset 0000 after compare match. Prescaler = 1X. out TCCR1B,temp out TCCR1B,temp wd1: in temp,TIFR sbrs temp,OCF1A ;Wait for flagreg bit two to go high (timer to time out) rjmp wd1 out TIFR,temp ;Clear the flag ldi temp,0b00000000 ;Set timer 1 to "normal" mode, prescale output stopped. out TCCR1B,temp pop temp ret SendVolts: ;Enter with input value in YH:YL. YH,YL,a1,a2,a3,temp,H,T,U modified. ;Scale input with range of 0 to 1023 to d digit expression of range ;from 0 to 5. This is for a 5 volt full scale input 10 bit ADC. ;Multiply input by 489 and divide by 1,000 to get answer in tens of ;millivolts. push temp clr a1 ;Clear the 3 byte number clr a2 clr a3 mloop: tst YL brne notzero tst YH brne notzero rjmp countdone notzero: sbiw YL,1 ;Decrement the 10 bit value and add 489 to each time ldi temp,$E9 add a1,temp ;To multiply number in Y by 489 ldi temp,$01 adc a2,temp clr temp adc a3,temp rjmp mloop countdone: ;At this point, the product is in a1,2,3 ;Test values come out of 489000 here. clr H clr T clr U MoreH: inc H subi a1,$A0 ;Find out how many 100,000's sbci a2,$86 sbci a3,1 brcc MoreH ldi temp,$A0 ;Subtracted one too many, add back on. add a1,temp ldi temp,$86 adc a2,temp ldi temp,1 adc a3,temp dec H ;VALUE EXITING THIS ROUTINE IS 23112. SHOULD BE 89000. MoreT: inc T subi a1,$10 ;Find out how many 10.000's sbci a2,$27 sbci a3,$00 brcc moreT ldi temp,$10 ;Subtracted one too many, add back on. add a1,temp ldi temp,$27 adc a2,temp ldi temp,0 adc a3,temp dec T MoreU: inc U subi a1,$E8 ;Find out how many 10.000's sbci a2,$03 sbci a3,$00 brcc moreT ldi temp,$E8 ;Subtracted one too many, add back on. add a1,temp ldi temp,$03 adc a2,temp ldi temp,0 adc a3,temp dec U subi H,-48 ;Convert to ASCII and send. Send H mov temp,H rcall SendMorseAscii subi T,-48 mov temp,T rcall SendMorseAscii subi U,-48 ;Send U mov temp,U rcall SendMorseAscii rcall interword rcall interword rcall interword pop temp ret ;/////////////////////////////Morse Code Chart\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ 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 ;/////////////////////////////Interrupt 0 to create tone\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ timer0service: push temp in temp,sreg push temp mov temp,tim0rel ;Set number of pulses to count up after division by prescaler out TCNT0,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 andi flagreg,0b11111110 rjmp toggledone codehigh: sbi codeport,codebit 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 ;sing interupts for dot and tone, this equalization won't be needed anymore. nop nop rjmp toggledone reti ;/////////////////////////////Setup via RS-232 Terminal\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ typestatus: ;Type the user teminal controls setup rcall GetOptionBits ;Get jumper selectable options to opsel register rcall Checkpin11 ;Check to see if Pin 11 is grounded. rcall ShowADOnOff ;Show status of A/D channels rcall ShowTermSetting ;Show Status of terminal control rcall ShowWPM ;Show WPM rcall ShowTone ;Show tone settings ret OptionsEditor: ;Allow user to set options via RS-232. ;Check to see if return character ($0D) is in UART recveive buffer. ;If no $0D, return to calling routine. ;If it is $0D, then enter editor to edit options. chk1: sbis UCSRA,RXC ;Check for character ret ;If no character, return in temp,UDR ;Read byte from the UART cpi temp,$0D breq HaveCR rjmp chk1 ;Continue to check for CR until buffer empty. Return if no $0D. HaveCR: ;Start Editor cli ;Stop interrupts while in options editor rcall crlf rcall crlf rcall typestatus rcall EditorGreeting ;Print greeting and menu. rcall getchar ;Get a character from the terminal. rcall crlf andi temp,$5F ;Make character upper-case. cpi temp,'A' breq Atodonoffj ;Toggle A/D channels on and off. cpi temp,'B' breq EnterTextj ;Enter text. cpi temp,'C' breq ToggleTerminalj ;Toggle terminal override of jumpers ON/OFF. cpi temp,'D' breq SetWPMj ;Set code speed. cpi temp,'E' breq ToggleTonej ;Toggle between 500Hz and 1 kHz tone cpi temp,'X' breq DoneOptons rjmp HaveCR DoneOptons: rcall TypeStoringMessage ;Save setup data rcall SaveCommand rcall crlf rjmp warm ;Warm start Atodonoffj: jmp Atodonoff EnterTextj: jmp EnterText ToggleTerminalj: jmp ToggleTerminal SetWPMj: jmp SetWPM ToggleTonej: jmp ToggleTone Checkpin11: ;Check pin 11 of the chip directly (port pin D5) sbis PIND,5 rcall WarnPin11 ret WarnPin11: ;Warn that pin 11 is grounded push ZL push ZH ldi ZH,high(2*Pin11message) ;Load high part of byte address into ZH ldi ZL,low(2*Pin11message) ;Load low part of byte address into ZL rcall typeromstring ;Send it pop ZH pop ZL ret TypeOFFMessage: ;Type labels for status of A/D inputs push ZL push ZH ldi ZH,high(2*OFFMessage) ;Load high part of byte address into ZH ldi ZL,low(2*OFFMessage) ;Load low part of byte address into ZL rcall typeromstring ;Send it pop ZH pop ZL ret OFFMessage: .db "OFF " .db $00,$00 TypeSelectAChannelmessage: ;Type labels for status of A/D inputs push ZL push ZH ldi ZH,high(2*SelectAChannelmessage) ;Load high part of byte address into ZH ldi ZL,low(2*SelectAChannelmessage) ;Load low part of byte address into ZL rcall typeromstring ;Send it pop ZH pop ZL ret SelectAChannelmessage: .db "Select a channel to toggle ON/OFF or X to eXit > " .db $00,$00 ShowADOnOff: rcall TypeAnalogChannelMessage;Put up the menu, position cursor for ON/OFF status. ldi temp,$20 rcall emitchar rcall emitchar rcall emitchar rcall emitchar rcall emitchar rcall emitchar rcall emitchar rcall emitchar rcall emitchar rcall emitchar rcall emitchar rcall emitchar mov temp2,termsel ror temp2 ;Get channel a flag into carry ror temp2 brcc noA rcall TypeONMessage ;Display either "ON" or "OFF" depending on rjmp HaveA ;State of bits corresponding to channels A..D. noA: call TypeOFFMessage HaveA: ror temp2 brcc noB rcall TypeONMessage rjmp HaveB noB: call TypeOFFMessage HaveB: ror temp2 brcc noC rcall TypeONMessage rjmp HaveC noC: call TypeOFFMessage HaveC: ror temp2 brcc noD rcall TypeONMessage rjmp HaveD noD: call TypeOFFMessage HaveD: rcall crlf ret Atodonoff: ;Turn A/D Channels on and off. rcall ShowADOnOff ;Show status of A/D channels rcall crlf rcall TypeSelectAChannelmessage rcall getchar andi temp,$5F ;Make upper-case cpi temp,'A' breq toggleA cpi temp,'B' breq toggleB cpi temp,'C' breq toggleC cpi temp,'D' breq toggleD cpi temp,'X' breq ad1 rjmp Atodonoff ad1: rcall crlf rjmp HaveCR ;Return to calling menu toggleA: ldi temp,0b0000010 eor termsel,temp rjmp Atodonoff toggleB: ldi temp,0b0000100 eor termsel,temp rjmp Atodonoff toggleC: ldi temp,0b0001000 eor termsel,temp rjmp Atodonoff toggleD: ldi temp,0b0010000 eor termsel,temp rjmp Atodonoff TypeAnalogChannelMessage: ;Type labels for status of A/D inputs push ZL push ZH ldi ZH,high(2*Analogchanelmessage);Load high part of byte address into ZH ldi ZL,low(2*Analogchanelmessage) ;Load low part of byte address into ZL rcall typeromstring ;Send it pop ZH pop ZL ret Analogchanelmessage: ;Labels for status of A/D inputs .db $0A,$0D .db "Channel: A B C & Build your own community today with the largest message board hosting company. |