'with permission from Jay, AJ4AY, ' '======================================================================= ' START Program ' MP+RevJay '======================================================================= '======================================================================= ' [ Program Description ] '======================================================================= ' ' Using an AT90S8515 micro-processor, provide control of an ' MP+ transceiver, including: ' AGC on/off ' Audio filter on/off ' Preamp on/off ' VFO Tuning ' VFO frequency change of 10, 100, & 1khz ' Dual VFO operation (VFO A or VFO B) ' SPLIT operation ' RIT on/off ' RIT frequency change in 10 hz steps, up to +/- 1 khz ' '----------------------------------------------------------------------- ' Port pin assignments are: ' ' Port A ' pin 0 output LCD DB7 pin 14 ' pin 1 output LCD DB6 pin 13 ' pin 2 output LCD DB5 pin 12 ' pin 3 output LCD DB4 pin 11 ' pin 4 output LCD Enable pin 6 ' pin 5 output LCD RS pin 4 ' pin 6 output Unused ' pin 7 output Freq +/- ' ' Port B ' pin 0 output DDS Load ' pin 1 output DDS Clock ' pin 2 output DDS Data ' pin 3 input TXE ' pin 4 input Band module bit 0 ' pin 5 input Band module bit 1 ' pin 6 input Band module bit 2 ' pin 7 input Band module bit 3 ' ' Port C ' pin 0 input AGC switch ' pin 1 input Pre-Amp switch ' pin 2 input Audio switch ' pin 3 input Step switch ' pin 4 input Split switch ' pin 5 input A = B switch ' pin 6 input A/B switch ' pin 7 input RIT switch ' ' Port D ' pin 0 input Frequency Encoder B ' pin 1 input RIT Encoder B ' pin 2 input Frequency Encoder A - INT0 ' pin 3 input RIT Encoder A - INT1 ' pin 4 output Relay Common ' pin 5 output Pre-Amp ' pin 6 output Audio Filter ' pin 7 output AGC ' '----------------------------------------------------------------------- '======================================================================= ' [ Compiler Statements ] '======================================================================= '----------------------------------------------------------------------- ' Program compiled to run on an AT90S8515 micro-controller. '----------------------------------------------------------------------- $regfile = "8515def.dat" 'AT90S8515 u-processor $crystal = 8000000 'at 8 mHz '======================================================================= ' [ Variable Declarations ] '======================================================================= '----------------------------------------------------------------------- ' Radio variables '----------------------------------------------------------------------- Dim bytAF As Byte 'ON (1) or OFF (0) Dim bytAGC As Byte 'ON (1) or OFF (0) Dim bytPreAmp As Byte 'ON (1) or OFF (0) Dim bytTR As Byte 'Trans (1) or Rcv (0) '----------------------------------------------------------------------- ' Band selection variables '----------------------------------------------------------------------- Dim bytBand As Byte 'Values 0..9 Dim bytSaveBand As Byte 'temp Dim bytFCOffset As Byte 'Frequency counter offset '----------------------------------------------------------------------- ' LCD variables '----------------------------------------------------------------------- Dim strLCDMessage As String * 16 '----------------------------------------------------------------------- ' RIT variables '----------------------------------------------------------------------- Dim bytRIT As Byte 'RIT ON (1) or OFF (0) Dim lonRITOffsetN As Long '0 to 2kHz Dim lonRITOffsetF As Long '0 to 2kHz Dim lonRITNoOffset As Long '= 0 '----------------------------------------------------------------------- ' VFO output variables '----------------------------------------------------------------------- Dim strActiveVFO As String * 1 '"A" or "B" Dim lonDDSACommand As Long '32 bit DDS command words Dim lonDDSBCommand As Long '32 bit DDS command words Dim bytSplit As Byte 'Split ON (1) or OFF (0) Dim bytStepChange As Byte 'values 0..3 Dim lonStepN As Long 'DDS changes for freq '----------------------------------------------------------------------- ' Frequency display variables '----------------------------------------------------------------------- Dim lonAFreq As Long 'The A VFO frequency Dim lonBFreq As Long 'The B VFO frequency DIm lonFreqChange As Long '10, 100 or 1k hz '----------------------------------------------------------------------- ' Interrupt variables '----------------------------------------------------------------------- Dim bytValuePinD As Byte Dim bytInt0Flag As Byte 'TRUE when INT0 Dim bytInt1Flag As Byte 'TRUE when INT1 Dim bytINT0Trigger As Byte Dim bytINT1Trigger As Byte '======================================================================= ' [ Alias Declarations ] '======================================================================= '----------------------------------------------------------------------- ' Switch Inputs '----------------------------------------------------------------------- aliAGCSwitch Alias PinC.0 'AGC ON or OFF aliPreampSwitch Alias PinC.1 'Pre-amp ON or OFF aliAFSwitch Alias PinC.2 'Audio Filter ON or OFF aliStepSwitch Alias PinC.3 '10, 100, or 1 kHz aliSplitSwitch Alias PinC.4 'Split ON/OFF aliAequalsB Alias PinC.5 'VFO's set equal aliABInput Alias PinC.6 'VFO A or B aliRITSwitch Alias PinC.7 'RIT ON/OFF '----------------------------------------------------------------------- ' DDS communications '----------------------------------------------------------------------- aliDDSLoad Alias PortB.0 'Load data aliDDSClock Alias PortB.1 'Clock data out aliDDSData Alias PortB.2 'data '----------------------------------------------------------------------- ' Relay Common Line '----------------------------------------------------------------------- aliRelayCommon Alias PortD.4 '----------------------------------------------------------------------- ' Relay Outputs '----------------------------------------------------------------------- aliPreampOut Alias PortD.5 aliAFOut Alias PortD.6 aliAGCOut Alias PortD.7 '----------------------------------------------------------------------- ' Frequency counter offset direction. '----------------------------------------------------------------------- aliFCDirection Alias PortA.7 '----------------------------------------------------------------------- ' Receive Volts - High during receive, Low during transmit '----------------------------------------------------------------------- aliRecVolts Alias PinB.3 '======================================================================= ' [ Subroutine Declarations ] '======================================================================= '----------------------------------------------------------------------- ' Audio Filter subs '----------------------------------------------------------------------- Declare SUB SetAF() Declare SUB ShowAF(valAF as Byte) '----------------------------------------------------------------------- ' AGC subs '----------------------------------------------------------------------- Declare SUB SetAGC() Declare SUB ShowAGC(valAGC as Byte) '----------------------------------------------------------------------- ' DDS subs '----------------------------------------------------------------------- Declare SUB GetN(valBand as Byte , _ valFreq_N_Data as Long , _ valAfreq as Long) Declare SUB LoadDDS(valDDS_Command as Long , _ valRIT_Offset_N as Long) '----------------------------------------------------------------------- ' Pre-Amp subs '----------------------------------------------------------------------- Declare SUB SetPreamp() Declare SUB ShowPreAmp(valPreAmp as Byte) '----------------------------------------------------------------------- ' Radio control subs '----------------------------------------------------------------------- Declare SUB GetBand(valBand as Byte) Declare SUB ShowFreq(valFreq as Long , valOffset as Long) Declare SUB ShowRIT(valRIT as Byte , valRIT_Offset as Long) Declare SUB ShowVFO(valVFO as string , valSplit as Byte) Declare SUB ShowStats(valAF as Byte , valAGC as Byte , _ valPreAmp as Byte , valRIT as Byte , _ valRIT_Offset as Long , _ valVFO as string , valSplit as byte , _ valStep as Byte , valTR as Byte) Declare SUB ShowStep(valStep as Byte) Declare SUB ShowTR(valTR as Byte) '----------------------------------------------------------------------- ' Relay subs '----------------------------------------------------------------------- Declare SUB ResetAll() Declare SUB SetRelay(valAGC as byte , valAF as byte , _ valPreAmp as byte) '======================================================================= ' [ Constant Declarations ] '======================================================================= '----------------------------------------------------------------------- ' Program Constants '----------------------------------------------------------------------- Const conOFF = 0 Const conON = 1 Const conPullupOff = 0 'pullup resistor disable Const conPullupOn = 1 'pullup resistor enable Const conRITChange = 430 'N value for 10 hz change Const conRITFChange = 10 Const conRITMaxNUP = 42950 'N value for +1000 hz Const conRITMaxNDOWN = -42950 'N value for -1000 hz Const conRITMaxFUP = 1000 Const conRITMaxFDOWN = -1000 '----------------------------------------------------------------------- ' Interrupt trigger Constants '----------------------------------------------------------------------- Const conTriggerFalling = 0 'interrupt trigger on falling edge Const conTriggerRising = 1 'interrupt trigger on rising edge Const conIFFrequency = 4913720 'IF frequency '----------------------------------------------------------------------- ' The frequency counter is offset by the IF. The direction of ' offset (up or down) is determined by the band. 15 meters up ' has an offset of down. All other bands have an offset of up. '----------------------------------------------------------------------- Const conFCOffsetDOWN = 0 Const conFCOffsetUP = 1 '----------------------------------------------------------------------- ' Step constants - As the encoder is turned, the rising edge of the ' A signal causes the interrupt 0 handler to run. The DDS frequency is ' changed by value lonStepN, which is set to one of the following ' constants. '----------------------------------------------------------------------- Const conStep10hz = 430 '10 hz change in frequency Const conStep100hz = 4295 '100 hz change in frequency Const conStep1000hz = 42950 '1 khz change in frequency '----------------------------------------------------------------------- ' Also applies to the change in frequency. '----------------------------------------------------------------------- Const conFreq10hz = 10 Const conFreq100hz = 100 Const conFreq1000hz = 1000 '----------------------------------------------------------------------- ' Port pin definitions. 0=Input 1=Output '----------------------------------------------------------------------- Const conPortADef = &HFF 'port A pins - outputs Const conPortBDef = &H07 'Port B pins - inputs & outputs Const conPortCDef = &H00 'Port C pins - inputs Const conPortDDef = &HF0 'Port D pins - inputs & outputs '======================================================================= ' [ Hardware Statements ] '======================================================================= '----------------------------------------------------------------------- ' Set up the ports. ' All INPUT pins have the pullup resistors enabled. '----------------------------------------------------------------------- DdrA = conPortADef 'all outputs DdrB = conPortBDef '0..2 outputs, 3..7 inputs PortB.3 = conPullupOn PortB.4 = conPullupOn PortB.5 = conPullupOn PortB.6 = conPullupOn PortB.7 = conPullupOn DdrC = conPortCDef 'all inputs PortC.0 = conPullupOn PortC.1 = conPullupOn PortC.2 = conPullupOn PortC.3 = conPullupOn PortC.4 = conPullupOn PortC.5 = conPullupOn PortC.6 = conPullupOn PortC.7 = conPullupOn DdrD = conPortDDef '0..3 inputs, 4..7 outputs PortD.0 = conPullupOn PortD.1 = conPullupOn PortD.2 = conPullupOn PortD.3 = conPullupOn '-------------------------------------------------------------------- ' The LCD is a 20 character by 2 row display. '-------------------------------------------------------------------- Config Lcd = 20 * 2 '-------------------------------------------------------------------- ' And uses the 4 pin communications mode. ' DB0..DB3 (pins 7..10) and R/W (pin 5) are connected to ground. '-------------------------------------------------------------------- Config Lcdpin = Pin , _ Db4 = PortA.3 , _ Db5 = PortA.2 , _ Db6 = PortA.1 , _ Db7 = PortA.0 , _ E = PortA.4 , _ Rs = PortA.5 '----------------------------------------------------------------------- ' Set the switch debounce time to 10msec. '----------------------------------------------------------------------- config debounce = 10 '----------------------------------------------------------------------- ' Interrupt handler definitions '----------------------------------------------------------------------- ' The tuning encoder is a Panasonic EVQB1R with a switch. Phase ' A will cause interrupt 0 on the rising edge. If phase B ' is a 0, the tuning knob is turning clockwise. If phase B is ' a 1, the tuning knob is turning counterclockwise. '----------------------------------------------------------------------- config INT0 = Falling bytINT0Trigger = conTriggerFalling On Int0 Int0Handler '----------------------------------------------------------------------- ' The RIT change encoder is also a Panasonic EVQB1R with a switch. ' The same conditions will produce a positive or negative frequency ' change as the RIT knob is turned, assuming that RIT is enabled. '----------------------------------------------------------------------- config INT1 = Falling bytINT1Trigger = conTriggerFalling On Int1 Int1Handler '======================================================================= ' [ MAIN Program] '======================================================================= '----------------------------------------------------------------------- ' Set program defaults '----------------------------------------------------------------------- strActiveVFO = "A" 'use VFO A bytAF = conON 'Audio filter is on bytAGC = conON 'AGC is on bytPreAmp = conON 'Preamp is on bytTR = conOFF 'Receive mode bytFCOffset = conFCOffsetUP 'freq counter offset is up bytInt0Flag = conOFF 'Interrupt 0 Flag OFF bytInt1Flag = conOFF 'Interrupt 1 Flag OFF lonRITNoOffset = 0 'RIT offset = 0 hz bytRIT = conOFF 'RIT is off lonRITOffsetN = 0 'RIT offset = 0 lonRITOffsetF = 0 'RIT offset frequency = 0 bytSaveBand = 0 'NO band module bytSplit = conOFF 'Split is off bytStepChange = 0 'step change of 10 hz lonStepN = conStep10hz 'frequency step change = 10 hz lonFreqChange = conFreq10hz '----------------------------------------------------------------------- ' All relays to the RESET position. '----------------------------------------------------------------------- call ResetAll '----------------------------------------------------------------------- ' Set the relays to the default positions. '----------------------------------------------------------------------- Call SetRelay(bytAGC , bytAF , bytPreAmp) '======================================================================= LCDStart: 'Initialize the display '======================================================================= '----------------------------------------------------------------------- ' Clear the DDS '----------------------------------------------------------------------- lonDDSACommand = 0 Call LoadDDS(lonDDSACommand , lonRITOffsetN) '----------------------------------------------------------------------- ' Clear the LCD display '----------------------------------------------------------------------- cursor off 'no cursor on LCD Cls 'clear the LCD Wait 1 'Wait 1 Second '----------------------------------------------------------------------- ' Band selection is defined on the low pass filter. Has a ' band module been found?? '----------------------------------------------------------------------- Call GetBand(bytBand) If bytBand > 0 then GoTo CkBand '----------------------------------------------------------------------- ' Not yet. Do nothing until a band module has been detected. ' The "No BAND Module" message is visible for 1/2 second then ' the LCD is cleared for 1 second. '----------------------------------------------------------------------- strLCDMessage = "No BAND Module " locate 1 , 1 Lcd strLCDMessage Waitms 500 'delay 500 mseconds GoTo LCDStart '======================================================================= CkBand: 'Valid values are 1..9 '======================================================================= '----------------------------------------------------------------------- ' A band module has been found. Valid values are 1..9. '----------------------------------------------------------------------- If bytBand < 10 then GoTo BandOK strLCDMessage = "Invalid BAND " 'This is not good. locate 1 , 1 'The band selection pins are Lcd strLCDMessage 'not wired properly. Waitms 500 GoTo LCDStart '======================================================================= BandOK: 'Valid band '======================================================================= '----------------------------------------------------------------------- ' Save the band. '----------------------------------------------------------------------- bytSaveBand = bytBand '----------------------------------------------------------------------- ' Set the Frequency counter offset, up (1) or down (0). The offset ' is UP for bands 1..7 and down for bands 8 and 9. '----------------------------------------------------------------------- If bytBand < 7 then bytFCOffset = conFCOffsetUP ReSet aliFCDirection Else bytFCOffset = conFCOffsetDOWN Set aliFCDirection End If '----------------------------------------------------------------------- ' Display the radio status on the LCD display. At this time, ' all radio controls assume default values. '----------------------------------------------------------------------- Call ShowStats(bytAF , bytAGC , bytPreAmp , bytRIT , _ lonRITOffsetF , strActiveVFO , bytSplit , bytStepChange , _ bytTR) '----------------------------------------------------------------------- ' Get the starting 40 bit DDS command for VFO_A. This is also ' a default value, depending on the band. It is assumed that ' the standard (?) QRP operating frequency for the band is the ' the default value. '----------------------------------------------------------------------- Call GetN(bytBand , lonDDSACommand , lonAFreq) '----------------------------------------------------------------------- ' Send the 40 bit command to the DDS card. '----------------------------------------------------------------------- Call LoadDDS(lonDDSACommand , lonRITOffsetN) '----------------------------------------------------------------------- ' At start up, VFO A is the default active VFO. Set VFO B equal ' to VFO A. SPLIT and RIT are both OFF at this time. '----------------------------------------------------------------------- lonBFreq = lonAFreq lonDDSBCommand = lonDDSACommand '----------------------------------------------------------------------- ' Display the operating frequency. '----------------------------------------------------------------------- Call ShowFreq(lonAFreq , lonRITOffsetF) '----------------------------------------------------------------------- ' Enable the interrupts. This must be done before the individual ' INT0 and INT1 interrupts are enabled. '----------------------------------------------------------------------- Enable Interrupts '----------------------------------------------------------------------- ' Enable the tuning encoder interrupt - INT0. '----------------------------------------------------------------------- Enable Int0 '======================================================================= MainLoop: 'Enter the MAIN program loop. '======================================================================= '----------------------------------------------------------------------- ' The MAIN program sequence looks for the pressing of a button, ' the changing of a band module, or the processing of an interrupt. '----------------------------------------------------------------------- '----------------------------------------------------------------------- ' Check the interrupt flags first. The flags are set ON in the ' interrupt handler. Action is processed here. This keeps ' interrupt processing time to a minimum. '----------------------------------------------------------------------- If bytInt0Flag = conOn then goto DoINT0 If bytInt1Flag = conOn then goto DoINT1 '----------------------------------------------------------------------- ' TRANSMIT mode? Check receiver voltage pin. If it is low, the ' transceiver is in transmit mode. '----------------------------------------------------------------------- debounce aliRecVolts , 0 , XMIT '----------------------------------------------------------------------- ' Check for the pressing of a button. The input pin pull up ' resistors are enabled so the pressing of a button pulls ' the input low. '----------------------------------------------------------------------- debounce aliABInput , 0 , ABPressed debounce aliAequalsB , 0 , AEqualsBPressed debounce aliAGCSwitch , 0 , AGCPressed debounce aliAFSwitch , 0 , AFPressed debounce aliPreampSwitch , 0 , PreampPressed debounce aliRITSwitch , 0 , RITPressed debounce aliSplitSwitch , 0 , SplitPressed debounce aliStepSwitch , 0 , StepPressed '----------------------------------------------------------------------- ' Has the band module changed? The band module can be changed ' with power ON. Not recommended. '----------------------------------------------------------------------- Call GetBand(bytBand) If bytBand = bytSaveBand then GoTo MainLoop '----------------------------------------------------------------------- ' A different band module or NO bamd module has been found. Start ' over with checking the band module and new defaults. '----------------------------------------------------------------------- GoTo LCDStart '======================================================================= ' The MAIN program routine has ended. What follows are the handler ' routines for various operator actions. '======================================================================= '======================================================================= ABPressed: 'The A/B button has been Pressed. '======================================================================= '----------------------------------------------------------------------- ' Swaps the active/inactive VFO. '----------------------------------------------------------------------- If strActiveVFO = "A" then strActiveVFO = "B" Call LoadDDS(lonDDSBCommand , lonRITOffsetN) Call ShowFreq(lonBFreq , lonRITOffsetF) else strActiveVFO = "A" Call LoadDDS(lonDDSACommand , lonRITOffsetN) Call ShowFreq(lonAFreq , lonRITOffsetF) end if Call ShowVFO(strActiveVFO , bytSplit) GoTo MainLoop '======================================================================= AEqualsBPressed: 'The A=B button has been Pressed. '======================================================================= '----------------------------------------------------------------------- ' Sets the inactive VFO equal to the active VFO. '----------------------------------------------------------------------- if strActiveVFO = "A" then lonDDSBCommand = lonDDSACommand lonBFreq = lonAFreq else lonDDSACommand = lonDDSBCommand lonAFreq = lonBFreq end if GoTo MainLoop '======================================================================= AGCPressed: 'The AGC button has been Pressed. '======================================================================= '----------------------------------------------------------------------- ' Toggles the AGC ON and OFF. '----------------------------------------------------------------------- If bytAGC = conOFF then bytAGC = conON Call SetAGC Else bytAGC = conOFF Call ResetAll Call SetRelay(bytAGC , bytAF , bytPreAmp) End If Call ShowAGC(bytAGC) GoTo MainLoop '======================================================================= AFPressed: ' The audio filter button has been Pressed. '======================================================================= '----------------------------------------------------------------------- ' Toggles the audio filter ON and OFF. '----------------------------------------------------------------------- If bytAF = conOFF then bytAF = conON Call SetAF Else bytAF = conOFF Call ResetAll Call SetRelay(bytAGC , bytAF , bytPreAmp) End If Call ShowAF(bytAF) GoTo MainLoop '======================================================================= DoINT0: ' Process interrupt 0 - tuning knob has been turned '----------------------------------------------------------------------- '----------------------------------------------------------------------- ' Disable interrupt 0 first. '----------------------------------------------------------------------- Disable Int0 '----------------------------------------------------------------------- ' The tuning knob has been turned, producing interrupt 0 and setting ' bytInt0Flag true. '----------------------------------------------------------------------- If bytINT0Trigger = conTriggerRising then '----------------------------------------------------------------------- ' Interrupt triggered on the rising edge of phase A. ' phase B = 0 is CW, phase B = 1 is CCW '----------------------------------------------------------------------- If strActiveVFO = "A" then If bytValuePinD = 0 then '----------------------------------------------------------------------- ' Tuning is UP frequency. '----------------------------------------------------------------------- lonDDSACommand = lonDDSACommand + lonStepN lonAFreq = lonAFreq + lonFreqChange Else '----------------------------------------------------------------------- ' Tuning is DOWN frequency. '----------------------------------------------------------------------- lonDDSACommand = lonDDSACommand - lonStepN lonAFreq = lonAFreq - lonFreqChange End If Call LoadDDS(lonDDSACommand , lonRITOffsetN) Call ShowFreq(lonAFreq , lonRITOffsetF) Else '----------------------------------------------------------------------- ' VFO B is the active VFO. '----------------------------------------------------------------------- If bytValuePinD = 0 then '----------------------------------------------------------------------- ' Tuning is UP frequency. '----------------------------------------------------------------------- lonDDSBCommand = lonDDSBCommand + lonStepN lonBFreq = lonBFreq + lonFreqChange Else '----------------------------------------------------------------------- ' Tuning is DOWN frequency. '----------------------------------------------------------------------- lonDDSBCommand = lonDDSBCommand - lonStepN lonBFreq = lonBFreq - lonFreqChange End If Call LoadDDS(lonDDSBCommand , lonRITOffsetN) Call ShowFreq(lonBFreq , lonRITOffsetF) End If config INT0 = Falling bytINT0Trigger = conTriggerFalling Else '----------------------------------------------------------------------- ' Interrupt triggered on the falling edge of phase A. ' phase B = 0 is CCW, phase B = 1 is CW '----------------------------------------------------------------------- If strActiveVFO = "A" then If bytValuePinD = 0 then '----------------------------------------------------------------------- ' Tuning is DOWN frequency. '----------------------------------------------------------------------- lonDDSACommand = lonDDSACommand - lonStepN lonAFreq = lonAFreq - lonFreqChange Else '----------------------------------------------------------------------- ' Tuning is UP frequency. '----------------------------------------------------------------------- lonDDSACommand = lonDDSACommand + lonStepN lonAFreq = lonAFreq + lonFreqChange End If Call LoadDDS(lonDDSACommand , lonRITOffsetN) Call ShowFreq(lonAFreq , lonRITOffsetF) Else '----------------------------------------------------------------------- ' VFO B is the active VFO. '----------------------------------------------------------------------- If bytValuePinD = 0 then '----------------------------------------------------------------------- ' Tuning is DOWN frequency. '----------------------------------------------------------------------- lonDDSBCommand = lonDDSBCommand - lonStepN lonBFreq = lonBFreq - lonFreqChange Else '----------------------------------------------------------------------- ' Tuning is UP frequency. '----------------------------------------------------------------------- lonDDSBCommand = lonDDSBCommand + lonStepN lonBFreq = lonBFreq + lonFreqChange End If Call LoadDDS(lonDDSBCommand , lonRITOffsetN) Call ShowFreq(lonBFreq , lonRITOffsetF) End If config INT0 = Rising bytINT0Trigger = conTriggerRising End If bytInt0Flag = conOFF Enable Int0 GoTo MainLoop '======================================================================= DoInt1: ' Process interrupt 1 - RIT knob has been turned '======================================================================= '----------------------------------------------------------------------- ' Disable interrupt 1 first. '----------------------------------------------------------------------- Disable Int1 '----------------------------------------------------------------------- ' The Int1Handler is enabled ONLY when RIT is ON. '----------------------------------------------------------------------- ' The RIT change knob has been turned, producing interrupt 1. ' ' If INT1 trigger is Falling: ' B = 0 is CCW, B = 1 is CW ' ' The RIT incremental change is limited to 10 hz per interrupt ' with a maximum of +/- 2khz from the active VFO. RIT offset ' is applied ONLY to the active VFO. Changing VFO's while RIT ' is ON will apply the RIT offset to the newly selected active VFO. '----------------------------------------------------------------------- If bytINT1Trigger = conTriggerRising then '----------------------------------------------------------------------- ' Interrupt triggered on the rising edge of phase A. ' phase B = 0 is CW, phase B = 1 is CCW '----------------------------------------------------------------------- If bytValuePinD = 0 then '----------------------------------------------------------------------- ' Tuning is UP frequency. '----------------------------------------------------------------------- lonRITOffsetN = lonRITOffsetN + conRITChange lonRITOffsetF = lonRITOffsetF + conRITFChange If lonRITOffsetN > conRITMaxNUP then lonRITOffsetN = conRITMaxNUP lonRITOffsetF = conRITMaxFUP End IF Else '----------------------------------------------------------------------- ' Tuning is DOWN frequency. '----------------------------------------------------------------------- lonRITOffsetN = lonRITOffsetN - conRITChange lonRITOffsetF = lonRITOffsetF - conRITFChange If lonRITOffsetN < conRITMaxNDOWN then lonRITOffsetN = conRITMaxNDOWN lonRITOffsetF = conRITMaxFDOWN End IF End if config INT1 = Falling bytINT1Trigger = conTriggerFalling Else '----------------------------------------------------------------------- ' Interrupt triggered on the falling edge of phase A. ' phase B = 0 is CCW, phase B = 1 is CW '----------------------------------------------------------------------- If bytValuePinD = 0 then '----------------------------------------------------------------------- ' Tuning is DOWN frequency. '----------------------------------------------------------------------- lonRITOffsetN = lonRITOffsetN - conRITChange lonRITOffsetF = lonRITOffsetF - conRITFChange If lonRITOffsetN < conRITMaxNDOWN then lonRITOffsetN = conRITMaxNDOWN lonRITOffsetF = conRITMaxFDOWN End IF Else '----------------------------------------------------------------------- ' Tuning is UP frequency. '----------------------------------------------------------------------- lonRITOffsetN = lonRITOffsetN + conRITChange lonRITOffsetF = lonRITOffsetF + conRITFChange If lonRITOffsetN > conRITMaxNUP then lonRITOffsetN = conRITMaxNUP lonRITOffsetF = conRITMaxFUP End IF End if config INT1 = Rising bytINT1Trigger = conTriggerRising End If '----------------------------------------------------------------------- ' Apply to the ACTIVE VFO ONLY. '----------------------------------------------------------------------- If strActiveVFO = "A" then Call LoadDDS(lonDDSACommand , lonRITOffsetN) Call ShowFreq(lonAFreq , lonRITOffsetF) Else Call LoadDDS(lonDDSBCommand , lonRITOffsetN) Call ShowFreq(lonBFreq , lonRITOffsetF) End If Call ShowRIT(bytRIT , lonRITOffsetF) bytInt1Flag = conOFF Enable Int1 GoTo MainLoop '======================================================================= PreampPressed: 'The Pre-Amp toggle button has been Pressed. '======================================================================= '----------------------------------------------------------------------- ' Toggles the preamp ON and OFF. '----------------------------------------------------------------------- If bytPreAmp = conOFF then bytPreAmp = conON Call SetPreamp Else bytPreAmp = conOFF Call ResetAll Call SetRelay(bytAGC , bytAF , bytPreAmp) End If Call ShowPreAmp(bytPreAmp) GoTo MainLoop '======================================================================= RITPressed: 'The RIT toggle button has been Pressed. '======================================================================= '----------------------------------------------------------------------- ' Whenever the RIT button is pressed, default the RIT offset to 0. ' If RIT has been turned ON, enable interrupt 1. '----------------------------------------------------------------------- If bytRIT = conOFF then bytRIT = conON enable INT1 Else bytRIT = conOFF disable INT1 End IF lonRITOffsetN = 0 lonRITOffsetF = 0 If strActiveVFO = "A" then Call LoadDDS(lonDDSACommand , lonRITOffsetN) Call ShowFreq(lonAFreq , lonRITOffsetF) Else Call LoadDDS(lonDDSBCommand , lonRITOffsetN) Call ShowFreq(lonBFreq , lonRITOffsetF) End If '----------------------------------------------------------------------- ' Display the RIT status. '----------------------------------------------------------------------- Call ShowRIT(bytRIT , lonRITOffsetF) GoTo MainLoop '======================================================================= SplitPressed: 'The SPLIT button has been pressed. '======================================================================= '----------------------------------------------------------------------- ' Enable split operation with the active VFO as the receive and ' the other VFO as the transmit. When the split button is pressed, ' the current inactive VFO operating frequency is set equal to the ' active VFO operating frequency. '----------------------------------------------------------------------- If bytSplit = conOFF then bytSplit = conON if strActiveVFO = "A" then lonDDSBCommand = lonDDSACommand lonBFreq = lonAFreq end if if strActiveVFO = "B" then lonDDSACommand = lonDDSBCommand lonAFreq = lonBFreq end if Else bytSplit = conOFF End If '----------------------------------------------------------------------- ' Now display it on the LCD. '----------------------------------------------------------------------- Call ShowVFO(strActiveVFO , bytSplit) GoTo MainLoop '======================================================================= StepPressed: 'The frequency step button has been Pressed. '======================================================================= '----------------------------------------------------------------------- ' Adjust the step change value. Changes are ' bytStepChange = 0 10hz (default) ' bytStepChange = 1 100hz ' bytStepChange = 2 1khz '----------------------------------------------------------------------- Incr bytStepChange If bytStepChange > 2 then bytStepChange = 0 end if Select Case bytStepChange Case 0: lonStepN = conStep10hz lonFreqChange = conFreq10hz Case 1: lonStepN = conStep100hz lonFreqChange = conFreq100hz Case 2: lonStepN = conStep1000hz lonFreqChange = conFreq1000hz End Select '----------------------------------------------------------------------- ' Display the curent step status. '----------------------------------------------------------------------- Call ShowStep(bytStepChange) GoTo MainLoop '======================================================================= XMIT: 'Transmit mode. '======================================================================= '----------------------------------------------------------------------- ' Disable the interrupts. Disables the changing of RIT and ' tuning during transmit mode. '----------------------------------------------------------------------- Disable Int0 Disable Int1 '----------------------------------------------------------------------- ' Show Transmit mode on the display. '----------------------------------------------------------------------- bytTR = conON call ShowTR(bytTR) '----------------------------------------------------------------------- ' The ACTIVE VFO is always the receive VFO. If split operation is ' ON, the inactive VFO is the transmit VFO. Notice - no RIT offset ' is used. '----------------------------------------------------------------------- If bytSplit = conON then '----------------------------------------------------------------------- ' SPLIT is active in this section. Use the transmit VFO. '----------------------------------------------------------------------- If strActiveVFO = "A" then Call LoadDDS(lonDDSBCommand , lonRITNoOffset) Call ShowFreq(lonBFreq , lonRITNoOffset) Else Call LoadDDS(lonDDSACommand , lonRITNoOffset) Call ShowFreq(lonAFreq , lonRITNoOffset) End If Else '----------------------------------------------------------------------- ' SPLIT is not active in this section. Use the receive VFO. '----------------------------------------------------------------------- If strActiveVFO = "A" then Call LoadDDS(lonDDSACommand , lonRITNoOffset) Call ShowFreq(lonAFreq , lonRITNoOffset) Else Call LoadDDS(lonDDSBCommand , lonRITNoOffset) Call ShowFreq(lonBFreq , lonRITNoOffset) End If End If '======================================================================= XMIT1: 'Wait for receive mode '======================================================================= '----------------------------------------------------------------------- ' WAIT until the transceiver enters receive mode. '----------------------------------------------------------------------- Bitwait aliRecVolts , Set If strActiveVFO = "A" then Call LoadDDS(lonDDSACommand , lonRITOffsetN) Call ShowFreq(lonAFreq , lonRITOffsetF) Else Call LoadDDS(lonDDSBCommand , lonRITOffsetN) Call ShowFreq(lonBFreq , lonRITOffsetF) End If '----------------------------------------------------------------------- ' Enable the interrupts. '----------------------------------------------------------------------- Enable Int0 If bytRIT = conON then Enable Int1 '----------------------------------------------------------------------- ' Show Receive mode on the display. '----------------------------------------------------------------------- bytTR = conOFF Call ShowTR(bytTR) GoTo MainLoop '======================================================================= ' [ INTERRUPT HANDLERS ] '======================================================================= '======================================================================= Int0Handler: 'INT 0 handler '======================================================================= '----------------------------------------------------------------------- ' The tuning knob has been turned, generating interrupt 0. ' Very little work is done in the handler. The primary work ' is performed in DoINT0. '----------------------------------------------------------------------- bytValuePinD = PinD 'input port D bytValuePinD = bytValuePinD and $01 'bit 0 ONLY - phase B bytInt0Flag = conOn Return '======================================================================= Int1Handler: 'INT 1 handler '======================================================================= '----------------------------------------------------------------------- ' Process the turning of the RIT knob ONLY if RIT is enabled. '----------------------------------------------------------------------- If bytRIT = conON then bytValuePinD = PinD 'input port D bytValuePinD = bytValuePinD and $02 'bit 1 ONLY - phase B bytInt1Flag = conOn Else bytInt1Flag = conOFF End If Return '======================================================================= ' [ SUBROUTINES ] '======================================================================= '======================================================================= SUB GetBand(valBand as byte) '======================================================================= '----------------------------------------------------------------------- ' Read the BPF band module selection bits. B.4..B.7 '----------------------------------------------------------------------- valBand = PinB 'get port B input pin value valBand = valBand And &HF0 'upper 4 bits only valBand = valBand Xor &HF0 'invert the bits valBand = valBand / 16 'move upper byte to lower byte End SUB '======================================================================= Sub GetN(valBand as Byte , valFreq_N_Data as Long , valAFreq as Long) '======================================================================= Dim strBandMessage as string * 4 '----------------------------------------------------------------------- ' Depending on the operating band, provide N. Using an EXCEL ' spreadsheet and the AD9850 data sheet, these values for N produce ' operating frequencies that are "close" to the default band QRP ' frequencies. ' ' N is the value fed to the DDS chip to determine the DDS generated ' output frequency and is equal to: ' INT((Operating Freq/DDS Xtal Freq) * 2^32) ' ' For bands 1 - 7, the output frequency is: ' Operating Frequency + IF ' For bands 8 - 9, the output frequency is: ' Operating Frequency - IF '----------------------------------------------------------------------- Select Case valBand Case 1 : valFreq_N_Data = 288780006 '160 meters strBandMessage = "160m" valAFreq = 1810000 Case 2 : '80 meters valFreq_N_Data = 363941414 strBandMessage = " 80m" valAFreq = 3560000 Case 3 : '40 meters valFreq_N_Data = 513405242 strBandMessage = " 40m" valAFreq = 7040000 Case 4 : '30 meters valFreq_N_Data = 645259536 strBandMessage = " 30m" valAFreq = 10110000 Case 5 : '20 meters valFreq_N_Data = 814909439 strBandMessage = " 20m" valAFreq = 14060000 Case 6 : '17 meters valFreq_N_Data = 988253540 strBandMessage = " 17m" valAFreq = 18096000 Case 7 : '15 meters valFreq_N_Data = 693473077 strBandMessage = " 15m" valAFreq = 21060000 Case 8 : '12 meters valFreq_N_Data = 858655946 strBandMessage = " 12m" valAFreq = 24906000 Case 9 : '10 meters valFreq_N_Data = 994118707 strBandMessage = " 10m" valAFreq = 28060000 Case else : valFreq_N_Data = 0 strBandMessage = "BAD " valAFreq = 0 End Select Locate 2 , 1 LCD strBandMessage End SUB '======================================================================= SUB LoadDDS(valDDS_Command as long , valRIT_Offset_N as long) '======================================================================= Dim bytWork As Byte Dim lngWork As Long '----------------------------------------------------------------------- ' Sends the 40 bit command to the DDS. '----------------------------------------------------------------------- bytWork = 0 '----------------------------------------------------------------------- ' DDS_Command contains the LONG value for the DDS output frequency. '----------------------------------------------------------------------- lngWork = valDDS_Command + valRIT_Offset_N Shiftout aliDDSData , aliDDSClock , lngWork , 3 , 32 , 1 Shiftout aliDDSData , aliDDSClock , bytWork , 3 , 8 , 1 Set aliDDSLoad ' Waitus 10 Reset aliDDSLoad End SUB '======================================================================= SUB ResetAll() '======================================================================= '----------------------------------------------------------------------- ' RESET all relays. ' GND on relay pin 1, +5V on relay pin 10. '----------------------------------------------------------------------- '----------------------------------------------------------------------- ' Set all output pins (+5V on relay pin 1) ON. '----------------------------------------------------------------------- Set aliAFOut Set aliAGCOut Set aliPreampOut '----------------------------------------------------------------------- ' Set the relay common line (+5V on relay pin 10) ON. '----------------------------------------------------------------------- Set aliRelayCommon '----------------------------------------------------------------------- ' Reset each relay output pint (GND on relay pin 1) and hold it ' for 5 msec. '----------------------------------------------------------------------- Reset aliAFOut Waitms 5 Set aliAFOut Reset aliAGCOut Waitms 5 Set aliAGCOut Reset aliPreampOut Waitms 5 Set aliPreampOut '----------------------------------------------------------------------- ' Set the relay common line OFF. '----------------------------------------------------------------------- Reset aliRelayCommon '----------------------------------------------------------------------- ' Set the relay output line OFF. '----------------------------------------------------------------------- Reset aliAFOut Reset aliAGCOut Reset aliPreampOut End SUB '======================================================================= SUB SetAF() '======================================================================= '----------------------------------------------------------------------- ' Set the audio filter relay. '----------------------------------------------------------------------- Set aliAFOut Waitms 5 Reset aliAFOut End SUB '======================================================================= SUB SetAGC() '======================================================================= '----------------------------------------------------------------------- ' Set the AGC relay. '----------------------------------------------------------------------- Set aliAGCOut Waitms 5 Reset aliAGCOut End SUB '======================================================================= SUB SetPreamp() '======================================================================= '----------------------------------------------------------------------- ' Set the pre-amp relay. '----------------------------------------------------------------------- Set aliPreampOut Waitms 5 Reset aliPreampOut End SUB '======================================================================= SUB SetRelay(valAGC as byte , valAF as byte , valPreAmp as byte) '======================================================================= '----------------------------------------------------------------------- ' Depending on the value, set the appropriate relay. '----------------------------------------------------------------------- If valAGC = conON then Call SetAGC End If If valAF = conON then Call SetAF End If If valPreAmp = conON then Call SetPreamp End If End SUB '======================================================================= SUB ShowAGC(valAGC as Byte) '======================================================================= Dim strWorkAGC As String * 1 '----------------------------------------------------------------------- ' Display the AGC setting. DEFAULT is ON. '----------------------------------------------------------------------- strWorkAGC = "A" If valAGC = 0 then strWorkAGC = " " End If Locate 1 , 19 Lcd strWorkAGC End SUB '======================================================================= SUB ShowAF(valAF as Byte) '======================================================================= Dim strWorkAF As String * 1 '----------------------------------------------------------------------- ' Display the audio filter status. DEFAULT is OFF. '----------------------------------------------------------------------- strWorkAF = " " If valAF = 1 then strWorkAF = "F" End If Locate 1 , 20 Lcd strWorkAF End SUB '======================================================================= SUB ShowFreq(valFreq as Long , valOffset as Long) '======================================================================= Dim lonWork as Long lonWork = valFreq + valOffset '----------------------------------------------------------------------- ' Display the vfo operating frequency. '----------------------------------------------------------------------- Locate 1 , 1 Lcd lonWork End SUB '======================================================================= SUB ShowPreAmp(valPreAmp as Byte) '======================================================================= Dim strWorkPAmp As String * 1 '----------------------------------------------------------------------- ' Display the preamp status. DEFAULT is ON. '----------------------------------------------------------------------- strWorkPAmp = "P" If valPreAmp = 0 then strWorkPAmp = " " End If Locate 1 , 18 Lcd strWorkPAmp End SUB '======================================================================= SUB ShowRIT(valRIT as Byte , valRIT_Offset as Long) '======================================================================= Dim strWorkRIT As String * 9 Dim lngWorkRIT as Long '----------------------------------------------------------------------- ' Display the RIT status. ' Is RIT enabled? If not, no display and exit. '----------------------------------------------------------------------- If valRIT = conOFF Then strWorkRIT = "RIT: Off " Locate 2 , 12 Lcd strworkRIT exit SUB End If '----------------------------------------------------------------------- ' At this point, RIT is enabled. ' ' Is the offset up or down? Put the sign in the string. '----------------------------------------------------------------------- strWorkRIT = "RIT:" Select Case valRIT_Offset Case is = 0: strWorkRIT = strWorkRIT + " " Case is > 0: strWorkRIT = strWorkRIT + "+ " Case is < 0: strWorkRIT = strWorkRIT + "- " End Select Locate 2 , 12 LCD strWorkRIT '----------------------------------------------------------------------- ' Leading spaces, depending on the value. '----------------------------------------------------------------------- lngWorkRIT = abs(valRIT_Offset) strWorkRIT = str(lngWorkRIT) Select Case lngWorkRIT Case is >= 2000: strWorkRIT = "2000" Case is < 1000: strWorkRIT = str(lngWorkRIT) + " " Case is < 100: strWorkRIT = str(lngWorkRIT) + " " End Select Locate 2 , 17 Lcd strWorkRIT End SUB '======================================================================= SUB ShowStats(valAF as Byte , valAGC as Byte , valPreAmp as Byte , _ valRIT as Byte , valRIT_Offset as Long , valVFO as string , _ valSplit as Byte , valStep as Byte , valTR as Byte) '======================================================================= '----------------------------------------------------------------------- ' Display all of the radio information on the LCD Display. '----------------------------------------------------------------------- Call ShowVFO(valVFO , valSplit) Call ShowPreAmp(valPreAmp) Call ShowAGC(valAGC) Call ShowAF(valAF) Call ShowStep(valStep) Call ShowRIT(valRIT , valRIT_Offset) call ShowTR(valTR) End SUB '======================================================================= SUB ShowStep(valStep as Byte) '======================================================================= Dim strWorkSTEP As String * 3 '----------------------------------------------------------------------- ' Depending on the value of valStep, select the frequency change ' value for each interrupt 0. valStep has values of 0 (10 hz), ' 1 (100 hz), or 2 (1 khz) '----------------------------------------------------------------------- Select Case valStep Case 0: strWorkSTEP = " 10" Case 1: strWorkSTEP = "100" Case 2: strWorkSTEP = " 1k" End Select Locate 1 , 14 Lcd strWorkSTEP End SUB '======================================================================= SUB ShowTR(valTR as Byte) '======================================================================= Dim strWorkTR As String * 1 '----------------------------------------------------------------------- ' valTR indicates Receive (0) or Transmit (1) mode. '----------------------------------------------------------------------- If valTR = 0 then strWorkTR = "R" Else strWorkTR = "T" End If Locate 2 , 5 Lcd strWorkTR End SUB '======================================================================= SUB ShowVFO(valVFO as String , valSplit as Byte) '======================================================================= Dim strWorkVFO as string * 3 '----------------------------------------------------------------------- ' Display the SPLIT status on the LCD. valVFO is the ACTIVE ' VFO. '----------------------------------------------------------------------- If valSplit = conOFF then strWorkVFO = valVFO + " " Locate 1 , 10 LCD strWorkVFO exit sub End If '----------------------------------------------------------------------- ' SPLIT is ON. Show the ACTIVE VFO : InACTIVE VFO. '----------------------------------------------------------------------- If valVFO = "A" then strWorkVFO = "A:B" Else strWorkVFO = "B:A" End If Locate 1 , 10 Lcd strWorkVFO End SUB END '======================================================================= ' [ Data TABLES ] '======================================================================= '======================================================================= ' END MP+Rev Jay Program '=======================================================================