Refined this a bit, thanks a mil to those, knowingly and unknowingly, that pointed me in the right direction.
Code: Select all
' A simple program to enable KeyPad control of an AD9832/9835 DDS
' 16X2 Lcd on Port B, DDS on Port C, KeyPad on Port D
' Default startup values in eeprom, 1 MHz out, for 24 MHz Clock
' Standard mikroElektronika connections as per EasyPic3 Board apply,
' using Pic 16F877A.
' RA0 switches display to frequency entry, RA1 changes clock value
' Both pins are normally pulled high, switches when pulled low
' KeyPad "*" deletes last keypress only, "#" writes new values to eeprom
' DDS PSEL0, PSEL1, FSELECT GROUNDED
' Hardware SPI function of Pic used
'
' MANY thanks to Sorcerer and Xor, who freely gives of their code....
program meBasicAD9832ver1
include "Print_Dec_16" ' Xor's lcd print utility
symbol delay50 = Delay_ms(50)
symbol delay500 = Delay_ms(500)
Dim frequency, xtal, cfreq, KeyInput,KeyInputOld as longint
dim Key,Key1 as byte
dim myvar as string[11]
'Map 4*4 KeyPad to ascii
const KeyPad as byte[16] = (49, 50, 51, 65,
52, 53, 54, 66,
55, 56, 57, 67,
42, 48, 35, 68)
sub procedure Welcome ' Welcome Message
dim I as byte
lcd_cmd(LCD_CURSOR_OFF)
lcd_cmd(lcd_clear)
lcd_out(1, 4, "gkSolutions")
lcd_out(2,2,"DDS Synthesizer")
For I = 0 to 3
Delay500
Next I
lcd_cmd(lcd_clear) ' Message Ends
end sub
sub function eread01(dim eeprom_addr, offset as byte) as longint
' eeprom_addr = 0 'Is this nessary?
For offset = 0 to 3
FSR = @ frequency + offset
INDF = EEPROM_READ(eeprom_addr + offset)
Next offset
result = frequency
delay50
end sub
sub function eread02(dim eeprom_addr, offset as byte) as longint
' eeprom_addr = 16
For offset = 0 to 3
FSR = @ xtal + offset
INDF = EEPROM_READ(eeprom_addr + offset)
Next offset
result = xtal
delay50
end sub
sub procedure lcdwrite01(dim yy as longint)
Lcd_Cmd(LCD_CLEAR) ' Clear display
Lcd_Cmd(LCD_CURSOR_OFF) ' Cursor off
' print_dec(yy*16,"###.######",RJZ,myvar) ' For FM Version
print_dec(yy,"##.######",RJZ,myvar) ' For Straight Version
Lcd_Out(1, 4, "gkSolutions")
Lcd_Out(2,3,myvar)
Lcd_Out(2,13,"MHz")
delay500
end sub
sub function CalcFreq(dim f, x as longint) as longint
dim g as float
g = ( f / x ) * $7FFFFFFF
result = longint(g) * 2
delay50
end sub
'sub procedure ddswrite(dim f as longint) ' Hardware SPI, I HAD to play !
' eread01(0, 0)
' delay50
' eread02(16, 0)
' delay50
' cfreq = CalcFreq(frequency, xtal)
' delay50
' TRISC = TRISC and $FD
' ClearBit(PORTC,1) 'Sync low enable write
' Spi_Write($F8) 'Setup AD9832 for writing
' Spi_Write($00) 'Just padding.......
' Spi_Write($33) 'Write High MSB into register $33
' Spi_Write(highest(f))
' Spi_Write($22) 'Write Low MSB into register $22
' Spi_Write(higher(f))
' Spi_Write($31) 'Write High LSB into register $31
' Spi_Write(hi(f))
' Spi_Write($20) 'Write Low LSB into register $20
' Spi_Write(lo(f))
' Spi_Write($C0) 'Enable AD9832 for transmit
' Spi_Write($00) 'Just padding.......
' SetBit(PORTC,1) 'Sync high disable write
' delay50
' lcdwrite01(frequency)
' delay50
'end sub
sub procedure ddswrite(dim f as longint) ' Soft SPI, ditto :-)
eread01(0, 0)
delay50
eread02(16, 0)
delay50
cfreq = CalcFreq(frequency, xtal)
delay50
TRISC = TRISC and $FD
ClearBit(PORTC,1) 'Sync low enable write
Soft_Spi_Write($F8) 'Setup AD9832 for writing
Soft_Spi_Write($00) 'Just padding.......
Soft_Spi_Write($33) 'Write High MSB into register $33
Soft_Spi_Write(highest(f))
Soft_Spi_Write($22) 'Write Low MSB into register $22
Soft_Spi_Write(higher(f))
Soft_Spi_Write($31) 'Write High LSB into register $31
Soft_Spi_Write(hi(f))
Soft_Spi_Write($20) 'Write Low LSB into register $20
Soft_Spi_Write(lo(f))
Soft_Spi_Write($C0) 'Enable AD9832 for transmit
Soft_Spi_Write($00) 'Just padding.......
SetBit(PORTC,1) 'Sync high disable write
delay50
lcdwrite01(frequency)
delay50
end sub
sub procedure ewrite(dim xx as longint)
Eeprom_Write(0, lo(xx))
delay50
Eeprom_Write(1, hi(xx))
delay50
Eeprom_Write(2, higher(xx))
delay50
Eeprom_Write(3, highest(xx))
delay50
end sub
sub procedure ewrite2(dim xx as longint)
Eeprom_Write(16, lo(xx))
delay50
Eeprom_Write(17, hi(xx))
delay50
Eeprom_Write(18, higher(xx))
delay50
Eeprom_Write(19, highest(xx))
delay50
end sub
sub Procedure Need_Input01 'Original routine from Sorcerer
Lcd_cmd(lcd_clear)
Lcd_Out(1, 4, "Freq in MHz")
Lcd_Out(2, 3, "Enter with #")
Key1 = 0
KeyInput=0
KeyInputOld=0
While Key1<>35 ' Exit on #
Key=0
while Key = 0
Key = Keypad_Released
Wend
Key1=KeyPad[Key-1]
If Key1=42 Then '* = delete (last input only!)
KeyInput=KeyInputOld
End If
If (Key1 > 47) and (Key1 < 58) then '0-9 are added in, anything else ignored
KeyInputOld = KeyInput
KeyInput = KeyInput * 10
KeyInput = KeyInput + Key1 - 48
End If
' print_dec(keyinput,"###.######",RJZ,myvar) ' For FM Version
print_dec(keyinput,"##.######",RJZ,myvar) ' For Straight Version
Lcd_cmd(LCD_CURSOR_OFF)
Lcd_Out(2, 1," ")
Lcd_Out(2, 4, myvar)
delay50
Wend
' KeyInput = KeyInput div 16 ' Only For FM Version
ewrite(Keyinput)
delay50
ddswrite(cfreq) ' Can't explain why it needs TWO writes ?
delay50
ddswrite(cfreq)
delay50
end sub
sub Procedure Need_Input02 ' Fine Tune xtal Osc
Lcd_cmd(lcd_clear)
Lcd_Out(1, 1, "Xtal Freq in MHz")
Lcd_Out(2, 3, "Enter with #")
Key1 = 0
KeyInput=0
KeyInputOld=0
While Key1<>35 ' Exit on #
Key=0
while Key = 0
Key = Keypad_Released
Wend
Key1=KeyPad[Key-1]
If Key1=42 Then '* = delete (last input only!)
KeyInput=KeyInputOld
End If
If (Key1 > 47) and (Key1 < 58) then '0-9 are added in, anything else ignored
KeyInputOld = KeyInput
KeyInput = KeyInput * 10
KeyInput = KeyInput + Key1 - 48
End If
print_dec(keyinput,"##.######",RJZ,myvar)
Lcd_cmd(LCD_CURSOR_OFF)
Lcd_Out(2, 1," ") ' Cleans Line for next display
Lcd_Out(2, 4, myvar)
delay50
Wend
ewrite2(Keyinput)
delay50
ddswrite(Cfreq) ' Can't explain why it needs TWO writes ?
delay50
ddswrite(Cfreq)
delay50
end sub
main:
ADCON1 = 7
trisa = %11111111
' Spi_Init ' Required for Hardware SPI
Soft_Spi_Config(PortC,4, 5, 3) ' Required for Soft_SPI
Lcd_Init(PORTB)
Keypad_Init(PORTD)
Welcome
ddswrite (cfreq)
delay50
ddswrite(cfreq)
delay50
eloop:
if porta.0 = 0 then
Need_Input01
end if
if porta.1 = 0 then
Need_Input02
end if
goto eloop
end.