Andre, Bill Cornut's advice is excellent. Have you considered putting the code to generate the output waveform in the interrupt handler, but leave the A to D code in the main loop? A while back, I designed some PIC code for a circuit that went into a ruggedized portable PC that had internal heating elements. This PC was for data collection in test aircraft, the PC had to function at -30 deg C. The PIC had to sample four temp sensors, calculate the required PWM duty cycles for the five heating elements, and generate the five PWM outputs that controlled FETs to switch power to the heaters. I put the A to D code and the calculation code in the main program loop - real easy stuff there. The difficult part was the PWM outputs. The heaters consume a huge amount of power, so all five could not be on at the same time. I had to synchronize and interleave the PWM outputs to not exceed the power budget (and burn up the power supply section!) In the interrupt code, I had a counter that would increment each interrupt. The main loop calculated the start and end count number for each of the five PWM outputs. The interrupt turned on/off the appropriate PWM outputs when the count equalled the start/stop values. Worked great, so I submitted the design. In testing, the client wanted the PWM frequency increased. But I already had the TMR0 prescaler at 0, and the PIC was running at 20Mhz. The interrupt code could not be made smaller, so I decided to modify the TMR0 value from inside the interrupt routine. Since TMR0 caused an interrupt when it rolls from 0xFF to 0x00, TMR0 has a value of 0 when the interrupt routine begins. The first instructions in my interrupt routine (except saving STATUS and W) were to load TMR0 with a new value. This forced the interrupt frequency to increase. To get the maximum PWM frequency, the interrupts happened so often that the main loop code would execute about five instuctions between interrupts. Any faster and the main loop would never get a chance to run! So, try putting your output code in the interrupt handler, and if the top frequency is still inadequate, modify TMR0 in the interrupt handler to force interrupt frequency to increase. Carefully calculate worse-case timing and make sure the main loop gets a chance to execute. Dave Andre Abelian wrote: > 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 > MOVLW 10 ; THIS LINE IS 10 > MOVWF TEMP > DECFSZ TEMP,F ; WAIT A WHILE > 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 > > BSF PORTB,0 > CALL DELAY > BCF PORTB,0 > CALL DELAY > GOTO MAIN > > END