PDA

View Full Version : ICSP not recognizing..



sirvo
- 11th June 2008, 16:04
Hello..

I've implemented the ICSP and it's working really fine.. BUT, the winpic800 do not recognize the 16f877 at the second time, neither at the thirty... I got to remove pic from the board, disconnect the device and restart.... then it works...

Have anyone the idea of what is going on?

Thanks in advance..

mackrackit
- 11th June 2008, 16:10
Is the software set up to erase before programming?
And what are you doing with MCLR?

sirvo
- 11th June 2008, 16:34
Yeap..

I always erase pic after programming and MCLR is tied like this:

VCC-10K-1N4148-MCLR-VPP(ICSP)

Thanks!!

mackrackit
- 11th June 2008, 16:40
Does it always work the first time?
Try adding capacitors between VDD and VSS. As close as you can to the PIC on both sides. I had a similar problem once with the PICSTART and an 18F'r. ???

sirvo
- 11th June 2008, 18:49
Well, I've tried that too... same thing..

Sometimes it works on the second try... i do not know.. :(

Well, got another problem, could you help again???

I'm trying to make TMR1 interrupt at 36kHz.

It uses a 20Mhz crystal... The code is below:



@ DEVICE pic16F877, HS_OSC ; System Clock Options
@ DEVICE pic16F877, WDT_OFF ; Watchdog Timer
@ DEVICE pic16F877, PWRT_ON ; Power-On Timer
@ DEVICE pic16F877, BOD_OFF ; Brown-Out Detect
@ DEVICE pic16F877, CPD_OFF ; Data Memory Code Protect
@ DEVICE pic16F877, PROTECT_OFF

define OSC 20

INT VAR PIR1.0 ' OVERFLOW flag
START VAR T1CON.0 ' START TMR1
LOAD VAR word

'------- Configurações iniciais --------------------
TRISA = %00000000 ' PORTA
TRISB = %00000000 ' PORTB
TRISC = %00000000 ' PORTC
TRISD = %00000000 ' PORTD
TRISE = %00000000 ' PORTE

INTCON = %11000000 ' enable global interrupt
OPTION_REG = %00000000
ADCON1 = %10001111 ' all digital
T1CON = %00000000 ' TMR1 1:1 prescaler
PIE1 = %00000001 ' Henable TMR1 INT
START = 0
INT = 0
LOAD = 65404 ' INT. 36KHz
'---------------------------------------------------
ON INTERRUPT GOTO SINUS

TMR1L = LOAD.lowbyte
TMR1H = LOAD.highbyte
START = 1
PORTB.0 = 1
MAIN:
GOTO MAIN


DISABLE
SINUS: INT = 0
TMR1L = LOAD.lowbyte
TMR1H = LOAD.highbyte
PORTB.0 = 1 ' JUST TO MEASURE THE FREQ. ON OSCILLOSCOPE
PORTB.0 = 0
RESUME
ENABLE

end


The oscilloscope do not shows 35.9kHz, but 30~33kHz...

Anything I can do?

Thanks again!

mister_e
- 11th June 2008, 19:08
make sure you also disable the LVP mode. This pin have to be loaded to GND when progaming.


And then... when you reload a 16Bit timer you want to add the reload value instead of just dumping the values in. Finally you want to stop it, then add the reload value, the restart the timer.

Depending how accurate you want it, not a bad idea to switch to Darrel's instant INTs (PBP or ASM... where asm is always handy .. )

skimask
- 11th June 2008, 19:13
Try this and see what happens, should give you a 50% duty cycle ~36khz square wave on your o'scope:


@ DEVICE pic16F877, HS_OSC ; System Clock Options
@ DEVICE pic16F877, WDT_OFF ; Watchdog Timer
@ DEVICE pic16F877, PWRT_ON ; Power-On Timer
@ DEVICE pic16F877, BOD_OFF ; Brown-Out Detect
@ DEVICE pic16F877, CPD_OFF ; Data Memory Code Protect
@ DEVICE pic16F877, PROTECT_OFF
DEFINE OSC 20
load con 65468:intcon=$c0:option_reg=0:adcon1=$87:t1con=1:p ie1=1:c var byte
goto main
ON INTERRUPT GOTO SINUS
TMR1L=LOAD.lowbyte:TMR1H=LOAD.highbyte
MAIN: GOTO MAIN
DISABLE
SINUS: if pir1.0=1 then
pir1.0=0:tmr1l=load.lowbyte:tmr1h=load.highbyte:c= c+1:portb.0=c.0
endif
RESUME
ENABLE
END

And take note of Mr_E's note about adding values.

sirvo
- 11th June 2008, 19:41
Thanks for answering..

I've trie instant interrupts but it stays the same..

I've also tried the code you wrote Skimask... the oscil. shows ~50kHz... The load you typed is too large...

Don't know what is wrong.. The oscilloscope is a Tektronix TDS2014.. it is working ok!

Anything else I can do?

Let me tell you something.. I'm using 22p capacitor at the @20Mhz... is that ok?

skimask
- 11th June 2008, 19:45
I've also tried the code you wrote Skimask... the oscil. shows ~50kHz... The load you typed is too large...

Well then change it!

Or perhaps you wish for me to change the LOAD value myself and re-post the exact same code with that one change so you can cut and paste it over and try it again?

I never said my code would be perfect, but your code had a few faults that needed to be corrected.

mister_e
- 11th June 2008, 19:54
How accurate you want it?

Skimask changed the reload value... hence why you have higher value.

try...


@ __CONFIG _HS_OSC & _WDT_OFF & _LVP_OFF & _PWRTE_ON & _BODEN_ON

define OSC 20

INT VAR PIR1.0 ' OVERFLOW flag
START VAR T1CON.0 ' START TMR1
LOAD VAR word

'------- Configurações iniciais --------------------
TRISA = %00000000 ' PORTA
TRISB = %00000000 ' PORTB
TRISC = %00000000 ' PORTC
TRISD = %00000000 ' PORTD
TRISE = %00000000 ' PORTE



OPTION_REG = %00000000
ADCON1 = %10001111 ' all digital
T1CON = %00000000 ' TMR1 1:1 prescaler
PIE1 = %00000001 ' Henable TMR1 INT
START = 0
INT = 0
LOAD = 65404 ' INT. 36KHz
@TIMER1=TMR1L
TIMER1 var word EXT

'---------------------------------------------------
ON INTERRUPT GOTO SINUS

TIMER1=LOAD
INTCON = %11000000 ' enable global interrupt
START = 1
PORTB.0 = 1
MAIN:
GOTO MAIN


DISABLE
SINUS:
@ MOVE?CT 0, T1CON, TMR1ON
TIMER1=TIMER1+LOAD
@ MOVE?CT 1, T1CON, TMR1ON
toggle PORTB.0
INT = 0
RESUME
ENABLE

end
you should have something like 18KHz signal.. so yeah, your interrupt is still 36Khz... i just toggle the pin..

I tend to stay away of ON INTERRUPT when i need accuracy. ASM is the best while DT INST with PBP is still good enough for many purpose.

skimask
- 11th June 2008, 20:04
That is a bit wierd, because what I posted should've had a freq of about 36khz (73.5khz int rate, 20mhz/4=5Mhz instruction rate / 68 = 73.5khz toggling the pin).

If anything, the freq should've dropped BELOW 36khz due to not reloading the timer with 'fixed' values and not compensating for the extra cycles in the interrupt loop.
I get the feeling that the 'scope isn't being read right (i.e. only measuring half of the square wave, not the whole thing)

And yes, I agree completely about DT_INT's vs. ON_Interrupt.

mister_e
- 11th June 2008, 20:31
completely untested, should work anyway...


define OSC 20

include ".\include_routines\DT_INTS-14.bas"

ASM
INT_LIST macro ; IntSource, Label, Type, ResetFlag?
INT_Handler TMR1_INT, _SINUS, ASM, yes
endm
INT_CREATE

endasm


'------- Configurações iniciais --------------------
TRISA = %00000000 ' PORTA
TRISB = %00000000 ' PORTB
TRISC = %00000000 ' PORTC
TRISD = %00000000 ' PORTD
TRISE = %00000000 ' PORTE

OPTION_REG = %00000000
ADCON1 = %10001111 ' all digital
T1CON = %00000000 ' TMR1 1:1 prescaler
PIE1 = %00000001 ' Henable TMR1 INT

@TIMER1=TMR1L
TIMER1 var word EXT

INT VAR PIR1.0 ' OVERFLOW flag
START VAR T1CON.0 ' START TMR1

LOAD CON 65404 ' INT. 36KHz

TIMER1=LOAD
START = 1
@ INT_ENABLE TMR1_INT
PORTB.0 = 1
MAIN:
GOTO MAIN

SINUS:
ASM
MOVE?CT 0, T1CON, TMR1ON ; Stop Timer1
MOVLW LOW(_LOAD) ; Reload timer1
ADDWF TMR1L,F ; but add current Timer
BTFSC STATUS,C ; value
INCF TMR1H,F ;
MOVLW HIGH(_LOAD) ;
ADDWF TMR1H,F ;
MOVE?CT 1, T1CON, TMR1ON ; Start Timer1
ENDASM
toggle PORTB.0
@ INT_RETURN