Problem with the CLKO of the Pic184520 - Page 1
Forum section: electronics / general

author: vodka
author_rank: Frequent Contributor
timestamp: September 21, 2015, 08:02:48 am
content: My project that i am doing is a VCO with the pic18f4520(use the RB0 as out signal) . And this project don't work fine and i suspect that is the oscillator(using Internal oscillator with the option max PLL).I configured the pic with the option (Internal oscillator block, CLKO function on RA6; port function on RA7), then when i put the oscilloscope probe at the pin A6 ,it showed me a straight line of approximately 2 to 3 volts ,then i put the other probe at RB0 for seeing if the pic worked , and YES it worked.Why can't i see the clock out ?

author: vodka
author_rank: Frequent Contributor
timestamp: September 21, 2015, 05:55:08 pm
content: I am swearing as a gipsy and shitting at all their breedwho has written the datasheet for pic18f4520. The configuration bytes that put at the datasheet is inverse,ergo, if the datasheet put that the configuration FOSC is "1001" (Internal oscillator block, CLKO function on RA6; port function on RA7) really at the software programmer is "0110".

author: Scrts
author_rank: Frequent Contributor
timestamp: September 22, 2015, 09:48:22 am
content: I'm always please myself with these type of PIC threads and happy with a move to ARM

author: Bruce Abbott
author_rank: Frequent Contributor
timestamp: September 22, 2015, 08:19:11 pm
content: Code:CONFIG OSC = INTIO7;======================================; MPASM PIC18F4520 processor include;_CONFIG1H EQU H'300001'_OSC_INTIO7_1H EQU H'F9'<18F4520.HEX>:020000040030CA:03000010091F1FB5

author: vodka
author_rank: Frequent Contributor
timestamp: September 23, 2015, 06:46:25 pm
content: Thanks Bruces, i haven't PICKIT2 and i use the Minipro 5.71 of the TL866A.Furthermore , i have other problem : Now when power on the micro at the board trainer , it doesn't work the ISR of the Timer0, but the same program without any change , i test it with the proteus ,it works .I checked the code, checked if the oscillator micro works,checked if the configuration byte of the timer and the interrupt are fine and i put checkpoint at code for seeing for where it passes(all ,less the ISR )I am very confused

author: Bruce Abbott
author_rank: Frequent Contributor
timestamp: September 23, 2015, 11:35:35 pm
content: Quote from: vodka on September 23, 2015, 06:46:25 pmYou have to realize that config bits start out as '1', and are programmed down to '0' when their boxes are ticked. If you set the config bits in your program and tell Minipro to "load all memory" then it should automatically load them according to the values in the Hex file. You might also consider upgrading to the latest Minipro software, version 6.17 (download fromwww.autoelectric.cn/TL866_Main.html).QuotePost your code here and someone might be able to figure out what is causing the problem.

author: vodka
author_rank: Frequent Contributor
timestamp: September 24, 2015, 02:50:00 pm
content: The program is in Mikrobasic" Global variables"Code:program vcodim contador_tiempo as worddim timer0H as bytedim timer0L as bytedim cuentanuevaadc as worddim cuentaviejaadc as worddim tiempo_muestreo as worddim contador as longworddim anterior as boolean' Declarations section"SUBRUTINES 1 AND 2"Code:Sub procedure contimo(dim bits_config,tim0L,tim0H as byte)INTCON = INTCON and 0x7FT0CON = T0CON and 0x00T0CON = bits_configTMR0H = tim0HTMR0L = tim0LINTCON2 = INTCON2 or 0x04INTCON = INTCON or 0xA0 REM HABILITA INTERRUPCION GENERALend subsub function division (dim dividendo as longword , dim divisor as word) as worddim quociente as worddim cierto as booleancierto =0quociente =0while (cierto <> 1)if (dividendo > divisor) thendividendo = dividendo - divisorquociente = quociente + 1else if (dividendo < divisor) thencierto = 1else cierto =1end ifend ifwendresult = quocienteend sub"SUBRUTINES 3"Code:sub procedure config_ADC(dim C_ADCON0,C_ADCON1,C_ADCON2 as byte)INTCON = INTCON AND 0xBFC_ADCON0 = C_ADCON0 AND 0xFDADCON0 = C_ADCON0ADCON1 = C_ADCON1ADCON2 = C_ADCON2'PIE1 = PIE1 or 0x40INTCON = INTCON or 0x40end sub"ISR TIMER0"Code:Sub procedure Timer0_interrupt iv 0x000008T0CON = T0CON AND 0x7fLATD = LATD OR 0x02 '(SNEAK ISR TIMER0)INTCON = INTCON and 0x30 REM DESHABILITA INTERRUPCIONES GENERALES Y LIMPIA FLAG TIMER0if contador_tiempo >= contador then '(BEGIN GENERATOR SQUARE)if anterior = 0 thenLATB = LATB OR 0x01anterior = 1contador_tiempo =0elseLATB = LATB and 0xfeanterior =0contador_tiempo =0end ifend if '(END GENERATOR SQUARE))contador_tiempo = contador_tiempo +1 '(TIME DUTY CICLE SQUARE)tiempo_muestreo = tiempo_muestreo +1 '(TIME SAMPLE ADC)'(RECHARGE TIMER0)TMR0H = timer0HTMR0L = timer0LLATD = LATD AND 0xFD'(END SNEAK ISR TIMER )INTCON = INTCON or 0xc0T0CON = T0CON or 0x80end sub"1 PART OF MAIN"Code:main:dim capullo as worddim tmp1 as byteTRISD =0IPR1=0IPR2=0timer0L =0xfatimer0H =0xffRCON = RCON and 0x3fRCON = RCON or 0x80 rem habilita interrupcione scon prioridadOSCTUNE = OSCTUNE and 0x00' PLL INTERNO'OSCTUNE = OSCTUNE OR 0x5FOSCCON = OSCCON and 0x00OSCCON = OSCCON or 0x76LATD = 0x01contimo(0x08,timer0L,timer0H) rem valores prueba revisar despuesconfig_ADC(0x01,0x0E,0x9B)tiempo_muestreo = 0contador = 10capullo =0TRISB = 0x00TRISA = 0x01anterior =0'INTCON = 0xA0T0CON = T0CON OR 0x80"2 PART OF MAIN"Code:'CHIVATO CONFIGURACION OSCILADOR(SNEAK OSC CONFIGURATION)if T0CON = 0x88 thenLATD = LATD OR 0x08end if'FIN CHIVATO CONFIGURACION OSCILADOR(END SNEAK OSC CONFIGURATION)' ADCON0 = ADCON0 or 0x02while(true)LATD = LATD OR 0X04 'CHIVATO WHILE(SNEAK WHILE)' MUESTREO DEL ADC(SAMPLE ADC)if tiempo_muestreo >= 1000 thenADCON0 = ADCON0 or 0x02'ESPERA CONVERSION (WAIT CONVERSION)while ( ADCON0 and 0x02 =0 )capullo = capullo +1wendcuentaviejaadc = cuentanuevaadctmp1 = ADRESHcuentanuevaadc= tmp1cuentanuevaadc = cuentanuevaadc << 8cuentanuevaadc = cuentanuevaadc OR ADRESLend if' FIN MUESTREO ADC(END SAMPLE ADC)'CALCULA CUENTA NUEVA (CALCULATE NEW COUNT)if cuentanuevaadc <> cuentaviejaadc THENcontador = (cuentanuevaadc *100)'contador = contador /2048contador = division(contador,2048)contador_tiempo=0cuentaviejaadc = cuentanuevaadcend if'FIN CALULA CUENTA NUEVA(END CALCULATE NEW COUNT)wend' Main programend.

author: Bruce Abbott
author_rank: Frequent Contributor
timestamp: September 27, 2015, 05:24:41 am
content: Timer0 is counting cpu cycles directly (no prescaler) so it will overflow after only 6 cpu cycles. Since it takes about 6 cycles just to exit the interrupt routine, the main program will slow to a crawl because it is being constantly interrupted! Also you are stopping the timer and reloading it, which may cause timing jitter because interrupt latency varies depending on which instruction gets interrupted.You should increase the timer period to give enough time for the rest of your program to work. If this makes the square wave's frequency and/or resolution too low then you will have to use some other technique that has less overhead (eg. hardware PWM generator).A suggestion on coding style:-your code is quite hard to follow because you are not using symbolic names for the SFR bits. It took me a long time just to verify that the bits in each register were being set correctly (some aren't, but luckily are not affecting program operation).For example,Code:INTCON = INTCON and 0x30What does the 0x30 do? We have to convert it to binary, determine which bits are being cleared, and read the datasheet to figure out what they do.But if you coded it like this,Code:INTCON.GIE = 0INTCON.TMR0IF = 0then your intention becomes clear.This also helps avoid bugs that could be hard to find. Your code is clearing the RB0 and Port B pin change interrupts. Perhaps that was your intention, but it may cause trouble if you ever decide to use those other interrupts (you will probably have forgotten what the number 0x30 does, then spend hours trying to figure why some interrupts are going missing!).

author: RogerRowland
author_rank: Regular Contributor
timestamp: September 27, 2015, 06:51:51 am
content: Quote from: Bruce Abbott on September 27, 2015, 05:24:41 amEh? That's not what it's doing. If it's effectively AND'ing itself with 0x30, it's clearing every bit except TMR0IE and INT0IE, which it leaves untouched.Not clear at all, but certainly not equivalent to what you suggested.

author: Bruce Abbott
author_rank: Frequent Contributor
timestamp: September 27, 2015, 04:51:58 pm
content: Quote from: RogerRowland on September 27, 2015, 06:51:51 amYes, but the comment on that line says "DESHABILITA INTERRUPCIONES GENERALES Y LIMPIA FLAG TIMER0" (disable general interrupts and clear timer0 flag) so I'm guessing hisintentionwas to only change those 2 bits.QuoteThe other bits that were being cleared should already be low (RBIE, INT0IF, RBIF) or have no effect (PEIE) soin this casemy code is equivalent.

author: vodka
author_rank: Frequent Contributor
timestamp: September 28, 2015, 09:29:09 am
content: Thanks Bruce for helping me , and i proved to increase the timer count(timer0L =0xFA to timer0L =0xFA ) as you said, but it neither didn't work.Today ,i awaked that i put high the debug icd in the configuration bytes , and then i disenabled the ICD debug and it workedAfter i sought info of the protocol ICD , i found an old datasheet(DS51242A.) that it explained when the icd is enabled all interrupt are disabled.