📄 at90s2313controlplllmx1601_asm.txt
字号:
;******************************************************
;Version LMX060331D
;
;PLL FM Transmitter control firmware for AT90S2313 or ATtin2313
;controlling a National Semiconductor LMX1601 PLL chip. Both chips
;are clocked at 4 Mhz. Accuracy of the clock affects accuracy of the
;PLL frequency.
;
;
;The AUX PLL is used since its operational range includes
;the FM broadcast band. The 4 Mhz clock from the microcontroller
;is devided by 320 to make a 12.5 kHz reference frequency. The AUX
;prescaler devides by 8, so each count into the 16 bit AUX N Counter
;counts for 100 kHz. Therefore, a value of 1000 in the AUX N Counter
;will result the PLL operating at 100.0 MHz. Each increase in the
;value written to the AUX N Counter will increase the oscillator frequency
;by 100 kHz. So, a value of 1001 will make the PLL drive the oscillator
;to 100.1 kHz.
;
; The SendAUX_N: routine adds an offset of 825 to the contents of
;the register named "channel", and channel is a single 8 bit variable.
;Thus, the maximum range of the PLL is:
;Minimum frequency = 100 kHz X (825 + 0) = 82.5 kHz.
;Maximum frequency = 100 kHz x (825 + 255) = 108.0 MHz
;
;Tests in the Plusbutton and Minusbutton routines restirct the
;range of the PLL to 88.0 to 108.0 MHz.
;
;Read the LMX1601 datasheet carefully.
;
;******************************************************
.nolist ;Don't include 2313 defitiions in the
.include "2313def.inc" ;listing file.
.list
;******************************************************
;************* MEMO OF I/O PORT ASSIGNMENTS *************
;Port B pin assignments
;B0 Comparitor + input INPUT
;B1 Comparitor - input INPUT
;B2 - Button INPUT with pullup
;B3 + Button INPUT with pullup
;B4 Oscillator Enable OUTPUT
;B5 LMX1601 Clock Pin, Microwire OUTPUT
;B6 LMX1601 Data Pin, Microwire OUTPUT
;B7 LMX1601 Latch Enablem Microwire OUTPUT
;PORT D pin assignments
;D0
;D1
;D2
;D3
;D4 Daignostic - high during interrupts OUTPUT
;D5 Status LED. 1 = ON OUTPUT
;D6 Beep output OUTPUT
;D7
;************* DEFINE FEGISTER USAGE *************
;Variables for shifting into LMX1601 AUX_N register.
.def AUX_Nr2 = r5
.def AUX_Nr1 = r6
.def AUX_Nr0 = r7
;Variables for VOX timer.
.def voxt0 = r8
.def voxt1 = r9
;Variables for button and EEPROM management.
.def temp = r16 ;Scratch register.
.def temp2 = r17 ;Scratch register.
.def delayone = r18 ;Used for button filtering delay.
.def delaytwo = r19 ;Used for button filtering delay.
.def Dreg = r20 ;PORTD data output buffer
.def EEPROMpntr = r21 ;Pointer to EEPOROM location to
;be read/written. Bits zero
.def flagreg = r22 ;Flags for firmware.
;LMX1601 loader Register assignments.
.def delayc = r2 ;Variable for delay routine.
.def secondelay = r3 ;Variable for delay routine.
.def channel = r4
.def tempreg = r23 ;General purpose working
;register for non-interrupt
;times
;Notaitonal (dummy) register assignments.
;def XL = r26 ;Used for Channel calculation.
;def XH = r27 ;Used for Channel calculation.
;def YL = r28 ;AUX_N counter value calculation
;def YH = 2r9 ;AUX_N counter value calculation
;def ZL = r30 ;EEPROM write delay
;def ZH = r31 ;EEPROM write delay
;flagreg bit assignments Single bit flags.
;0
;1
;2
;3
;4
;5 Set in On mode to indicate that oscillator is on.
;6 Set by comparitor interrupt routine.
;7 If set, data in dreg needs to be written to EEPROM.
;************* ESTABLISH CONSTANTS *************
.equ DataPin = 6 ;Bit 6 of PORTB is the Microwire
;data pin.
.equ ClockPin = 5 ;Bit 5 of PORTB is the Microwire
;data pin.
.equ LEPin = 7 ;Bit 7 of PORTB is the Microwire
;data pin.
.equ waitL = 0
.equ waitH = 3 ;waitH is the number of 10
;second increments.
;Initial data for LMX1601 registgers
;Make bit 7 of AuxR2 = 1 to look at
;Aux_R otuput, make it 1 to look at
;Aux_N output. Maker 4 upper bits (FoLD)
;= 0101 for Aux lock with xtal.
.equ AuxR2 = 0b11000000 ;Most significant byte. Upper two bits
;contain bits 16 and 17. The rest are ;
;unused.
.equ AuxR1 = 0b11000101 ;Middle byte ;Div by 320 for 12.5 kHz
;from 4 MHz xtal
.equ AuxR0 = 0b00000000 ;Least significant byte. Devide by 8.
.equ AUX_N2 = 0b00000000 ;With a 12.5 kHz reference frequency,
;osc freq = 100 kHz X N
.equ AUX_N1 = 0b11111010 ;Frequency can be changed by
;incrementing and decrementing N.
.equ AUX_N0 = 0b10000001
;The AUX_N vlaues 00000000 11111010
;10000001 get 100 MHz out of the
;synthesizer.
;The AUX_N vlaues $00 $FA $81 get
;100 MHz out of the synthesizer
.equ Main_R2 = 0b11110000
.equ Main_R1 = 0b11000000
.equ Main_R0 = 0b00000010
.equ Main_N2 = 0b00000000 ;These values should not matter.
.equ Main_N1 = 0b00000000
.equ Main_N0 = 0b00000011
.equ nominalchannel = 175 ;Channel 175 corresponds to 100 MHz.
;82.5 MHz + (175 X 100 kHz) = 100 MHz.
;************* START EXECUTABLE CODE *************
.org $0000
rjmp start
.org ACIaddr
rjmp ANA_COMP ;Analog Comparator Handle (Strictly
;speaking, the jump is not needed this
;time.)
ANA_COMP:
push tempreg ;Save tempreg on stack
in tempreg,SREG ;Temporarily store the Status register.
sbi PORTD,4 ;Diagnotic - set D4 high (So one can see
;the interrupts externally)
sbi PORTD,5 ;Turn the status LED on. (Make sure it
;is on)
sbr flagreg,0b01000000 ;Set comparitor tripped flag for
;foreground control of indicator light.
cbi PORTD,4 ;Diagnotic - set D4 low.
out SREG,temp ;Restore Status register.
pop tempreg ;Restore tempreg.
reti
on: ;Turn oscillator on.
push tempreg ;Turn on the oscillator and reset the
;vox timer.
sbi PORTB,4 ;Turn oscillator poin on.
sbr flagreg,0b00100000 ;Set oscillator running flag.
sbi PORTD,5 ;Turn status LED on.
clr voxt0
;Below is the vox timer, which shuts off
;the oscillator if a preset amount
;of time passes without an analog
;comparitor interrupt occurring.
;test modify the code between "test" and "
;endtest" to shorten timer period for
;test pruposes.
; ldi tempreg,20 ;This ine ACTIVE for TEST (For 9
;second timeout, make this value 20)
; mov voxt0,tempreg ;This ine ACTIVE for TEST
; ldi tempreg,1 ;This ine ACTIVE for TEST (For 9 second tiemout, make this value 1)
ldi tempreg,30 ;This line NOT ACTIVE for test. About 10
;seconds per count.
;endtest
mov voxt1,tempreg ;Each count in voxt1 is worth about 9
;seconds.
pop tempreg
ret
off: ;Turn oscillator off, clear indicators.
cbi PORTB,4 ;Turn off oscillator.
cbr flagreg,0b00100000 ;Clear oscillator running flag.
cbi PORTD,5 ;Make sure power LED is in OFF state.
cbi ACSR,ACIE ;Disable Analog Comparator interrup.
ldi tempreg,10 ;Delay for a second or two so oscillator
;off glictch does not retrigger.
Powerup2:
dec tempreg
breq PowerupDone2
rcall DelayLoader ;Wait for power supply to settle before
;loading LMX1601
rjmp Powerup2
PowerupDone2:
sbi ACSR,ACIE ;Enable Analog Comparator interrupt.
ret
start: ;COMES HERE AFTER POWER-ON RESET
ldi r16,RAMEND ;Init Stack Pointer
out SPL,r16
ldi tempreg,10 ;DelayLoader at startup.
Powerup:
dec tempreg
breq PowerupDone
rcall DelayLoader ;Wait for power supply to settle before
;loading LMX1601
rjmp Powerup
PowerupDone:
ldi tempreg,0b00001100 ;Set Port B pullups.
out PORTB,tempreg
ldi tempreg,0b11110000 ;Set port B direction bits.
out DDRB,tempreg
rcall DelayLoader ;DelayLoader before loading
ldi temp, AUX_N2 ;Load variables for LMX AUX_N register.
mov AUX_Nr2,temp
ldi temp, AUX_N1
mov AUX_Nr1,temp
ldi temp, AUX_N0
mov AUX_Nr0,temp
;Get the oscillator channel data from the EEPROM, bute $AA
ldi EEPROMpntr,$AA ;Get channel number from EEPROM.
rcall ReadEE
rcall LoadLMX ;Load initial control bits into LMX1601
;registers.
ldi temp, 00 ;Set PORTD as output.
out PORTD, temp ;Set bits to initial value.
ldi temp, $FF
out DDRD, temp
clr flagreg
ldi ZL, waitL
ldi ZH, waitH
rcall on ;Initially turn the oscillator on. It
;will time out if there is no stimulus.
ldi temp,(ACI<<1) ;Clear interrupt flag and ACIS1/ACIS0...
out ACSR,temp ;to select interrupt on toggle.
sei ;Enablfsbre global interrupts.
sbi ACSR,ACIE ;Enable Analog Comparator interrupt.
ldi temp,255
rcall Buzzloop
Loadbuttons: ;********Main loop entry point. ********
;Make LED blink, working with comparitor interrupt routine.
sbrc flagreg,5 ;In in On mode, then turn on LED.
sbi PORTD,5
sbrc flagreg,5 ;In in On mode, then turn on Oscillator.
sbi PORTB,4
sbrs flagreg,6 ;Turn on if comparitor has beentripped, and reset comparitor flag.
rjmp NotTripped
rcall on
cbi PORTD,5 ;Turn off LED
cbr flagreg,0b01000000 ;Clear the camparitor interrupt flag.
NotTripped:
dec ZL ;Wait some number of times through this loop before writing
; channel number to EEPROM.
brne noprog
dec ZH
brne noprog
ldi ZL, waitL
ldi ZH, waitH
sbrs flagreg,7
rjmp noprog
ldi EEPROMpntr,$AA
rcall WriteEE ;Write cuttent channel number to EEPROM.
andi flagreg,0b01111111
noprog:
dec voxt0
brne NoShutoff
dec voxt1
brne NoShutoff
rcall off
NoShutoff:
in temp ,PINB ;Get the button status.
andi temp,0b00001100 ;Only bits 2 and 3 can contain button
;information.
rcall delay ;Wait debounce period.
in temp2, pinB ;If button changed, start over
andi temp2,0b00001100 ;Only bits 2 and 3 can contain button
;information.
cp temp, temp2
brne loadbuttons
rcall InterpretButtons
rjmp loadbuttons
InterpretButtons: ;Interpret buttons routines called by
;this must terminate with ret
;instruction.
cpi temp,0b00000100 ;Is "+" button down?
breq Plusbutton
cpi temp,0b00001000 ;Is "-" button down?
breq Minusbutton
ret ;Both butttns case taken care of in debounce.
Plusbutton: ;Increment channel number and send new
;AUX_N value.
mov temp,channel
cpi temp,$FF ;Skip if channel number is already 255 (corresponds to 108 MHz).
breq DontIncrement
inc channel
rcall SendAUX_N
DontIncrement:
rcall on ;Assure that the oscillator is on while being adjusted.
rjmp Buttonack
Minusbutton: ;Increment channel number and send new
;AUX_N value.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -