;=============================================================================== ; ; u_PLL 1.1.16F84 ; Ing. Mario Kienspergher ; OE9MKV ; ;------------------------------------------------------------------------------- ; ; Original Header follows: ; ; ;*************************************** ; ;*** U6223B u_pll - micro PLL *** ; ;*** Assembler AS (public domain) *** ; ;*************************************** ; ; CPU 16C54 ; ; ident macro ; DATA "u_PLL 1.1 08.03.96 DF1OG" ; endm ; ;=============================================================================== TITLE "PLL 1.1.16F84" LIST P=16F84A ;======================================= ;constant and storage definitions ;======================================= kc100_10l EQU 0AH ;100 kc binary conversion kc100_10h EQU 00H kc100_100l EQU 64H kc100_100h EQU 00H kc100_1000l EQU 0E8H kc100_1000h EQU 03H kc100_10000l EQU 10H kc100_10000h EQU 27H kc125_10l EQU 08H ;125 kc binary conversion kc125_10h EQU 00H kc125_100l EQU 50H kc125_100h EQU 00H kc125_1000l EQU 20H kc125_1000h EQU 03H kc125_10000l EQU 40H kc125_10000h EQU 1FH AdrByte EQU 0C2H ;pll address byte: device address open CtrlByte1 EQU 0C6H ;control byte 1: hi current, scale 512 CtrlByte2 EQU 00H ;control byte 2: hi impedance outputs ;======================================= ;Registers: ;======================================= Indirect EQU 00H ;virtual indirect register RTCC EQU 01H ;realtime clock/counter PClo EQU 02H ;program counter low Status EQU 03H ;status register FSR EQU 04H ;file select register Port_A EQU 05H ;port A Port_B EQU 06H ;port B ;--------------------------------------- ;Register flags / bits ;--------------------------------------- RP0 EQU 05H ; Bank Select Bit 0 RP1 EQU 06H ; Bank Select Bit 1 ;--------------------------------------- ;general purpose registers: ;--------------------------------------- R0 EQU 10H ;general purpose register 0 R1 EQU 11H ;general purpose register 1 R2 EQU 12H ;general purpose register 2 Kc100 EQU 13H ;frequency bcd values 100/125 kc Mc1 EQU 14H ; 1 mc Mc10 EQU 15H ; 10 mc Mc100 EQU 16H ; 100 mc Mc1000 EQU 17H ; 1000 mc Control EQU 18H ;bit 2 off 100 kc steps ; on 125 kc steps SwChange EQU 19H ;switch change check DevAdr EQU 1AH ;device address PDB1 EQU 1BH ;program divider byte 1 PDB2 EQU 1CH ;program divider byte 2 CB1 EQU 1DH ;control byte 1 CB2 EQU 1EH ;control byte 2 ;--------------------------------------- ;allocation status register flags: ;--------------------------------------- Flag_C EQU 00H ;carry flag Flag_DC EQU 01H ;digit carry flag Flag_Z EQU 02H ;zero flag ;--------------------------------------- ;destination register: ;--------------------------------------- w EQU 00H ;destination w register f EQU 01H ;destination f register ;=============================================================================== ;Code follows ;=============================================================================== ORG 000H Start: goto Init ;subroutines in first 256 code bytes ORG 004H ;forget about ISR RETURN ORG 008H ;subroutines within first 256 bytes ;--------------------------------------- ;scan switches ;--------------------------------------- ScanSw: movlw Kc100 ;set pointer to freq. registers movwf FSR movlw 05H ;five switches to scan movwf R0 movlw b'11111110' ;start with low significant switch movwf R1 ScanSw10: movf R1,w ;put scan information onto port movwf Port_B tris Port_B movf Port_B,w ;read scan information bits 0-2 andlw b'11100000' movwf Indirect swapf Indirect,f bcf Status,Flag_C rrf Indirect,f movf Port_A,w ;read scan information bit 3 movwf R2 rlf R2,w andlw b'00001000' iorwf Indirect,f ;combine bits to negative logic movlw b'00001111' xorwf Indirect,f bsf Status,Flag_C ;prepare next scan rlf R1,f incf FSR,f decfsz R0,f goto ScanSw10 ;all switches scaned? ScanSw99: retlw 0 ;--------------------------------------- ;set pll data using i2c protocol ;--------------------------------------- SetPLL: movlw DevAdr ;set pointer to pll data movwf FSR movlw 05H ;5 bytes have to be transfered movwf R0 movlw b'11111101' ;start condition tris Port_A nop nop nop movlw b'11111100' tris Port_A SetPLL10: movlw 08H ;set bit counter movwf R1 SetPLL20: rlf Indirect,f ;carry flag stores the bit btfsc Status,Flag_C goto SetPLL30 movlw b'11111100' ;set data low tris Port_A call ClkOut goto SetPLL40 SetPLL30: movlw b'11111110' ;set data high tris Port_A call ClkOut SetPLL40: decfsz R1,f goto SetPLL20 ;one byte transfered? movlw b'11111110' ;handle acknowledge tris Port_A call ClkOut rlf Indirect,f ;now all has left correctly again incf FSR,f ;set pointer to next byte decfsz R0,f goto SetPLL10 ;all bytes transfered? movlw b'11111100' ;stop condition tris Port_A movlw b'11111101' tris Port_A nop nop nop movlw b'11111111' tris Port_A SetPLL99: retlw 0 ;--------------------------------------- ClkOut: iorlw b'00000001' ;set clock high tris Port_A nop nop nop andlw b'11111110' ;set clock low tris Port_A retlw 0 ;--------------------------------------- SwChk: movlw -10 ;check for greater than nine addwf Indirect,w btfss Status,Flag_C goto SwChk99 movlw 9 ;if greater set to nine movwf Indirect SwChk99: retlw 0 ;--------------------------------------- AddPDB: movf R0,w ;do while not zero... btfsc Status,Flag_Z goto AddPDB99 movf R2,w ;add LSBs addwf PDB2,f btfsc Status,Flag_C incf PDB1,f ;add carry to MSB movf R1,w ;add MSBs addwf PDB1,f decf R0,f ;decrement loop count goto AddPDB ;loop... AddPDB99: retlw 0 ;--------------------------------------- DATA " * * * u _ P L L 1 . 1 0 8 . 0 3 . 9 6 D F 1 O G * * * " DATA " 1 . 1 . 1 6 F 8 4 1 5 . 0 7 . 0 2 O E 9 M K V * * *" ;======================================= ;start of main program... ;======================================= ORG 100H Init: bcf Status,RP0 ; select register bank 0 bcf Status,RP1 ; only for upward compability movlw b'11111100' ;prepare SDA and SCL ports movwf Port_A clrf Kc100 ;clear freq. registers clrf Mc1 clrf Mc10 clrf Mc100 clrf Mc1000 clrf Control clrf SwChange ;initiate freq. setting decf SwChange,f ;--------------------------------------- ;main program loop ;--------------------------------------- Main: call ScanSw ;scan switches ;--------------------------------------- movlw Mc1000 ;mask out 1000 mc movwf FSR movf Indirect,w movwf Control andlw b'00000011' ;bit 0-1 frequency movwf Indirect movlw b'00000100' ;bit 2 control andwf Control,f decf FSR,f ;check for valid BCD call SwChk ;100 mc decf FSR,f call SwChk ;10 mc decf FSR,f call SwChk ;1 mc decf FSR,f ;Kc100 mustn't exceed 9 at 100 kc btfsc Control,2 ;and mustn't exceed 7 at 125 kc steps goto Main10 call SwChk ;100 kc steps goto Main20 Main10: movlw -8 ;125 kc steps addwf Indirect,w btfss Status,Flag_C goto Main20 movlw 7 ;if greater than seven set to seven movwf Indirect ;--------------------------------------- Main20: movlw Kc100 ;check for switch change movwf FSR clrw ;add frequency and control values addwf Indirect,w ;100 kc incf FSR,f addwf Indirect,w ;1 mc incf FSR,f addwf Indirect,w ;10 mc incf FSR,f addwf Indirect,w ;100 mc incf FSR,f addwf Indirect,w ;1000 mc incf FSR,f addwf Indirect,w ;control incf FSR,f xorwf Indirect,f ;compare to old switch change check movwf Indirect ;store new change check btfsc Status,Flag_Z goto Main ;no change, back to main loop... ;--------------------------------------- clrf PDB1 ;convert 100/125 kc into binary format movf Kc100,w ;100/125 kc movwf PDB2 btfsc Control,2 ;100/125 kc steps? goto Main30 movf Mc1,w ;100 kc steps 1 mc movwf R0 movlw kc100_10h movwf R1 movlw kc100_10l movwf R2 call AddPDB movf Mc10,w ;10 mc movwf R0 movlw kc100_100h movwf R1 movlw kc100_100l movwf R2 call AddPDB movf Mc100,w ;100 mc movwf R0 movlw kc100_1000h movwf R1 movlw kc100_1000l movwf R2 call AddPDB movf Mc1000,w ;1000 mc movwf R0 movlw kc100_10000h movwf R1 movlw kc100_10000l movwf R2 call AddPDB goto Main40 Main30: movf Mc1,w ;125 kc steps 1 mc movwf R0 movlw kc125_10h movwf R1 movlw kc125_10l movwf R2 call AddPDB movf Mc10,w ;10 mc movwf R0 movlw kc125_100h movwf R1 movlw kc125_100l movwf R2 call AddPDB movf Mc100,w ;100 mc movwf R0 movlw kc125_1000h movwf R1 movlw kc125_1000l movwf R2 call AddPDB movf Mc1000,w ;1000 mc movwf R0 movlw kc125_10000h movwf R1 movlw kc125_10000l movwf R2 call AddPDB ;--------------------------------------- Main40: movlw AdrByte ;load pll parameter movwf DevAdr movlw CtrlByte1 movwf CB1 movlw CtrlByte2 movwf CB2 call SetPLL ;transfer pll data goto Main ;main loop... ;======================================= END ;=======================================