SAA1057 PLL Synth code-Can it be improved/tidied up?

djsb

New Member
I have found this code that drives a SAA1057 PLL synthesizer chip.

Code:
'saa1057 pll
'by fdu@home.nl
'programed with pic simulator ide 7.37
'pic16f628
'------------------
'discription of ports pic to saa
'portb.4 = pin10 = clb > pin14 saa
'portb.5 = pin11 = dlen > pin13 saa
'portb.6 = pin12 = data > pin12 saa
'porta.4 = pin 3 = lock > pin18 saa

Define CONF_WORD = 0x3f41
Define CLOCK_FREQUENCY = 4

AllDigital
'port =  76543210
TRISA = %11111011
TRISB = %00000000

PORTB.7 = 1  'highpower off (1=off / 0=on)
PORTB.4 = 0
PORTB.5 = 0
PORTB.6 = 0

Dim data(15) As Byte
Dim tlr As Byte
Dim deler As Word
Dim deler1 As Word
deler = 0
deler1 = 32768

Dim freq As Word
Dim freq1 As Word
Dim freqhun As Byte
Dim freqten As Byte

Dim ht As Byte

'--- lcd ini ---
Define LCD_LINES = 2
Define LCD_CHARS = 16
Define LCD_BITS = 4
Define LCD_DREG = PORTB
Define LCD_DBIT = 0
Define LCD_RSREG = PORTA
Define LCD_RSBIT = 2
Define LCD_EREG = PORTA
Define LCD_EBIT = 3
Lcdinit 0

'---- firstime on ----
Read 0, freqhun
If freqhun < 87 Or freqhun > 108 Then
    freqhun = 87
    Write 0, freqhun
    freqten = 50
    Write 1, freqten
Endif
Read 1, freqten

freq1 = freqhun * 100 + freqten


'--- tube heater ----
Lcdcmdout LcdLine1Pos(1)
Lcdout "Tube oscillator"
Lcdcmdout LcdLine2Pos(1)
Lcdout "Heater warmup"

For ht = 59 To 0 Step -1

Lcdcmdout LcdLine2Pos(15)
Lcdout #ht
If ht < 10 Then Lcdout " ", #ht
WaitMs 990
Next ht
Lcdcmdout LcdClear
PORTB.7 = 0  'highpower on 0=on/1=off



'----- ten pulses saa1057 initialisering -----
For tlr = 0 To 9
Gosub routine
Next tlr
WaitMs 1

'----- program latch B -----
PORTB.5 = 1  'DLEN = 1 > start sending
Gosub routine  '0-1-0 > 1st clb

PORTB.6 = 1  '0 > latch B
Gosub routine
PORTB.6 = 1  '1 > FM (put to 0 for am input)
Gosub routine
PORTB.6 = 0  '2 > REFH >10KHz
Gosub routine
PORTB.6 = 0  '3 > CP3 = 0
Gosub routine
PORTB.6 = 1  '4 > CP2 = 1 >pca=0.7V
Gosub routine
PORTB.6 = 1  '5 > CP1 = 1 >pca=0.7V
Gosub routine
PORTB.6 = 0  '6 > CP0 = 0
Gosub routine
PORTB.6 = 1  '7 > SB2 > 1 for programming next 8 bits
Gosub routine
PORTB.6 = 1  '8 > SLA > synchronous latch mode
Gosub routine
PORTB.6 = 0  '9 > PDM1 >phase detector auto
Gosub routine
PORTB.6 = 0  '10 > PDM0 >phase detector auto
Gosub routine
PORTB.6 = 1  '11 > BRM >current switched on (T1,2,3)
Gosub routine
PORTB.6 = 0  '12 > T3 > must be 0!
Gosub routine
PORTB.6 = 1  '13 > T2 > lock output
Gosub routine
PORTB.6 = 0  '14 > T1 > must be 0!
Gosub routine
PORTB.6 = 1  '15 > T0 > lock output
Gosub routine
PORTB.6 = 0

PORTB.5 = 0  'stop sending
Gosub routine  '18th clb
'---- end of ini latch B ----



'----- main ----
main:

freq = freq1

'----- convert dec to bin -----

'data(0) = 16384
'data(1) = 8192
'data(2) = 4096
'data(3) = 2048
'data(4) = 1024
'data(5) = 512
'data(6) = 256
'data(7) = 128
'data(8) = 64
'data(9) = 32
'data(10) = 16
'data(11) = 8
'data(12) = 4
'data(13) = 2
'data(14) = 1

For tlr = 0 To 14

If freq <= deler1 Then
freq = freq - deler
data(tlr) = 1
Endif
If freq > deler Then
freq = freq + deler
data(tlr) = 0
Endif

deler1 = deler1 / 2
deler = deler1 / 2

Next tlr
deler1 = 32768


'---- freq. output to saa1057 latch A ------
PORTB.5 = 1  'DLEN = 1 > start sending
Gosub routine  '0-1-0 > clb
PORTB.6 = 0  'latch A
Gosub routine  '0-1-0

'-- programming bits ---
For tlr = 0 To 14

If data(tlr) = 1 Then PORTB.6 = 1 Else PORTB.6 = 0
Gosub routine

Next tlr
PORTB.6 = 0

PORTB.5 = 0  'stop sending
Gosub routine
'----- end of programming latch A -----


loop:

'---- freq on display ---
If freqhun < 100 Then
Lcdcmdout LcdLine1Pos(1)
Lcdout " ", #freqhun
Endif
If freqhun >= 100 Then
Lcdcmdout LcdLine1Pos(1)
Lcdout #freqhun
Endif

If freqten < 10 Then
Lcdcmdout LcdLine1Pos(4)
Lcdout ".0", #freqten
Endif
If freqten >= 10 Then
Lcdcmdout LcdLine1Pos(4)
Lcdout ".", #freqten
Endif

Lcdcmdout LcdLine1Pos(7)
Lcdout "MHz"


'----- freq up -----
If PORTA.1 = 0 Then
    freq1 = freq1 + 5
    freqten = freqten + 5
    If freqten >= 100 Then
        freqten = 0
        freqhun = freqhun + 1
    Endif
    If freq1 > 10800 Then
        freq1 = 10800
        freqten = 0
        Goto main
    Endif
    Write 0, freqhun
    Write 1, freqten
    Goto main
Endif

'----- freq down -----
If PORTA.0 = 0 Then
    freq1 = freq1 - 5
    If freq1 < 8750 Then
        freq1 = 8750
        Goto main
    Endif
    freqten = freqten - 5
    If freqten > 250 Then
        freqten = 95
        freqhun = freqhun - 1
    Endif
    Write 0, freqhun
    Write 1, freqten
    Goto main
Endif

'----- read lock ----
If PORTA.4 = 1 Then
Lcdcmdout LcdLine1Pos(11)
Lcdout "  lock"
Endif
If PORTA.4 = 0 Then
Lcdcmdout LcdLine1Pos(11)
Lcdout "NOlock"
Endif

Goto loop


End                                              

'----- clb routine > 0-1-0  -----
routine:
WaitMs 1
PORTB.4 = 0
WaitMs 1
PORTB.4 = 1
WaitMs 1
PORTB.4 = 0
WaitMs 1
Return

I'm wondering if this code can be improved for clarity anywhere. For instance, can an alias be used for PORTB.4 which is used for the clock pin clb for example. It was also written quite a while ago and maybe there have been some improvements/enhancements in more recent compiler versions. Also does

Code:
'---- firstime on ----

Read 0, freqhun

If freqhun < 87 Or freqhun > 108 Then

    freqhun = 87

    Write 0, freqhun

    freqten = 50

    Write 1, freqten

Endif

Read 1, freqten

Involve writing and reading from the PIC's INTERNAL eeprom? If so, I wonder how this code works? Just started learning basic, so it doesn't seem obvious at the moment. I can post the data sheet of the SAA1057 if it would help. Thanks.
 
Last edited:
According to the program header, it is version 7.37 of the IDE, so the code could be from 2015. Of course, it is easier to understand the code using aliases. But have you tested if it works?.

Read and Write are commands used to manage the internal EEprom, they are old but new versions must have compatibility with them according to the language manual. EEPROM_Write and EEPROM_Read are now used.
 
Not tested on hardware yet, as it's quite complex to set up. I'm going to try learning to use the simulator first. Can the internal EEPROM reads and writes be simulated? Is there some kind of waveform viewer to see the timing of transitions on each pin? That would be useful.
 
Yes, I am simulating it and I am seeing the display, the variables, pins and the EEPROM values on the screen. In the simulator it scans the FM frequencies shown on the display.
 
I suppose it could be improved, but I wouldn't modify it before testing it in reality. This way, if it stops working, you can undo the latest modifications until it works to your liking.
 
Last edited:
Cookies are required to use this site. You must accept them to continue using the site. Learn more…