#include "biosdem.h" #include void waitRAT(void); /* Turn on ADC */ void adc_on(void) { ADCON1 = 0x0E ; /* RA0 analogique seulement */ ADCON0 = 0x41 ; /*Tad = 8*Tosc = 8 * 0.25µs = 2µs > 1.6µs , ADON ;*/ ADIF = 0 ; } /* Start convert channel ch */ /*and read 8 most significant bits when complete */ unsigned char adc_read_8b(unsigned char ch) { ADCON0 &= 0xC7 ; /* RAZ CHSx */ /* Sélection du canal */ if ( ch & 1 ) { CHS0 = 1 ; } if ( ch & 2 ) { CHS1 = 1 ; } if ( ch & 4 ) { CHS2 = 1 ; } waitRAT(); /* Attendre le temps d'acquisition */ ADGO = 1 ; /* Démarre la conversion */ /* Attend la fin de conversion */ while (ADGO && ADON) /* Par sécurité on teste aussi ADON */ ; /* car sinon on rentre dans une boucle infinie */ return ADRESH ; } /******************************************************************************************** * Required acquisition time for A/D module form Max. Heise 2002 * p. 115 equation 11-1 Tacq=19,72,e-6 * seconds, approx. 2,e-5 seconds. * One instruction is executed in one * cycle, one cycle at 4MHz takes 2,5,e-7 * seconds. Thus we must idle for 80 * instructions * Formula for this loop * Inst(I)=1+1+( (I-1)*(1+2) )+2+2=6+3I-3=3I+3 * +2 Inst.Cycles for the call of this function * => Inst(I)=3I+5 * Inst(I) must be 80 * 80=3I+5 * => I=25 * Timing critical, so this is still in assembler. ********************************************************************************************/ char counter ; void waitRAT(void) { #asm I EQU 50 ; Note this is actually twice the required value of I, just to be sure movlw I ; 1 Inst.Cycle movwf _counter ; 1 Inst.Cycle WaitRAT_Loop decfsz _counter,f ; 1 Inst.Cycle if I!=0, 2 Inst.Cycles if I==0 goto WaitRAT_Loop ; 2 Inst.Cycles #endasm }