;***************************************************************************************** ; HAM GENE 52 ; F6EHJ - Gérard LAGIER (gerard.lagier"at"wanadoo.fr or F6EHJ"at"wanadoo.fr) ;----------------------------------------------------------------------------------------- ;RIGHTS AND LIMITS OF USAGE OF THIS PROGRAMM : ;This programm can be use for personnal usage only. ;Commercial use of this programm is forbiden without the authorization of the author. ;No garantee and reliability of this programm is provided. Its usage is under ;the responsability of the user. ;The author cannot be responsible of all sort of dammages which could happen when and ;following the usage of the programm. ;----------------------------------------------------------------------------------------- ;Usage of the AD9852 and AD9854 DDS chips ;The Analog Device DDS AD9852 and AD9854 show a limited thermal capacity as described ;in the Analog Device Data sheets. ;Two different versions of these DDS exist : ;the AST version (plastic) which is limited to a 200MHz frequency clock ;the ASQ version (thermal mount) which is able to run at 300 MHz if proper ;dissipation hardware is provided. ;the author cannot be responsible of the experimentation done with these chips, if they ;are used out of specification or/with an incorrect thermal system. ;****************************************************************************************** ;The Program : ;The programm allows to command an AD9852 DDS with a PIC 16F877 in order ;to generate sinewave frequencies from audio to RF. ;RF Section interface : ;Ham band selection (10 bands) ;incremental step selection (10Hz, 100Hz, 1kHz, 10kHz and 100 kHz) ;frequency variation (according to the step in use) ;amplitude variation (-30dBV min) ; ;DISPLAY Section : ;1 PC board ;the display uses a 2lines/16 characters LCD ;the 8 bits lines are driven through a serial/parallel register driven by the SPI output ;of the PIC ;all the parameters described hereabove are displayed ;KEYBOARD (connector on the PIC board) ;all the commands are send from the 16 pad keyboard ;Port D of the PIC is dedicated to the keyboard ;the keyboard is permanently polled ;****************************************************************************************** ; WHAT ABOUT THE PROGRAM ? ;A main loop is running permanently and polls the 16 pads of the keyboard. ;each time a pad is pressed, a subroutine is called and process the function required. ;Interrupts are not used in this program. ;INITIALIZATION : ;A large amount of variables and registers are used and are initialized ;during the beginning of the program. ;The LCD display is initialized two times with the same instructions. ;this insures a good start especially with a 20MHz PIC clock. ;the AD9852 DDS is initialized by sending all the bytes with 0. ;The SPI bus is used for this purpose. ;the bytes values which are sent to the DDS register is directly computed ;from the DDS frequency clock. ;The values corresponding to each step (from 10Hz to 10MHz) are located into ;the PIC's EEPROM ;The values corresponding at the beginning of each ham band are also ;stored in EEPROM ;The memory function allows to store and recall until 10 frequencies are ;located in EEPROM too. So at powerdown, these values are not lost. ;DDS FREQUENCY GENERATION : ;The DDS frequency generation is directly linked to the displayed frequency. ;this insure that the output frequency is really the frequency displayed. ;KEYBOARD PADS : ; B+ B- P+ P- ;UTILISATION DU CLAVIER: ;B+ : Band incrementation : 1.8....50 MHz. no action over 50 MHz ;de 50 MHz ;B- : Band decrementation : 50....1.8MHz. no action under 1.8 MHz ; P+: ;Step incrementation : 10Hz...100kHz. no action over 100 kHz ;Touche P-: ;Step decrementation : 100kHz....10Hz. no action under 10Hz ;PIC MEMORY : ;this programm has been extracted from a more complex and longer ;program. ;One part of the program uses the page 1 despite the available memory in page 0 ;it was easier to do that to avoid rewriting of several subroutines. ;RAM memory is processed in the same way for the variables. ;****************************************************************************************** LIST P=16F877;f=inhx8m include "p16f877.inc" __CONFIG H'3772' ;****************************************************************************************** ; Bank 0. ;Warning, 96 bytes allowed only. CBLOCK 0x20 ; Start Data Block (BANK 0) TEMP DATA_LCD COLS KEY PASSEL NRBANDE LCD_0 LCD_1 LCD_2 LCD_3 LCD_4 LCD_5 LCD_6 ACC0 ACC1 ACC2 ACC3 ACC4 ACC5 DATAEE TEMP2 LASTPB EEAD LEVEL MSB_LEVEL LSB_LEVEL CURS ENDC ; End of Data Block ;--------------------------------------------------------------------- ; Bank 1 CBLOCK 0xA0 ; Start Data Block (BANK 1) LOAD0 LOAD1 LOAD2 LOAD3 LOAD4 LOAD5 DDS_0 DDS_1 DDS_2 DDS_3 DDS_4 DDS_5 DDS_6 DDS_7 DDS_8 DDS_9 DDS_10 DDS_11 DDS_12 DDS_13 DDS_14 DDS_15 DDS_16 DDS_17 DDS_18 DDS_19 DDS_20 DDS_21 DDS_22 DDS_23 DDS_24 DDS_25 DDS_26 DDS_27 DDS_28 DDS_29 DDS_30 DDS_31 DDS_32 DDS_33 DDS_34 DDS_35 DDS_36 DDS_37 DDS_38 DDS_39 DDS_40 DDS_41 T_1 T_2 ENDC ; End of Data Block ;*************************************************************************** ; Labels definition ;*************************************************************************** ;Labels to position the LCD cursor ;L0C0 = 1st line, 1st column #DEFINE POS CALL CHRPOS #DEFINE L0C0 MOVLW H'80' #DEFINE L0C1 MOVLW H'81' #DEFINE L0C2 MOVLW H'82' #DEFINE L0C3 MOVLW H'83' #DEFINE L0C4 MOVLW H'84' #DEFINE L0C5 MOVLW H'85' #DEFINE L0C6 MOVLW H'86' #DEFINE L0C7 MOVLW H'87' #DEFINE L0C8 MOVLW H'88' #DEFINE L0C9 MOVLW H'89' #DEFINE L0C10 MOVLW H'8A' #DEFINE L0C11 MOVLW H'8B' #DEFINE L0C12 MOVLW H'8C' #DEFINE L0C13 MOVLW H'8D' #DEFINE L0C14 MOVLW H'8E' #DEFINE L0C15 MOVLW H'8F' #DEFINE L1C0 MOVLW H'C0' #DEFINE L1C1 MOVLW H'C1' #DEFINE L1C2 MOVLW H'C2' #DEFINE L1C3 MOVLW H'C3' #DEFINE L1C4 MOVLW H'C4' #DEFINE L1C5 MOVLW H'C5' #DEFINE L1C6 MOVLW H'C6' #DEFINE L1C7 MOVLW H'C7' #DEFINE L1C8 MOVLW H'C8' #DEFINE L1C9 MOVLW H'C9' #DEFINE L1C10 MOVLW H'CA' #DEFINE L1C11 MOVLW H'CB' #DEFINE L1C12 MOVLW H'CC' #DEFINE L1C13 MOVLW H'CD' #DEFINE L1C14 MOVLW H'CE' #DEFINE L1C15 MOVLW H'CF' ;--------------------------------------------------------------------- ;Miscellaneous labels #DEFINE CARRY_BIT STATUS,0 #DEFINE ZERO_BIT STATUS,2 #DEFINE BANK0 BCF STATUS,5 ;select page 0 #DEFINE BANK1 BSF STATUS,5 ;select page 1 #DEFINE P0 BCF PCLATH,3 ;select mem 0 #DEFINE P1 BSF PCLATH,3 ;select mem 0 ;bank 2 and 3 selection requires RP0 and RP1 at the same time ;--------------------------------------------------------------------- ;labels PORTS #DEFINE KEYPAD PORTD #DEFINE ROW1 PORTD,4 #DEFINE ROW2 PORTD,5 #DEFINE ROW3 PORTD,6 #DEFINE ROW4 PORTD,7 #DEFINE RS PORTB,2 #DEFINE E PORTB,3 #DEFINE IO PORTE,0 #DEFINE CS PORTE,1 #DEFINE MRESET PORTE,2 ;Standard version ;--------------------------------------------------------------------- ;***************************************************************************************** ;EEPROM INIT ;The EEPROM holds the 10 frequencies corresponding to the beginning of ;each ham band. ;These values can be easily changed to follow the user preferences. ;Anyway, it will be necessary to keep the same number of characters at each ;DATA line. A blank ' ' or two will be use if necessary. ;***************************************************************************************** ORG 0x2100 ; BANDs INIT DE ' ','1','8','0','0','0','0',' ' DE ' ','3','7','0','0','0','0',' ' DE ' ','7','0','4','0','0','0',' ' DE '1','0','0','0','0','0','0',' ' DE '1','4','1','0','0','0','0',' ' DE '1','8','1','1','0','0','0',' ' DE '2','1','1','5','0','0','0',' ' DE '2','4','9','3','0','0','0',' ' DE '2','8','5','0','0','0','0',' ' DE '5','0','1','0','0','0','0',' ' ORG 0x2150; FCLK DDS=200 MHz DE H'94',H'BF',H'D6',H'00',H'00',H'00' ;10H DE H'D0',H'7B',H'63',H'08',H'00',H'00' ;100H DE H'23',H'D6',H'E2',H'53',H'00',H'00' ;1k DE H'63',H'5D',H'DC',H'46',H'03',H'00' ;10k DE H'E3',H'A5',H'9B',H'C4',H'20',H'00' ;100k DE H'E1',H'7A',H'14',H'AE',H'47',H'01' ;1M DE H'CC',H'CC',H'CC',H'CC',H'CC',H'0C' ;10M ORG 0X21F3; Version DE 'F','6','E','H','J',' ','V','5','2','9','9' ;**************************************************************************************** ORG 0 ;adresse origine data mémoire programme GOTO INIT ;**************************************************************************************** ;TABLE LCD_INIT ;Cette table contient les différents code de commande nécessaire à l'initialisation ;de l'afficheur LCD. ;La 1ère commande est volontairement transmise 4 fois (H'38') ;La configuration utilisée est 2 lignes de 16 caractères, entrée ;sur 8 bits. ;***************************************************************************************** LCDINIT_TABLE MOVF TEMP,W ADDWF PCL,F RETLW H'38' RETLW H'38' RETLW H'38' RETLW H'38' RETLW H'01' RETLW H'0C' RETLW H'06' RETLW H'00' ;***************************************************************************************** ;Initialisation des ports E/S ;***************************************************************************************** INIT BANK1 CLRW MOVWF TRISA ;PORT A = all output MOVWF TRISC ;PORT C = all output MOVWF TRISE ;PORT E = all output MOVLW b'00010011' ;PORT B MOVWF TRISB MOVLW b'11110000' ;PORT D MOVWF TRISD ;PORT D = Clavier BANK0 MOVLW b'00110000' ;SPI MAster ON MOVWF SSPCON CLRF PORTA CLRF PORTB CLRF PORTC CLRF PORTD CLRF PORTE CLRF LASTPB CLRF TEMP BSF CS ;***************************************************************************************** ; MAIN PROGRAM ;****************************************************************************************** ;INIT LCD et "Welcome display" ;****************************************************************************************** CALL INITLCD ;init LCD display CALL BIENVENU ;welcome message CLRF PCLATH CALL BON_TR CLRF PCLATH ; CALL W32 CALL W32 CALL W32 CALL LINE0BK CALL F6_EHJ CLRF PCLATH ; CALL W32 CALL W32 CALL W32 CALL LINE0BK ;erase upper line L0C6 ;display "." POS MOVLW '.' ;on line 1 CALL DATALCD ;display LCD CALL LINE1BK ;erase lower line ;***************************************************************************************** ;INIT DDS ;***************************************************************************************** CALL INIT_DDS ; DDS initialization (both) MOVLW H'0F' ;Init output level (MAX) MOVWF MSB_LEVEL MOVLW H'FF' MOVWF LSB_LEVEL CALL NIVEAU ;***************************************************************************************** ;INIT LOAD DDS BYTES ;***************************************************************************************** BCF PCLATH,4 ;page 1 BSF PCLATH,3 CALL INIT_DDSWRD ;S/R page 1 BCF PCLATH,3 ;back page 0 ;**************************************************************************************** ; STEP INIT (default 10Hz) MOVLW 1 MOVWF PASSEL BCF PCLATH,4 ;page 1 BSF PCLATH,3 CALL PAS10H ;default (10 Hz) ;**************************************************************************************** ; ; BAND INIT (default 10100 kHz) ;***************************************************************************************** MOVLW 4 ;default: 10100.00 kHz MOVWF NRBANDE BCF PCLATH,4 ;page 1 BSF PCLATH,3 CALL BANDNR CALL SCRBAND ;load LCD and DDS ;**************************************************************************************** ; MAIN LOOP DEB CALL SCRUKB ;poll KBD GOTO DEB ;**************************************************************************************** ; FREQUENCY DEC/INC from Keyboard ;*************************************************************************************** DWNF CALL UPLCDR P1 CALL FQCYR RETURN UPF CALL DWNLCDR P1 CALL FQCYR ;met à jour fréquence DDS RETURN ;***************************************************************************************** ; OUPUT SIGNAL INC/DEC AMPLITUDE from keyboard ; ; The ouput amplitude variation is done in 16 steps ; ; a bargraph on the LCD shows the realtive output ;***************************************************************************************** LEVELUP BCF LEVEL,0 INCFSZ LSB_LEVEL GOTO NIVEAU INCF MSB_LEVEL MOVLW H'10' SUBWF MSB_LEVEL,0 BTFSS ZERO_BIT GOTO NIVEAU MOVLW H'0F' MOVWF MSB_LEVEL MOVLW H'FF' MOVWF LSB_LEVEL GOTO NIVEAU RETURN LEVELDWN BTFSC LEVEL,0 RETURN DECFSZ LSB_LEVEL,1 GOTO NIVEAU DECFSZ MSB_LEVEL MOVLW H'FF' SUBWF MSB_LEVEL,0 BTFSS ZERO_BIT GOTO NIVEAU CLRF MSB_LEVEL CLRF LSB_LEVEL BSF LEVEL,0 GOTO NIVEAU RETURN NIVEAU MOVLW 5 ;Output multiplier CALL RSPI MOVF MSB_LEVEL CALL RSPI MOVF LSB_LEVEL CALL RSPI MOVLW B'00001111' ANDWF MSB_LEVEL,0 BTFSC ZERO_BIT RETURN CALL LINE1BK MOVF MSB_LEVEL,0 MOVWF CURS ECRIT MOVLW H'C0' ADDWF CURS,0 POS MOVLW H'FF' CALL DATALCD DECFSZ CURS,1 GOTO ECRIT RETURN ;***************************************************************************************** ;S/P BANDUP et BANDDWN : circular buffer from 1 to 10. ; BANDUP (14) or BANDDWN (13) inc or dec the band ;10 bands are available (1.8 to 50 MHz) ; On dispose des 10 bandes 1.8 à 50MHz ;******************************************************************************** BANDUP INCF NRBANDE,F ;incrementation of the band number MOVLW d'11 SUBWF NRBANDE,0 ;if we were on 50 (10) we are at 11 BTFSS ZERO_BIT GOTO GOOD ;we are not at 11 GOTO NOGOOD ;we are at 11 NOGOOD MOVLW d'10' MOVWF NRBANDE ;we stay on 50 MHz RETURN ;nothing more GOOD BCF PCLATH,4 ;page 1 BSF PCLATH,3 CALL BANDNR CALL SCRBAND RETURN BANDDWN DECF NRBANDE,F ; 1 ? CLRW ; 0 SUBWF NRBANDE,0 BTFSS ZERO_BIT GOTO OK ;no 1, normal process GOTO NOK NOK MOVLW d'1' ;we stay on 1.8 MOVWF NRBANDE ;nothing more RETURN OK BCF PCLATH,4 ;page 1 BSF PCLATH,3 CALL BANDNR CALL SCRBAND RETURN ;******************************************************************************** ; S/R UPLCDR :Incrementation LCD ; ; ;******************************************************************************** UPLCDR MOVLW 1 SUBWF PASSEL,0 ;step=1 (10Hz) BTFSC ZERO_BIT GOTO LCD10H MOVLW 2 ;step=100Hz? SUBWF PASSEL,0 BTFSC ZERO_BIT GOTO LCD100H ;if yes inc 100Hz MOVLW 3 ;no step=1KHz ? SUBWF PASSEL,0 BTFSC ZERO_BIT GOTO LCD1K MOVLW 4 ;if not =10KHz ? SUBWF PASSEL,0 BTFSC ZERO_BIT GOTO LCD10K ;if yes inc 10kHz GOTO LCD100K ;if not 100kHz LCD10H MOVLW '9' ;do nothing special XORWF LCD_6,0 BTFSS ZERO_BIT GOTO INC10H MOVLW '0' MOVWF LCD_6 CALL DISP10H ;---------------------------------------------------------- LCD100H MOVLW '9' ;do nothing special XORWF LCD_0,0 BTFSS ZERO_BIT GOTO INC100H MOVLW '0' MOVWF LCD_0 CALL DISP100H ;---------------------------------------------------------- LCD1K MOVLW '9' ;do nothing special XORWF LCD_1,0 BTFSS ZERO_BIT GOTO INC1K MOVLW '0' MOVWF LCD_1 CALL DISP1K ;---------------------------------------------------------- LCD10K MOVLW '9' ;do nothing special XORWF LCD_2,0 BTFSS ZERO_BIT GOTO INC10K MOVLW '0' MOVWF LCD_2 CALL DISP10K ;---------------------------------------------------------- LCD100K MOVLW '9' ;do nothing special XORWF LCD_3,0 BTFSS ZERO_BIT GOTO INC100K MOVLW '0' MOVWF LCD_3 CALL DISP100K MOVLW H'39' XORWF LCD_4,0 BTFSS ZERO_BIT GOTO INC1M MOVLW H'30' MOVWF LCD_4 CALL DISP1M GOTO INC10M ;---------------------------------------------------------- INC10H INCF LCD_6,1 CALL DISP10H RETURN INC100H INCF LCD_0,1 CALL DISP100H RETURN INC1K INCF LCD_1,1 CALL DISP1K RETURN INC10K INCF LCD_2,1 CALL DISP10K RETURN INC100K INCF LCD_3,1 CALL DISP100K RETURN INC1M INCF LCD_4,1 CALL DISP1M RETURN INC10M INCF LCD_5,1 CALL DISP10M RETURN ;---------------------------------------------------------- ;******************************************************************************** ; S/R DWNLCDR :Déc LCD ; ;******************************************************************************** DWNLCDR MOVLW 1 SUBWF PASSEL,0 ;pas=1 (10Hz) BTFSC ZERO_BIT GOTO LCDH10 MOVLW 2 ;pas=100Hz? SUBWF PASSEL,0 BTFSC ZERO_BIT GOTO LCDH100 ;si oui va décrémenter de 100Hz MOVLW 3 ;pas=100Hz? SUBWF PASSEL,0 BTFSC ZERO_BIT GOTO LCDK1 ;si oui va décrémenter de 1khz MOVLW 4 ;sinon pas=1KHz ? SUBWF PASSEL,0 BTFSC ZERO_BIT GOTO LCDK10 ;si oui va décrémenter de 1kHz GOTO LCDK100 ;sinon de 10kHz LCDH10 MOVLW H'30' SUBWF LCD_6,0 BTFSS ZERO_BIT GOTO DEC_6 MOVLW H'39' MOVWF LCD_6 CALL DISP10H LCDH100 MOVLW H'30' SUBWF LCD_0,0 BTFSS ZERO_BIT GOTO DEC_0 MOVLW H'39' MOVWF LCD_0 CALL DISP100H LCDK1 MOVLW H'30' SUBWF LCD_1,0 BTFSS ZERO_BIT GOTO DEC_1 MOVLW H'39' MOVWF LCD_1 CALL DISP1K LCDK10 MOVLW H'30' SUBWF LCD_2,0 BTFSS ZERO_BIT GOTO DEC_2 MOVLW H'39' MOVWF LCD_2 CALL DISP10K LCDK100 MOVLW H'30' SUBWF LCD_3,0 BTFSS ZERO_BIT GOTO DEC_3 MOVLW H'39' MOVWF LCD_3 CALL DISP100K MOVLW H'30' SUBWF LCD_4,0 BTFSS ZERO_BIT GOTO DEC_4 MOVLW H'39' MOVWF LCD_4 CALL DISP1M DECF LCD_5,1 CALL DISP10M RETURN DEC_6 DECF LCD_6,1 CALL DISP10H RETURN DEC_0 DECF LCD_0,1 CALL DISP100H RETURN DEC_1 DECF LCD_1,1 CALL DISP1K RETURN DEC_2 DECF LCD_2,1 CALL DISP10K RETURN DEC_3 DECF LCD_3,1 CALL DISP100K RETURN DEC_4 DECF LCD_4,1 CALL DISP1M RETURN ;*************************************************************************************************** ; ;S/R DISP100H, 1K, 10K, 100K, 1M, 10M ;These S/R update the only LCD digit which have changed instead of a global LCD update in order ;to reduce the CPU time. ;********************************************************************************************* ; DISP10H L0C8 POS MOVF LCD_6,0 CALL DATALCD RETURN ;-------------------------------- DISP100H L0C7 POS MOVF LCD_0,0 CALL DATALCD RETURN ;------------------------------------ DISP1K L0C5 POS MOVF LCD_1,0 ;contenu des 6 mots "fréquence" CALL DATALCD RETURN ;-------------------------------------- DISP10K L0C4 POS MOVF LCD_2,0 ;contenu des 6 mots "fréquence" CALL DATALCD RETURN ;-------------------------------------- DISP100K L0C3 POS MOVF LCD_3,0 ;contenu des 6 mots "fréquence" CALL DATALCD RETURN ;-------------------------------------- DISP1M L0C2 POS MOVF LCD_4,0 ;contenu des 6 mots "fréquence" CALL DATALCD RETURN ;-------------------------------------- DISP10M L0C1 POS MOVF LCD_5,0 ;contenu des 6 mots "fréquence" CALL DATALCD RETURN ;********************************************************************************* ;S/R SCRBAND: ;Frequency init at power up. ;Update display and output frequency ;***************************************************************************************** SCRBAND CALL DISP10H CALL DISP100H CALL DISP1K CALL DISP10K CALL DISP100K CALL DISP1M CALL DISP10M P1 CALL FQCYR P0 RETURN ;********************************************************************************* ;S/P OL52 : AD 9852 LOADING ; ;The loading process uses the SPI S/R for DATA and CLOCK signals ;*********************************************************************** OL52 MOVLW b'00110001' ;SPI MAster actif MOVWF SSPCON BCF CS ;CS ON MOVLW 2 MOVWF TEMP CALL RSPI MOVF ACC5,W MOVWF TEMP ;charge séquentiellement la valeur CALL RSPI MOVF ACC4,W MOVWF TEMP ;de chaque octet du DDS CALL RSPI MOVF ACC3,W MOVWF TEMP ;dans la variable TEMP CALL RSPI MOVF ACC2,W MOVWF TEMP CALL RSPI MOVF ACC1,W MOVWF TEMP CALL RSPI MOVF ACC0,W MOVWF TEMP CALL RSPI BSF IO ;IO BCF IO ;IO BSF CS ;fin CS MOVLW b'00110000' ;SPI MAster actif MOVWF SSPCON RETURN ;********************************************************************* ;**************************************************************************************** ;INIT_DDS : Init DDS AD9852 ; ;The init procedure sends the 6 bytes to the DDS register (48 bits). ;all the 6 bytes = 00 ;***************************************************************************************** INIT_DDS MOVLW b'00110001' ;SPI MAster actif F/16 MOVWF SSPCON CLRF ACC0 CLRF ACC1 CLRF ACC2 CLRF ACC3 CLRF ACC4 CLRF ACC5 BSF MRESET ;Master RESET ON CALL W16 BCF MRESET ;Fin RESET BCF CS ;Chip Select BSF IO ;IO NOP BCF IO ;IO MOVLW H'07' CALL RSPI MOVLW b'00010100' ; CALL RSPI MOVLW b'00100010' ; CALL RSPI MOVLW b'00000001' ;Internal Update CLK CALL RSPI MOVLW b'01000000' ; By pass Inv Sync CALL RSPI MOVLW H'05' ;Calage IO Update CALL RSPI MOVLW b'00000000' ; CALL RSPI MOVLW b'00000000' ; CALL RSPI MOVLW b'00000000' ; CALL RSPI MOVLW d'10' CALL RSPI BSF IO ;IO RST NOP BCF IO ;Fin IO RST BSF CS ;CS OFF MOVLW b'00110000' ;SPI MAster actif nominal au retour MOVWF SSPCON CALL OL52 ;all bytes = 0 RETURN ;******************************************************************************************** ;S/R INITLCD: 2 LINES and 16 CHARACTERS + options ; ;13 Instructions ;************************************************************************************************* INITLCD CALL W4 BCF RS LDLCD CALL LCDINIT_TABLE IORLW H'00' BTFSC STATUS,Z GOTO INITLCD_DONE BSF E CALL RSPI BCF E CALL W4 INCF TEMP,F GOTO LDLCD INITLCD_DONE RETURN ;***************************************************************************************** ;S/R CMDLCD: SEND a COMMAND to LCD ; ;5 Instructions ;***************************************************************************************** CMDLCD BCF RS BSF E CALL RSPI ;SPI routine BCF E CALL W2 RETURN ;***************************************************************************************** ; ;S/R DATALCD: Send a character to LCD and display it ; ; ;***************************************************************************************** DATALCD BSF RS BSF E CALL RSPI ;routine SPI BCF E CALL W1 RETURN ;***************************************************************************************** ;S/R CHRPOS: Reach a position on the LCD (line/col) ; ;***************************************************************************************** CHRPOS ; S/R permet de se positionner ds la ligne CALL CMDLCD BSF RS RETURN ;***************************************************************************************** ;LINE0BK : ERASE UPPER LINE ;***************************************************************************************** LINE0BK L0C0 POS CALL BK RETURN ;************************************************************************************ ;LINE1BK ERASE LOWER LINE ;************************************************************************************ LINE1BK L1C0 POS CALL BK RETURN ;*********************************************************************************** ;BK LOAD with ALL BLANK CHARACTERS ;************************************************************************************ BK MOVLW d'16' MOVWF TEMP EFFACE MOVLW ' ' CALL DATALCD DECFSZ TEMP,1 GOTO EFFACE RETURN ;************************************************************************************ ;BIENVENU - WELCOME MESSAGE ;************************************************************************************ BIENVENU L0C4 POS CLRF TEMP BIEN MOVLW H'0D' ;MSB adresse table MOVWF PCLATH CALL BIEN_TABLE IORLW H'00' BTFSC STATUS,Z RETURN CLRF PCLATH CALL DATALCD INCF TEMP,F GOTO BIEN BON_TR L1C2 POS CLRF TEMP BON MOVLW H'0D' MOVWF PCLATH CALL BON_TRAFFIC IORLW H'00' BTFSC STATUS,Z RETURN CLRF PCLATH CALL DATALCD INCF TEMP,F GOTO BON RETURN F6_EHJ L0C2 POS CLRF TEMP F6 MOVLW H'0D' MOVWF PCLATH CALL F6EHJ IORLW H'00' BTFSC STATUS,Z RETURN CLRF PCLATH CALL DATALCD INCF TEMP,F GOTO F6 RETURN ;******************************************************************************************** ;S/P RSPI: ;The content of W register fom SDO pin is serialized ;Te clock is generated from SCK pin ;***************************************************************************************** RSPI BCF PIR1,SSPIF MOVWF SSPBUF SPI_T BTFSS PIR1,SSPIF GOTO SPI_T RETURN ;***************************************************************************************** ;S/P SCRUKB : KEYBOARD polling. ; KEY variable is processed according to the pad pressed ;branch according to pad number to s/p T_0 à T_15 ;***************************************************************************************** SCRUKB CALL KEYS CLAVIER MOVLW d'0' SUBWF KEY,0 BTFSC ZERO_BIT GOTO K_0 MOVLW d'1' SUBWF KEY,0 BTFSC ZERO_BIT GOTO K_1 MOVLW d'2' SUBWF KEY,0 BTFSC ZERO_BIT GOTO K_2 MOVLW d'3' SUBWF KEY,0 BTFSC ZERO_BIT GOTO K_3 MOVLW d'4' SUBWF KEY,0 BTFSC ZERO_BIT GOTO K_4 MOVLW d'5' SUBWF KEY,0 BTFSC ZERO_BIT GOTO K_5 MOVLW d'6' SUBWF KEY,0 BTFSC ZERO_BIT GOTO K_6 MOVLW d'7' SUBWF KEY,0 BTFSC ZERO_BIT GOTO K_7 MOVLW d'8' SUBWF KEY,0 BTFSC ZERO_BIT GOTO K_8 MOVLW d'9' SUBWF KEY,0 BTFSC ZERO_BIT GOTO K_9 MOVLW d'10' SUBWF KEY,0 BTFSC ZERO_BIT GOTO K_10 MOVLW d'11' SUBWF KEY,0 BTFSC ZERO_BIT GOTO K_11 MOVLW d'12' SUBWF KEY,0 BTFSC ZERO_BIT GOTO K_12 MOVLW d'13' SUBWF KEY,0 BTFSC ZERO_BIT GOTO K_13 MOVLW d'14' SUBWF KEY,0 BTFSC ZERO_BIT GOTO K_14 MOVLW d'15' SUBWF KEY,0 BTFSC ZERO_BIT GOTO K_15 CLRF PCLATH RETURN ; K_0 MUTE CALL BANDUP ;inc band CALL W24 RETURN K_1 P1 CALL PAS_UP ;inc step P0 CALL W24 RETURN K_2 CALL DWNF RETURN K_3 CALL LEVELUP ;output level inc RETURN ;----------------------------------------------------------------------- K_4 CALL BANDDWN ;band dec CALL W24 RETURN K_5 P1 CALL PAS_DWN ;step dec P0 CALL W24 RETURN K_6 CALL UPF RETURN K_7 CALL LEVELDWN ;output level dec RETURN ;----------------------------------------------------------------------- K_8 RETURN K_9 RETURN K_10 RETURN K_11 RETURN K_12 RETURN K_13 RETURN K_14 RETURN K_15 RETURN ;***************************************************************************************** ;S/P KEYS : ;Appel : call KEYS - ;Le retour variable clavier est contenu dans KEY (0 à 15) ;En l'absence de pression sur une touche, la valeur de KEY est H'10' ;***************************************************************************************** KEYS CALL SK MOVLW d'16' SUBWF KEY,0 BTFSC CARRY_BIT MOVF KEY,0 RETURN SK CLRF KEY CLRF KEYPAD MOVLW d'4' MOVWF COLS BSF CARRY_BIT SCAN RLF KEYPAD,1 BCF CARRY_BIT BTFSC ROW1 GOTO PRESS INCF KEY,1 BTFSC ROW2 GOTO PRESS INCF KEY,1 BTFSC ROW3 GOTO PRESS INCF KEY,1 BTFSC ROW4 GOTO PRESS INCF KEY,1 DECFSZ COLS,1 GOTO SCAN PRESS RETURN ;************************************************************************** ;S/P TIMER ; Delay with different PIC clock : ; W1 W2 W3 W4 W5 W6 W7 W8 ; 4 MHz = 1 2 4 8 16 32 64 128 ms ; 8 MHz = 0.5 1 2 4 8 16 32 64 ms ; 20MHz = 0.2 0.4 0.8 1.6 3.2 6.4 12.8 25 ms ; ***************************************************************************** ; W8 MOVLW 0xFF BANK1 MOVWF T_1 GOTO BOUCLE_2 W7 MOVLW 0x80 BANK1 MOVWF T_1 GOTO BOUCLE_2 W6 MOVLW 0x40 BANK1 MOVWF T_1 GOTO BOUCLE_2 W5 MOVLW 0x20 BANK1 MOVWF T_1 GOTO BOUCLE_2 W4 MOVLW 0x10 BANK1 MOVWF T_1 GOTO BOUCLE_2 W3 MOVLW 5 BANK1 MOVWF T_1 GOTO BOUCLE_2 W2 MOVLW 2 BANK1 MOVWF T_1 GOTO BOUCLE_2 W1 MOVLW 1 BANK1 MOVWF T_1 BOUCLE_2 MOVLW 0xFF BANK1 MOVWF T_2 BOUCLE_1 DECFSZ T_2,f GOTO BOUCLE_1 DECFSZ T_1,f GOTO BOUCLE_2 BANK0 RETURN W16 CALL W8 CALL W8 RETURN W24 CALL W8 CALL W8 CALL W8 RETURN W32 CALL W8 CALL W8 CALL W8 CALL W8 RETURN ;***************************************************************************************** ; SUBROUTINES AND TABLES IN PAGE 1 ;P0 0000-07FF - ;P1 0800-0FFF BSF PCLATH,3 ou H'08' ;P2 1000-17FF BSF PCLATH,4 ou H'10' ;P3 1800-1FFF BSF PCLATH,3 et BSF PCLATH,4 ou H'18' ;***************************************************************************************** ORG H'0800' ;************************************************************************************** ; ; S/R FQCYR ; ;************************************************************************************** ;This S/R transforms the diaplyed LCD value (7 digits) to 6 bytes for the DDS. ;Each digit from the LCD is processed individually and represent a frequency increment ;computed along the following formula : ; ; F= f Xtal * N /2exp 48 ;The value of F depends of each digit : 10Hz....10MHz with F Xtal=200 MHz ; ;All these values are inside the EEPROM and are transfered to the DDS variables ;DDS_0......DDS_41 during the init process. ;Each constant is multiplied by the wieght of the corresponding digit. ;In fact, the multiplication is a multiple addition. ;All the results are then add to make the frequency word. ; ; ; ;************************************************************************************************** FQCYR CLRF TEMP2 CLRF ACC0 CLRF ACC1 CLRF ACC2 CLRF ACC3 CLRF ACC4 CLRF ACC5 XADD10H BANK1 MOVF DDS_0,W MOVWF LOAD0 MOVF DDS_1,W MOVWF LOAD1 MOVF DDS_2,W MOVWF LOAD2 MOVF DDS_3,W MOVWF LOAD3 MOVF DDS_4,W MOVWF LOAD4 MOVF DDS_5,W MOVWF LOAD5 BANK0 MOVLW H'30' SUBWF LCD_6,0 ; Substrat 30 from LCD_6 BTFSC ZERO_BIT ; IF R=0 next digit because n*0=0... GOTO XADD100H MOVWF TEMP2 ; Multiplier CALL AGAIN ; If not add TEMP2 ;----------------------------------------------------------------------- XADD100H BANK1 MOVF DDS_6,W MOVWF LOAD0 MOVF DDS_7,W MOVWF LOAD1 MOVF DDS_8,W MOVWF LOAD2 MOVF DDS_9,W MOVWF LOAD3 MOVF DDS_10,W MOVWF LOAD4 MOVF DDS_11,W MOVWF LOAD5 BANK0 MOVLW H'30' SUBWF LCD_0,0 ; Soustrait 30 de LCD_0 BTFSC ZERO_BIT GOTO XADD1K MOVWF TEMP2 ; Multiplicateur CALL AGAIN ;---------------------------------------------------------------------------------------- XADD1K BANK1 MOVF DDS_12,W MOVWF LOAD0 MOVF DDS_13,W MOVWF LOAD1 MOVF DDS_14,W MOVWF LOAD2 MOVF DDS_15,W MOVWF LOAD3 MOVF DDS_16,W MOVWF LOAD4 MOVF DDS_17,W MOVWF LOAD5 BANK0 MOVLW H'30' SUBWF LCD_1,0 ; Soustrait 30 de LCD_1 BTFSC ZERO_BIT GOTO XADD10K MOVWF TEMP2 ; Multiplicateur CALL AGAIN ;------------------------------------------------------------------------------------------ XADD10K BANK1 MOVF DDS_18,W MOVWF LOAD0 MOVF DDS_19,W MOVWF LOAD1 MOVF DDS_20,W MOVWF LOAD2 MOVF DDS_21,W MOVWF LOAD3 MOVF DDS_22,W MOVWF LOAD4 MOVF DDS_23,W MOVWF LOAD5 BANK0 MOVLW H'30' SUBWF LCD_2,0 ; Soustrait 30 de LCD_2 BTFSC ZERO_BIT GOTO XADD100K MOVWF TEMP2 ; Multiplicateur CALL AGAIN ;------------------------------------------------------------------------------------------ XADD100K BANK1 MOVF DDS_24,W MOVWF LOAD0 MOVF DDS_25,W MOVWF LOAD1 MOVF DDS_26,W MOVWF LOAD2 MOVF DDS_27,W MOVWF LOAD3 MOVF DDS_28,W MOVWF LOAD4 MOVF DDS_29,W MOVWF LOAD5 BANK0 MOVLW H'30' SUBWF LCD_3,0 ; Soustrait 30 de LCD_3 BTFSC ZERO_BIT GOTO XADD1M MOVWF TEMP2 ; Multiplicateur CALL AGAIN ;------------------------------------------------------------------------------------------ XADD1M BANK1 MOVF DDS_30,W MOVWF LOAD0 MOVF DDS_31,W MOVWF LOAD1 MOVF DDS_32,W MOVWF LOAD2 MOVF DDS_33,W MOVWF LOAD3 MOVF DDS_34,W MOVWF LOAD4 MOVF DDS_35,W MOVWF LOAD5 BANK0 R1_M MOVLW H'30' SUBWF LCD_4,0 ; Soustrait 30 de LCD_4 BTFSC ZERO_BIT GOTO XADD10M MOVWF TEMP2 ; Multiplicateur CALL AGAIN ;------------------------------------------------------------------------------------------ XADD10M BANK1 MOVF DDS_36,W MOVWF LOAD0 MOVF DDS_37,W MOVWF LOAD1 MOVF DDS_38,W MOVWF LOAD2 MOVF DDS_39,W MOVWF LOAD3 MOVF DDS_40,W MOVWF LOAD4 MOVF DDS_41,W MOVWF LOAD5 BANK0 MOVLW H'30' SUBWF LCD_5,0 ; Soustrait 30 de LCD_0 BTFSS CARRY_BIT GOTO LD BTFSC ZERO_BIT GOTO LD MOVWF TEMP2 ; Multiplicateur CALL AGAIN ;------------------------------------------------------------------------------------------ LD CLRF PCLATH ;retour page 0 CALL OL52 ;chargement du DDS 9850 OL RETURN AGAIN CALL XADD DECFSZ TEMP2,1 GOTO AGAIN RETURN ;*************************************************************************** ;S/R XADD:Incrementation of the DDS word with the current step ; ;LOAD0 to LOAD4 hold the value coming from the LCD display. ;The 2 value are added en stored in ACC0 to ACC4 ;**************************************************************************** XADD BANK1 MOVF LOAD0,W BANK0 ADDWF ACC0,F BANK1 MOVF LOAD1,W BTFSC CARRY_BIT INCFSZ LOAD1,W BANK0 ADDWF ACC1,F BANK1 MOVF LOAD2,W BTFSC CARRY_BIT INCFSZ LOAD2,W BANK0 ADDWF ACC2,F BANK1 MOVF LOAD3,W BTFSC CARRY_BIT INCFSZ LOAD3,W BANK0 ADDWF ACC3,F BANK1 MOVF LOAD4,W BTFSC CARRY_BIT INCFSZ LOAD4,W BANK0 ADDWF ACC4,F BANK1 MOVF LOAD5,W BTFSC CARRY_BIT INCFSZ LOAD5,W BANK0 ADDWF ACC5,F RETURN ;******************************************************************************** ;S/P PAS : Circular buffer from 1 to 5. ;Once STEP from the KB is pressed (2), the word PASSEL is incremented. ;5 steps are available : 10HZ, 100Hz, 1kHz, 10kHz and 100 kHz ;when 100 kHz has been reached, it comes back to 10Hz ;******************************************************************************** PAS_UP INCF PASSEL,F ;incrément step number MOVLW d'6' SUBWF PASSEL,0 ;if we were at 100k (5) ;we are at 6 BTFSS ZERO_BIT GOTO DOOG ;we are not at 6 GOTO NODOOG ;we are at 6 NODOOG MOVLW d'5' MOVWF PASSEL ;stay at 5 (100kHz) DOOG CALL PASNR ;nominal process RETURN PAS_DWN DECF PASSEL,F ; 1 ? CLRW ; 0 SUBWF PASSEL,0 BTFSS ZERO_BIT GOTO OKK ;not 1, nominal process GOTO KON KON MOVLW d'1' ;stay at 1 (10Hz) MOVWF PASSEL ; OKK CALL PASNR RETURN PASNR MOVLW 1 ;no, <5 SUBWF PASSEL,W ;1st step ? (10Hz) BTFSC ZERO_BIT CALL PAS10H MOVLW 2 SUBWF PASSEL,W ;2nd step ? (100Hz) BTFSC ZERO_BIT CALL PAS100H MOVLW 3 SUBWF PASSEL,W ;3rd step ?(1kHz) BTFSC ZERO_BIT CALL PAS1K MOVLW 4 SUBWF PASSEL,W ;4th step ? (10kHz) BTFSC ZERO_BIT CALL PAS10K MOVLW 5 SUBWF PASSEL,W ;5th step ? (100kHz) BTFSC ZERO_BIT CALL PAS100K TERM RETURN PAS10H CLRF PCLATH L0C9 POS MOVLW ' ' CALL DATALCD MOVLW ' ' CALL DATALCD MOVLW '1' CALL DATALCD MOVLW '0' CALL DATALCD MOVLW 'H' CALL DATALCD CLRF PCLATH RETURN PAS100H CLRF PCLATH L0C9 POS MOVLW ' ' CALL DATALCD MOVLW '1' CALL DATALCD MOVLW '0' CALL DATALCD MOVLW '0' CALL DATALCD MOVLW 'H' CALL DATALCD CLRF PCLATH RETURN PAS1K CLRF PCLATH L0C10 POS MOVLW ' ' CALL DATALCD MOVLW ' ' CALL DATALCD MOVLW '1' CALL DATALCD MOVLW 'k' CALL DATALCD CLRF PCLATH RETURN PAS10K CLRF PCLATH L0C10 POS MOVLW ' ' CALL DATALCD MOVLW '1' CALL DATALCD MOVLW '0' CALL DATALCD MOVLW 'k' CALL DATALCD CLRF PCLATH RETURN PAS100K CLRF PCLATH L0C10 POS MOVLW ' ' CALL DATALCD MOVLW '1' CALL DATALCD MOVLW '0' CALL DATALCD MOVLW '0' CALL DATALCD MOVLW 'k' CALL DATALCD CLRF PCLATH RETURN ;*************************************************************************************************** ;S/R BANDNR ;Band selection from the KB BANDNR MOVLW d'1' SUBWF NRBANDE,0 BTFSC ZERO_BIT GOTO B_1.8 MOVLW d'2' SUBWF NRBANDE,0 BTFSC ZERO_BIT GOTO B_3.5 MOVLW d'3' SUBWF NRBANDE,0 BTFSC ZERO_BIT GOTO B_7 MOVLW d'4' SUBWF NRBANDE,0 BTFSC ZERO_BIT GOTO B_10 MOVLW d'5' SUBWF NRBANDE,0 BTFSC ZERO_BIT GOTO B_14 MOVLW d'6' SUBWF NRBANDE,0 BTFSC ZERO_BIT GOTO B_18 MOVLW d'7' SUBWF NRBANDE,0 BTFSC ZERO_BIT GOTO B_21 MOVLW d'8' SUBWF NRBANDE,0 BTFSC ZERO_BIT GOTO B_24 MOVLW d'9' SUBWF NRBANDE,0 BTFSC ZERO_BIT GOTO B_28 GOTO B_50 RETURN B_1.8 MOVLW H'00' ;branch to EEPROM address to read frequency MOVWF EEAD CALL EELOAD CLRF PCLATH RETURN B_3.5 MOVLW H'08' MOVWF EEAD CALL EELOAD CLRF PCLATH RETURN B_7 MOVLW H'10' MOVWF EEAD CALL EELOAD CLRF PCLATH RETURN B_10 MOVLW H'18' MOVWF EEAD CALL EELOAD CLRF PCLATH RETURN B_14 MOVLW H'20' MOVWF EEAD CALL EELOAD CLRF PCLATH RETURN B_18 MOVLW H'28' MOVWF EEAD CALL EELOAD CLRF PCLATH RETURN B_21 MOVLW H'30' MOVWF EEAD CALL EELOAD CLRF PCLATH RETURN B_24 MOVLW H'38' MOVWF EEAD CALL EELOAD CLRF PCLATH RETURN B_28 MOVLW H'40' MOVWF EEAD CALL EELOAD CLRF PCLATH RETURN B_50 MOVLW H'48' MOVWF EEAD CALL EELOAD CLRF PCLATH RETURN EELOAD BCF PCLATH,4 BSF PCLATH,3 CALL READEE MOVWF LCD_5 INCF EEAD,F CALL READEE MOVWF LCD_4 INCF EEAD,F CALL READEE MOVWF LCD_3 INCF EEAD,F CALL READEE MOVWF LCD_2 INCF EEAD,F CALL READEE MOVWF LCD_1 INCF EEAD,F CALL READEE MOVWF LCD_0 INCF EEAD,F CALL READEE MOVWF LCD_6 RETURN ;***************************************************************************************** ;INIT MOTS DDS ;Initialise ;***************************************************************************************** INIT_DDSWRD CLRF EEAD CLRF EEADR MOVLW H'50' ;H'50' pour 9852 MOVWF EEAD ;stored values in EEPROM for DDS bytes CALL READEE BANK1 MOVWF DDS_0 CALL RET MOVWF DDS_1 CALL RET MOVWF DDS_2 CALL RET MOVWF DDS_3 CALL RET MOVWF DDS_4 CALL RET MOVWF DDS_5 CALL RET MOVWF DDS_6 CALL RET MOVWF DDS_7 CALL RET MOVWF DDS_8 CALL RET MOVWF DDS_9 CALL RET MOVWF DDS_10 CALL RET MOVWF DDS_11 CALL RET MOVWF DDS_12 CALL RET MOVWF DDS_13 CALL RET MOVWF DDS_14 CALL RET MOVWF DDS_15 CALL RET MOVWF DDS_16 CALL RET MOVWF DDS_17 CALL RET MOVWF DDS_18 CALL RET MOVWF DDS_19 CALL RET MOVWF DDS_20 CALL RET MOVWF DDS_21 CALL RET MOVWF DDS_22 CALL RET MOVWF DDS_23 CALL RET MOVWF DDS_24 CALL RET MOVWF DDS_25 CALL RET MOVWF DDS_26 CALL RET MOVWF DDS_27 CALL RET MOVWF DDS_28 CALL RET MOVWF DDS_29 CALL RET MOVWF DDS_30 CALL RET MOVWF DDS_31 CALL RET MOVWF DDS_32 CALL RET MOVWF DDS_33 CALL RET MOVWF DDS_34 CALL RET MOVWF DDS_35 CALL RET MOVWF DDS_36 CALL RET MOVWF DDS_37 CALL RET MOVWF DDS_38 CALL RET MOVWF DDS_39 CALL RET MOVWF DDS_40 CALL RET MOVWF DDS_41 BANK0 RETURN RET BANK0 INCF EEAD,1 CALL READEE BANK1 RETURN ;**************************************************************************************** ;READEE READ THE EEPROM ;EEAD hold the read adress ;W returns the value read ;***************************************************************************************** READEE MOVF EEAD,0 BSF STATUS,RP1 BCF STATUS,RP0 MOVWF EEADR ; read adress in EEADR register BSF STATUS,RP0 ; bank 3 BCF EECON1,EEPGD ; go and read EEPROM BSF EECON1,RD BCF STATUS,RP0 ; back to bank 0 MOVF EEDATA,0 ; load value in W BCF STATUS,RP1 RETURN ;**************************************************************************************** ;WRITEE WRITE EEPROM ;EEAD hold the write adress ;DATAEE hold the DATA to write ;***************************************************************************************** WRITEE MOVF EEAD,W ;adress in EEAD register BSF STATUS,RP1 BCF STATUS,RP0 MOVWF EEADR ;write adress BCF STATUS,RP1 ;bank0 MOVF DATAEE,W ;data to write BSF STATUS,RP1 ;bank2 MOVWF EEDATA BSF STATUS,RP0 BCF EECON1,EEPGD BSF EECON1,WREN MOVLW H'55' MOVWF EECON2 MOVLW H'AA' MOVWF EECON2 BSF EECON1,WR BCF EECON1,WREN BCF STATUS,RP0 BCF STATUS,RP1 RETURN ;***************************************************************************************** ;TABLE BIENVENUE ;Welcome message ;***************************************************************************************** ORG H'0D00' BIEN_TABLE MOVF TEMP,W ADDWF PCL,F RETLW 'B' RETLW 'I' RETLW 'E' RETLW 'N' RETLW 'V' RETLW 'E' RETLW 'N' RETLW 'U' RETLW '!' RETLW H'00' BON_TRAFFIC MOVF TEMP,W ADDWF PCL,F RETLW 'H' RETLW 'A' RETLW 'M' RETLW ' ' RETLW 'G' RETLW 'E' RETLW 'N' RETLW 'E' RETLW ' ' RETLW '5' RETLW '2' RETLW '!' RETLW H'00' F6EHJ MOVF TEMP,W ADDWF PCL,F RETLW ' ' RETLW ' ' RETLW ' ' RETLW 'F' RETLW '6' RETLW 'E' RETLW 'H' RETLW 'J' RETLW ' ' RETLW ' ' RETLW ' ' RETLW H'00' end