Andre, Great looking code as all ways. One thing that may be slowing down the program is that you are starting the conversion and waiting for it to complete before reading the A/D and doing the delay. If you first read the A/D and then start the next conversion before doing the delay, there would be much less, if any, time spent waitting for the conversion to complete. I have rearanged your code in the MAIN routine to do this. I would arange the routines in a different order. wait for A/D to complete read A/D select next A/D input (if necessary) Delay for next input to settle (if changed A/D inputs) start conversion delay This can all be done under interupt if you desire. It gets a little complicated if you switch inputs. But there are no wasteful delays necessary. with no A/D input switching INTERUPT wait for A/D to complete read A/D start next conversion * this gives one more cycle store A/D reading * for conversion set 'NEW' bit flag * to show main that new A/D reading return from interupt END INTERUPT with A/D input switching INTERUPT wait for A/D to complete read A/D select next A/D input * if posible before store A/D reading * storing A/D reading set 'NEW' and 'CONVERSION DELAY' bit flags do something to show which A/D input had 'NEW' reading and it would be nice to calculate the next-next A/D input return from interupt END INTERUPT SUBRTN if 'CONVERSION DELAY' bit flag set clear 'CONVERSION DELAY' bit flag set 'START CONVERSION' bit flag return from subroutine else clear 'START CONVERSION' bit flag start conversion return from subroutine END SUBROUTINE and in the main body of the program test for the bits 'CONVERSION DELAY' OR 'START CONVERSION' in the same bit test in one instruction. if either is set, then call SUBRTN. Just make sure that there is enuff cycles between 'TEST's to let the A/D input settle, and that the numbers of cycles between three 'TEST's calls are not greater than the interupt timer. It is necessary to have the two part routine to insure that if an interupt occures just before a 'TEST' instruction, there will be a delay before the conversion is started. After writting this, I see another way to switch A/D inputs. Just run the interupt timmer twice as fast and... INTERUPT if 'START CONVERSION' bit flag clear read A/D select 'NEXT A/D INPUT' store A/D reading set 'NEW' and 'START CONVERSION' bit flags indicate which A/D input is 'NEW' ('LAST A/D INPUT') set 'START CONVERSION' bit flag return from interupt else (the bit is set) start conversion * do this as soon as possible clear 'START CONVERSION' bit flag good place to move the 'NEXT A/D INPUT' pointer into the 'LAST A/D INPUT' pointer, and calculate 'NEXT A/D INPUT' pointer return from interupt END INTERUPT It may be best to have a 'NEW' bit flag for each A/D input and a seperate register for each A/D input reading. With this method there is an equal amount of time for the input to settle and for the conversion to complete. But still best to test for conversion compete before reading it. Have fun Bill C. bill@cornutt.com The good smelling guy! ---------- > Hi to all engineers. > > I am trying to make analog control A/D generator. I connected > 20 Mhz crystal with 16c71. on output I am getting only 20 Khz. > I know 20/4 = 5 Mhz do you think A/D conversion slowing it down. > Is there any thing I am doing wrong? > > here is my code. > > > TMR0 EQU 0x01 ; COUNTER > PC EQU 0x02 ; PROGRAM COUNTER > STATUS EQU 0x03 ; STATUS REGISTER > FSR EQU 0x04 ; FILE SELECT REGISTER > PORTA EQU 0x05 ; OUTPUTS > PORTB EQU 0x06 > RP0 EQU 0x05 > TRISA EQU 0x05 ; > TRISB EQU 0x06 ; > OPTION_REG EQU 0x81 ; > ADCON0 EQU 0x08 > ADCON1 EQU 0x08 ; > ADRES EQU 0x09 > PCLATH EQU 0x0A > INTCON EQU 0x0B > CARRY EQU 0x00 ; CARRY BIT > DCARRY EQU 0x01 ; DIGIT CARRY BIT > PDOWN EQU 0x03 ; POWER DOWN BIT > WATDOG EQU 0x04 ; WATCHDOG TIMEOUT BIT > F EQU 0x01 > Z EQU 0x02 > PORTA EQU 0x05 ; PIN > PORTB EQU 0x06 ; INPUTS FROM DIP SWITCH > CH_1_RESOLT EQU 0x0C ; TEMP REGISTER > CH_2_RESOLT EQU 0x0D > CH_3_RESOLT EQU 0x0E > CH_4_RESOLT EQU 0x0F > COUNT EQU 0x1D > COUNT1 EQU 0x1C > TEMP EQU 0x1E > > LIST P=16C71 > ERRORLEVEL -302 > > > #DEFINE BANK1 BSF STATUS,RP0 > #DEFINE BANK0 BCF STATUS,RP0 > > > ORG 00H > GOTO INIT > > ; ****************** SUBROUTINES ********************** > DELAY > MOVF CH_1_RESOLT,W ; LOAD DECIMAL .25 TO COUNT > MOVWF COUNT ; SAVE IT THERE > > DECFSZ COUNT,F ; DECRIMENT COUNT2 > GOTO $ - 1 ; IF NOT JUMP > RETURN > > > ; ****************** INITALISATION ******************** > > INIT CLRF PORTB > BANK1 ; SET UP PAGE 1 > MOVLW B'00000000' > MOVWF TRISB ; B0 AND B1 INPUTS THE REST OUTPUTS > MOVLW B'00011111' > MOVWF TRISA ; SET AS INPUTS A4 OUTPUT > MOVLW B'00000000' > MOVWF ADCON1 ; SET A/D INPUTS ON A0/1 REST DIGITAL > BANK0 ; RETURN TO PAGE 0 > MOVLW B'11000001' ; SET A/D INTERNAL RC CLOCK AND 11 FOR > CH 4 > MOVWF ADCON0 ; DO IT > > ; ****************** THE START ************************ > > MAIN > BSF PORTB,2 > BSF ADCON0,2 ; START CONVERSION > BSF PORTB,0 > CALL DELAY > BCF PORTB,0 > CALL DELAY >* remove MOVLW 10 ; THIS LINE IS 10 >* remove MOVWF TEMP >* remove DECFSZ TEMP,F ; WAIT A WHILE >* remove GOTO $-1 > BTFSC ADCON0,2 ; TEST FOR END OF CONVERSION > GOTO $-1 > MOVF ADRES,W ; LOAD A/D RESULT INTO W > MOVWF CH_1_RESOLT ; STORE IT > > > GOTO MAIN > > END >