' Lampemetre avec le 16F876 '@ DEVICE HS_OSC,MCLR_OFF,LVP_OFF,WDT_OFF,PROTECT_OFF Include "modedefs.bas" DEFINE OSC 20 DEFINE ADC_BITS 10 ' Un cycle de base dure 0,8 µS à 20 MHz BLOC1 VAR BYTE[64] '1er champ de stockage échantillons MSD adc BLOC2 VAR BYTE[64] '2eme champ de stockage échantillons LSD adc POINTR VAR BYTE 'Pointeur de champ DATIN VAR BYTE 'Registre de communication DATDAC1 VAR BYTE 'Registre 2eme octet DAC 5571 DATDAC2 VAR BYTE 'Registre 3eme octet DAC 5571 CARIN var byte 'Compteur de secondes DSEC var byte 'Compteur de dizaines de secondes MNT var byte 'Compteur de minutes DMNT var byte 'Compteur de dizaines de minutes HEUR var byte 'Compteur d' heures DHEUR var byte 'Compteur de dizaines d' heures LOWCNT var byte 'Compteur PORTA.1 à 0 HICNT var byte 'Compteur PORTA.1 à 1 CHECK VAR WORD 'Checksum calculé par le lecteur CHECKL VAR CHECK.byte0 'LSD de CHECK CHECKH VAR CHECK.byte1 'MSD de CHECK DEFOCNT VAR BYTE 'Timer de défaut ADDR1 VAR BYTE 'Adresse I2C du DAC DACVAL VAR BYTE 'Octet à écrire dans le DAC TOUCHC VAR BYTE ' Pour gerer les rebonds touche C.7 LDT VAR BYTE 'Pour clignotement LED CONT con %01010000 Mainin: TRISA = %11111111 'Port A en entrée ADCON1 = %10000010 'ADC in sur AN0, AN1, AN2, AN3, AN4, right justified TRISB = %00000001 'Port B en sortie sauf B.0 en entrée LOW PORTB.1 'Pour RS232 LOW PORTB.5 'Pour test ( provisoire ) high PORTB.4 'RD245 a 1 high PORTB.5 'WR245 a 1 TRISC = %11000000 'Port C en sortie sauf C6 et C7 en entrée POINTR = 0 'Initialise le pointeur 'ADDR1 = $62 'Adresse hexa du DAC MAX5381M ADDR1 = $98 'Adresse hexa du DAC5571 'DACVAL = 127 'Initialise le dac à mi-course (decimal) 'I2CWRITE PORTB.2,PORTB.3,ADDR1,[DACVAL] 'Ecrit le DAC 'GOTO Waitpil '*********************************************************************** ' ROUTINE PRINCIPALE '*********************************************************************** Runin: LOW PORTC.5 'Allume la LED READY DACVAL = 31 'Initialise le dac à - 31 Volts ( V grille ) DATIN = DACVAL * 8 ' Calcule la valeur pour le DAC GOSUB Dac5571 'Pour le DAC5571 I2CWRITE PORTB.2,PORTB.3,ADDR1,[DATDAC1, DATDAC2] 'Ecrit le DAC5571 'I2CWRITE PORTB.2,PORTB.3,ADDR1,[DATIN] 'Ecrit le DAC Maxim TOUCHC = 1 'Initialise flag gestion touche port C.7 IF PORTC.6 = 0 THEN GOTO Modscope ' Sortie Oscilloscope si Port C.6 = 0 'ADCON0=%10000001 ' Clock ADC = Fosc/32,Channel 0, Turn-On A/D 'GOSUB ADrout ' Effectue une acquisition Inloop: SERIN PORTB.0,N2400,DATIN '5000,Rtimout,DATIN ' Réception ordre du PC IF DATIN = 101 THEN GOTO Mesure 'Début de mesure si " A " reçu IF DATIN = 124 THEN GOTO Intest 'Routine de test si " T " reçu GOTO Inloop 'PAUSE 40 ' Pause de 40 mS avant réponse Mesure: HIGH PORTC.5 'Eteint la LED READY ADCON0=%10000001 ' Clock ADC = Fosc/32,Channel 0, Turn-On A/D GOSUB ADrout ' Effectue une acquisition Finloop: DATIN = BLOC1[POINTR] 'Charge octet MSD SERout PORTB.1,N2400,[DATIN] 'Emission vers PC à 2400 Bauds Pauseus 200 ' Tempo entre octets DATIN = BLOC2[POINTR] 'Charge octet LSD SERout PORTB.1,N2400,[DATIN] 'Emission vers à 2400 Bauds POINTR = POINTR + 1 IF POINTR = 64 THEN POINTR = 0: GOTO Imesure Pauseus 200 ' Tempo entre octets GOTO Finloop '************************************************************************ Imesure: 'Mesure du courant cathode SERIN PORTB.0,N2400,DATIN 'Réception du PC IF DATIN = 32 THEN ADCON0=%10001001 'Courant max 32 mA: échantilloner sur AN1 IF DATIN <> 32 THEN ADCON0=%10010001 'Courant max 256 mA: échantilloner sur AN2 Loopmesure SERIN PORTB.0,N2400,DATIN 'Réception du PC IF DATIN = 105 THEN GOTO Runin 'Fin de mesure si " E " reçu IF DATIN > 212 THEN GOTO Runin 'Fin de mesure car V max grille = 32 V IF DATIN < 150 THEN GOTO Runin 'Fin de mesure car V min grille = 0 V DACVAL = (DATIN - 150) * 4 '8 ' Calcule la valeur pour le DAC DATIN = DACVAL GOSUB Dac5571 'Pour le DAC5571 I2CWRITE PORTB.2,PORTB.3,ADDR1,[DATDAC1, DATDAC2] 'Ecrit la tension grille dans le DAC5571 'I2CWRITE PORTB.2,PORTB.3,ADDR1,[DACVAL] ' Programme la tension grille PAUSE 100 'Attente de 100 mS pour stabilisation GOSUB ADrout ' Effectue une acquisition DATIN = 250 'Bloque la lampe entre les mesures GOSUB Dac5571 'Pour le DAC5571 I2CWRITE PORTB.2,PORTB.3,ADDR1,[DATDAC1, DATDAC2] 'Ecrit le DAC5571 'I2CWRITE PORTB.2,PORTB.3,ADDR1,[DATIN] 'Tension grille au maxi Triloop: DATIN = BLOC1[POINTR] 'Charge octet MSD SERout PORTB.1,N2400,[DATIN] 'Emission vers PC à 2400 Bauds Pauseus 200 ' Tempo entre octets DATIN = BLOC2[POINTR] 'Charge octet LSD SERout PORTB.1,N2400,[DATIN] 'Emission vers à 2400 Bauds POINTR = POINTR + 1 IF POINTR = 64 THEN POINTR = 0: GOTO Loopmesure Pauseus 200 ' Tempo entre octets GOTO Triloop '************************************************************ Intest: HIGH PORTC.5 'Eteint la LED READY 'DACVAL = 224 ' Preset à - 32v (MAX5382) DACVAL = 248 ' Preset à - 31v (DAC5571) GOTO Dirtest Test: 'Attend la commande PC HIGH PORTC.5 'Eteint la LED READY IF PORTC.7 = 1 THEN TOUCHC = 1 : GOTO Nodval ' Pour gèrer l' appui touche IF PORTC.7 = 0 AND TOUCHC = 0 THEN GOTO Nodval ' Pour gèrer l' appui touche 'IF PORTC.7 = 0 AND DACVAL > 0 THEN 'DACVAL = DACVAL - 7 : TOUCHC = 0 'ELSE 'DACVAL = 224 : TOUCHC =0'(MAX5382) IF DACVAL = 0 THEN DACVAL = 248 : TOUCHC =0'(DAC5571) ELSE DACVAL = DACVAL - 8 : TOUCHC = 0 ENDIF Dirtest: 'I2CWRITE PORTB.2,PORTB.3,ADDR1,[DATIN] ' Programme la tension grille ( DAC MAX 5382) DATIN = DACVAL GOSUB Dac5571 'Pour le DAC5571 I2CWRITE PORTB.2,PORTB.3,ADDR1,[DATDAC1, DATDAC2] 'Ecrit le DAC5571 Nodval: SERIN PORTB.0,N2400,50,Gotest,DATIN ' Réception ordre du PC, le timout de 50ms branche sur Gotest GOTO Runin 'Fin de Test si un caractère reçu reçu du PC Gotest: IF PORTB.0= 1 THEN GOTO Runin 'RS232 inversée HIGH PORTB.5 'Pour test ( provisoire ) ADCON0=%10000001 ' Clock ADC = Fosc/32,Channel 0, Turn-On A/D GOSUB ADrout ' Effectue une acquisition LOW PORTB.5 'Pour test ( provisoire ) LOW PORTB.4 DATIN = 126 'Envoie " V " pour signaler mesure Vplaque SERout PORTB.1,N2400,[DATIN] 'Emission vers PC à 2400 Bauds Pauseus 20 ' Tempo entre octets POINTR = 63 DATIN = BLOC1[POINTR] 'Charge octet MSD SERout PORTB.1,N2400,[DATIN] 'Emission vers PC à 2400 Bauds Pauseus 20 ' Tempo entre octets DATIN = BLOC2[POINTR] 'Charge octet LSD SERout PORTB.1,N2400,[DATIN] 'Emission vers PC à 2400 Bauds ' GOTO Test ' Reboucle Suitest: IF PORTA.4 = 1 THEN SuiTest 'Attend fin de 1/2 sinusoide positive ADCON0=%10011001 'Echantillone Vgrille sur AN3 Pauseus 50 'Wait 50 µS for channel to setup Asm waitsync1 btfss PORTA.4 ; teste SYNC goto waitsync1 EndAsm Loopad1: HIGH PORTB.4 'TEST ADCON0.2 = 1 ' Start conversion Asm waitendad1 btfsc ADCON0.2 ; attend fin de conversion goto waitendad1 EndAsm LOW PORTB.4 DATIN = 107 'Envoie " G " pour signaler mesure Vgrille SERout PORTB.1,N2400,[DATIN] 'Emission vers PC à 2400 Bauds Pauseus 20 ' Tempo entre octets DATIN = 0 ' High byte = 0 SERout PORTB.1,N2400,[DATIN] 'Emission vers PC à 2400 Bauds Pauseus 20 ' Tempo entre octets DATIN = DACVAL / 8 ' Low byte = valeur grille SERout PORTB.1,N2400,[DATIN] 'Emission vers PC à 2400 Bauds Suitest1: IF PORTA.4 = 1 THEN SuiTest1 'Attend fin de 1/2 sinusoide positive ADCON0=%10001001 'Echantillone I32 sur AN1 Pauseus 50 'Wait 50 µS for channel to setup Asm waitsync2 btfss PORTA.4 ; teste SYNC goto waitsync2 EndAsm Loopad2: HIGH PORTB.4 'TEST ADCON0.2 = 1 ' Start conversion Asm waitendad2 btfsc ADCON0.2 ; attend fin de conversion goto waitendad2 EndAsm LOW PORTB.4 DATIN = 151 'Envoie " i " pour signaler mesure I32 SERout PORTB.1,N2400,[DATIN] 'Emission vers PC à 2400 Bauds Pauseus 20 ' Tempo entre octets DATIN = ADRESH ' High byte adc SERout PORTB.1,N2400,[DATIN] 'Emission vers PC à 2400 Bauds Pauseus 20 ' Tempo entre octets DATIN = ADRESL ' Low byte adc SERout PORTB.1,N2400,[DATIN] 'Emission vers PC à 2400 Bauds Suitest2: IF PORTA.4 = 1 THEN SuiTest2 'Attend fin de 1/2 sinusoide positive ADCON0=%10010001 'Echantillone I256 sur AN2 Pauseus 50 'Wait 50 µS for channel to setup Asm waitsync3 btfss PORTA.4 ; teste SYNC goto waitsync3 EndAsm Loopad3: HIGH PORTB.4 'TEST ADCON0.2 = 1 ' Start conversion Asm waitendad3 btfsc ADCON0.2 ; attend fin de conversion goto waitendad3 EndAsm LOW PORTB.4 DATIN = 111 'Envoie " I " pour signaler mesure I32 SERout PORTB.1,N2400,[DATIN] 'Emission vers PC à 2400 Bauds Pauseus 20 ' Tempo entre octets DATIN = ADRESH ' High byte adc SERout PORTB.1,N2400,[DATIN] 'Emission vers PC à 2400 Bauds Pauseus 20 ' Tempo entre octets DATIN = ADRESL ' Low byte adc SERout PORTB.1,N2400,[DATIN] 'Emission vers PC à 2400 Bauds GOTO Test ' Reboucle '************************************************************ Fintrans: PAUSE 100 'TEST DACVAL = 0 Dacloop: PAUSE 1500 'TEST I2CWRITE PORTB.2,PORTB.3,ADDR1,[DACVAL] IF DACVAL = 252 THEN DACVAL = 0:GOTO Waitcom DACVAL = DACVAL +7 ' augmente de 1 volt (pour Vmax dac = 4,5 V) GOTO Dacloop '************************************************************ Rtimout: SERout PORTB.1,N2400,["erreur"] 'Emission vers PC à 2400 Bauds GOTO Waitcom '***************************************************************************** ' ROUTINE D' ACQUISITION DE 64 ECHANTILLONS ADrout: POINTR = 0 ' Initialise pointeur d' échantillons Waitcom: 'Attend la commande PC IF PORTA.4 = 1 THEN Waitcom 'Attend fin de 1/2 sinusoide positive Pauseus 50 ' Wait for channel to setup Asm waitsync btfss PORTA.4 ; teste SYNC goto waitsync EndAsm Loopad: HIGH PORTB.4 'TEST ADCON0.2 = 1 ' Start conversion Asm waitendad btfsc ADCON0.2 ; attend fin de conversion goto waitendad EndAsm LOW PORTB.4 BLOC1[POINTR] = ADRESH 'Charge octet MSD BLOC2[POINTR] = ADRESL 'Charge octet LSD POINTR = POINTR + 1 IF POINTR = 64 THEN POINTR = 0: RETURN ' Fin d' acquisition Pauseus 40 ' Wait for acquisition GOTO Loopad '***************************************************************************** Modscope: 'Sortie sur Oscilloscope en mode XY LDT = 0 'Initialise Timer LED 'DATIN = 8 'Positionne Vgrille à - 6 Volts DACVAL = 8 'Positionne Vgrille à - 8 Volts Waitsync: 'Attend la commande PC IF PORTA.4 = 1 THEN Waitsync 'Attend fin de 1/2 sinusoide positive LDT = LDT + 1 IF LDT < 25 THEN HIGH PORTC.5 'Clignotement la LED READY IF LDT > 24 THEN LOW PORTC.5 'Clignotement la LED READY IF LDT > 50 THEN LDT = 0 DATIN = DACVAL * 8 ' Calcule la valeur pour le DAC GOSUB Dac5571 'Pour le DAC5571 I2CWRITE PORTB.2,PORTB.3,ADDR1,[DATDAC1, DATDAC2] 'Ecrit la tension grille dans le DAC5571 'I2CWRITE PORTB.2,PORTB.3,ADDR1,[DACVAL] 'Ecrit le DAC IF DACVAL > 0 THEN DACVAL = DACVAL -1 'Balaye Vgrille ELSE DACVAL = 8 'Replace Vgrille à valeur de départ ENDIF Asm waits btfss PORTA.4 ; teste SYNC goto waits EndAsm GOTO Waitsync '***************************************************************************** Dac5571: 'Prépare les octets pour le DAC5571 DATDAC1 = 0 DATDAC2 = 0 DATDAC1.0 = DATIN.4 DATDAC1.1 = DATIN.5 DATDAC1.2 = DATIN.6 DATDAC1.3 = DATIN.7 DATDAC2.4 = DATIN.0 DATDAC2.5 = DATIN.1 DATDAC2.6 = DATIN.2 DATDAC2.7 = DATIN.3 'DATDAC1 = DATIN >>4 'Shift à gauche 4 bits MSB de DATIN 'DATDAC2 = DATIN >> 7 'Shift à gauche 4 bits LSB de DATIN RETURN '***************************************************************************** End