Thanks Dwight, I tried that, but it didn't help. The interrupt isn't happening at all.
Thanks Dwight, I tried that, but it didn't help. The interrupt isn't happening at all.
Just thinking out loud now...
some possibilities:
What is the source for the timer clock?
What is the prescaler value?
Did you properly enable the timer interrupt?
(with the 12f683 it is the PIE1 reg)
INTCON reg setup correctly?
I can't remember exactly why right now... but at the end of my timer interrupt service routine I had these two lines, which clears bit 0 of these two registers. I think it clears the interupt flags so that when the "ENABLE" statement is hit(at then end of the interrupt handler code), it does not immediatly, falsely, re-interrupt.
These are just my musings and I too am a newbie at this stuffCode:intcon.0 = 0 PIR1.0 = 0
If all else fails then write a small snippet of code that just tests one portion of your code to try and narrow the problem down.
Do not forget to make the chip .pdf manual your best friend... you must, must, must read it! (a section at a time) go to the section on timers and on interupts and see what it tells you.
That, in my opinion, is really the BIG difference between the versatility of the PIC micros and of something like the basic stamp. The PIC has much to offer and therefore much to configure correctly.
Good luck
Dwight
Internal oscillator, I think I've selected this properly, but I'm not sure.What is the source for the timer clock?
It should be 8 - I hope.What is the prescaler value?
I tried to. I suspect this is where I need the help.Did you properly enable the timer interrupt?
Once again, I'm not sure. I tried to.INTCON reg setup correctly?
I've read this, and other sections many times, but I really am starting from scratch here. I've nutted out quite a few things, but so much of the terminology is unfamiliar to me that it's not always clear.Do not forget to make the chip .pdf manual your best friend... you must, must, must read it!
Below is text copied from the 16f690 docs...
Section 6.7 Timer1 Interrupt
The Timer1 register pair (TMR1H:TMR1L) increments
to FFFFh and rolls over to 0000h. When Timer1 rolls
over, the Timer1 interrupt flag bit of the PIR1 register is
set. To enable the interrupt on rollover, you must set
these bits:
• TMR1ON bit of the T1CON register
• TMR1IE bit of the PIE1 register
• PEIE bit of the INTCON register
• GIE bit of the INTCON register
The interrupt is cleared by clearing the TMR1IF bit in
the Interrupt Service Routine.
Note: The TMR1H:TTMR1L register pair and the
TMR1IF bit should be cleared before
enabling interrupts.
I feel your pain!
Dwight
Can't help with the interupts for now but will offer a suggestion for your A/D part. I'm not sure how you got the numbers to compare and set the servo output values. Your variable "temp" will only get a value somewhere between 0 and 1023 due to the 10bit A/D.
I would suggest using the SELECT CASE to compare your 6 A/D value possibilities. List the "Values" in ascending order and this will set your "POSITION" value as needed.Code:FINDPROGRAM 'SELECTS BETWEEN SEVERAL TYPES OF MOTION ADCIN 10, TEMP 'READ CHANNEL 10 TO TEMP IF TEMP = 15000 THEN POSITION = 125 'USES VOLTAGE DIVIDER TO IF TEMP 15000 AND TEMP = 22000 THEN POSITION = 150 'VARY THE VOLTAGE ON CH10. IF TEMP 22000 AND TEMP = 35000 THEN POSITION = 175 'THIS CONVERTS AND STORES IF TEMP 35000 AND TEMP = 47000 THEN POSITION = 200 'TO 'TEMP'. IF TEMP 47000 AND TEMP = 60000 THEN POSITION = 225 IF TEMP 60000 THEN POSITION = 250 GOSUB SETPULSE RETURN
Code:FINDPROGRAM 'SELECTS BETWEEN SEVERAL TYPES OF MOTION ADCIN 10, TEMP ' Note: Value returned will be anywhere from 0 to 1023 SELECT CASE TEMP CASE Value1: POSITION = 125 'TEMP = Value1, lowest value CASE is <= Value2: POSITION = 150 'TEMP <= Value2 CASE IS <= Value3: POSITION = 175 'TEMP <= Value3 CASE IS <= Value4: POSITION = 200 'TEMP <= Value4 CASE IS <= Value5: POSITION = 225 'TEMP <= Value5 CASE Value6: POSITION = 250 'TEMP = Value6, highest value END SELECT GOSUB SETPULSE RETURN
Louie
Thanks for the input Link, I'll have to have a look at that code, it looks smaller than mine.
The way I've done it works currently though. When I cut and pasted code it seems some characters didn't come across for some reason. the individual lines should look more like:
I don't know why, but the ADC values do come out between those values; they go all the way up to 65535 with full voltage. I tried to calculate how they'd come out before I coded it, but ended up just adjusting them after seeing the output. If anyone knows why that'd be interesting.Code:IF TEMP > 22000 AND TEMP <= 35000 THEN POSITION = 175
Still need help with the interrupts though.
I've since added every single registry setting I could find in, and i got it off the ground, but it's giving me very strange results. I'll post more details once the kids are in bed.![]()
Hi, BB
your code doesn't compile at all ...
from MCS ...
add to that most of the operators and tokens are missing, your TMR1 calculations are false ( Where's the prescaler you've set to 8, gone ??? ), TMROFF calculations also false, your HSEROUT command syntax is not correct ...FATAL ERROR: Too many errors. (21)
ERROR Line 53: Bad expression or missing THEN. (AdCServo.pbp)
ERROR Line 53: Syntax error. (AdCServo.pbp)
ERROR Line 54: Bad expression or missing THEN. (AdCServo.pbp)
ERROR Line 54: Syntax error. (AdCServo.pbp)
ERROR Line 55: Bad expression or missing THEN. (AdCServo.pbp)
ERROR Line 55: Syntax error. (AdCServo.pbp)
ERROR Line 56: Bad expression or missing THEN. (AdCServo.pbp)
ERROR Line 56: Syntax error. (AdCServo.pbp)
ERROR Line 57: Bad expression or missing THEN. (AdCServo.pbp)
ERROR Line 64: Bad expression. (AdCServo.pbp)
ERROR Line 65: Bad expression. (AdCServo.pbp)
ERROR Line 66: Bad expression. (AdCServo.pbp)
ERROR Line 71: Bad expression. (AdCServo.pbp)
ERROR Line 72: Bad expression. (AdCServo.pbp)
ERROR Line 73: Bad expression. (AdCServo.pbp)
ERROR Line 82: Bad expression. (AdCServo.pbp)
ERROR Line 83: Bad expression. (AdCServo.pbp)
ERROR Line 91: Bad expression. (AdCServo.pbp)
ERROR Line 101: Bad expression. (AdCServo.pbp)
and the servo pulse values do not match 0 and 180° positions !
Ok, I stop here ...
You'd better rewrite your PROJECT on a white sheet from very start ...
Would be much better ( and quicker ) than trying to correct what you've done ...
AND I did forget last, but not least ... do not use " ON INTERRUPT " as timing is critical here ... only ASM interrupts will fit here ... IF you insist on using interrupts - that are not at all compulsory in such a project -
Alain
Last edited by Acetronics2; - 25th March 2010 at 09:51.
************************************************** ***********************
Why insist on using 32 Bits when you're not even able to deal with the first 8 ones ??? ehhhhhh ...
************************************************** ***********************
IF there is the word "Problem" in your question ...
certainly the answer is " RTFM " or " RTFDataSheet " !!!
*****************************************
As mentioned above, I've added every single register entry that I could find that was related to timer1.
The interrupt now executes, but I'm getting weird results.
Firstly here's the code for the registry entrys I've added:
I'm thinking I've added too many, but I don't really know how they work - even after reading the datasheet several times. If anyone has any comments to make about these I'd be most grateful, I really am trying to learn.Code:T1CON = %00110001 'ENABLE X,X,PRESCALER = 8,X,X,X,TMR1ON INTCON = %11001000 'ENABLE GIE,PEIE,x,x,GPIE,x,x,x GIE var INTCON.7 PEIE var INTCON.6 TMR1IE var PIE1.0 TMR1ON var T1CON.0 TMR1IE = 1 ' PEIE = 1 'WHO KNOWS GIE = 1 'WHAT ALL OF PIR1.0 = 0 'THESE DO, BUT IT TMR1H = 0 'DIDN'T START TMR1L = 0 'WITHOUT THEM.
Here's the interrupt routine again:
and here's the results on the serial port:Code:DISABLE' INTERRUPT INTCODE: IF SERVO1 = 0 THEN HSEROUT ["FIRST IF - POSITION: ",DEC POSITION,10] TMR1H = ((65535 - POSITION)/256) 'EXTRACT HIGH BYTE INTO TIMER1 TMR1L = ((65535 - POSITION)-(TMR1H*256)) 'EXTRACT LOW BYTE HSEROUT ["HIGH: ", DEC TMR1H," LOW: ", DEC TMR1L,10] SERVO1 = 1 HSEROUT ["SERVO1: ",DEC SERVO1,10,10] ENDIF IF SERVO1 = 1 THEN HSEROUT ["SECOND IF - TMROFF: ",DEC TMROFF,10] TMR1H = ((65535 - TMROFF)/256) 'EXTRACT HIGH BYTE INTO TIMER1 TMR1L = ((65535 - TMROFF)-(TMR1H*256)) 'EXTRACT LOW BYTE HSEROUT ["HIGH: ", DEC TMR1H," LOW: ", DEC TMR1L,10,10,13] SERVO1 = 0 HSEROUT ["SERVO1: ",DEC SERVO1,10,10] ENDIF INTCON.0 = 0 PIR1.0 = 0 RESUME ENABLE' INTERRUPT
FIRST IF - POSITION: 225
HIGH: 12 LOW: 64
SERVO1: 0
This is where it gets weird. I'm trying to extract the high and low bits for timer1, ie. I want the timer to countdown for the amount of time stored in 'position'. So the timer has to equal 65535 - Position. I need to break this down into the high and low bits for tmr1H and tmr1L. So tmr1H = 65535 - position / 256 etc. (much thanks to Aratti for helping me with that).
The strange thing is the value that the PIC has calculated for high and low.
high should equal (65535 - 225(value for position is shown in serout))/256 = 255.11 (I know we'll lose the .11)
Low should equal ((65535 - 225)-(255*256) = 30
of course this last value won't be correct until the first one comes out right, but even with the first incorrect value from formula one in place it's still all wrong.
I can't figure it out. Why so far out?
It looks too simple to go wrong. I'm missing something.
Can hair be glued back in?
I can't find a smilie for crying desperately...
Hey Ace, thanks for looking it over.
As mentioned briefly above, when I cut and pasted my code, it seems a lot of the symbols didn't come across. I'll repost here:
I hope it worked this time, dunno what went wrong the first time.Code:define OSC 4 ON INTERRUPT GOTO INTCODE DEFINE HSER_TXSTA 20h 'SET THE TRANSMIT REGISTER TO TRANSMITTER ENABLED DEFINE HSER_BAUD 2400 'SET BAUD RATE 'DEFINE ADCIN PARAMETERS Define ADC_BITS 10 'SET NUMBER OF BITS IN RESULT Define ADC_CLOCK 3 'SET CLOCK SOURCE (3=RC) Define ADC_SAMPLEUS 50 'SET SAMPLEING TIME IN uS define LOADER_USED 1 SELECTOR VAR BYTE 'SELECTS PROGRAM TYPE TEMP VAR WORD 'TEMPORY VARIABLE FOR ANY USE POSITION VAR WORD 'POSITION OF SERVO1 1250 - 2500 OFFWIDTH VAR WORD 'HOW LONG THE PULSE NEEDS TO BE OFF FOR FREQ VAR WORD 'FREQUENCY TO RUN THE SERVOS AT PICOSC VAR BYTE BANK0 'TO STORE OSCILLATOR FREQUENCY IN PERIOD VAR WORD 'TEMPORY VARIABLE TO DISPLAY THE PERIOD OF PULSE PRESCALER VAR WORD 'STORES THE TIMER1 PRESCALER VALUE TMROFF VAR WORD 'STORES THE TIME THAT THE SERVO1 PULSE WILL BE LOW RUN VAR BIT 'IS THE PROGRAM RUNNING? ADCON1 = %10000010 'SET PORTA ANALOGUE AND RIGHT JUSTIFY THE RESULT SERVO1 var PORTA.0 'OUTPUT PIN FOR SERVO1 PUSHBUTT VAR PORTA.2 'INPUT PIN FOR PUSHBUTTON TRISB.4 = 1 'INPUT FOR SELECTOR SWITCH PIN 13 TRISA.0 = 0 'MAKES PIN 19 AN OUTPUT FOR SERVO1 TRISA.2 = 1 'MAKES PIN 17 AN INPUT FOR PUSHBUTTON PRESCALER = 8 'DEFINES THE TIMER1 PRESCALER AS 1:8 FREQ = 50 'CONSTANT FREQUENCY FOR THE SERVOS RUN = 0 'TEMPORARY VARIABLE FOR SERVO RUNNING T1CON = %00110001 'ENABLE X,X,PRESCALER = 8,X,X,X,TMR1ON INTCON = %11001000 'ENABLE GIE,PEIE,x,x,GPIE,x,x,x GIE var INTCON.7 PEIE var INTCON.6 TMR1IE var PIE1.0 TMR1ON var T1CON.0 TMR1IE = 1 ' PEIE = 1 'WHO KNOWS GIE = 1 'WHAT ALL OF PIR1.0 = 0 'THESE DO, BUT IT TMR1H = 0 'DIDN'T START TMR1L = 0 'WITHOUT THEM. GOSUB GETOSC MAINLOOP: IF PUSHBUTT = 1 THEN HSEROUT ["HIGH.",13,10] ELSE HSEROUT ["LOW",13,10] ENDIF GOSUB FINDPROGRAM GOSUB STARTPULSE 'GOSUB STOPPULSE GOTO MAINLOOP FINDPROGRAM: 'SELECTS BETWEEN SEVERAL TYPES OF MOTION ADCIN 10, TEMP 'READ CHANNEL 10 TO TEMP IF TEMP <= 15000 THEN POSITION = 125 'USES VOLTAGE DIVIDER TO IF TEMP > 15000 AND TEMP <= 22000 THEN POSITION = 150 'VARY THE VOLTAGE ON CH10. IF TEMP > 22000 AND TEMP <= 35000 THEN POSITION = 175 'THIS CONVERTS AND STORES IF TEMP > 35000 AND TEMP <= 47000 THEN POSITION = 200 'TO 'TEMP'. IF TEMP > 47000 AND TEMP <= 60000 THEN POSITION = 225 IF TEMP > 60000 THEN POSITION = 250 GOSUB SETPULSE RETURN DISABLE' INTERRUPT INTCODE: IF SERVO1 = 0 THEN HSEROUT ["FIRST IF - POSITION: ",DEC POSITION,10] TMR1H = ((65535 - POSITION)/256) 'EXTRACT HIGH BYTE INTO TIMER1 TMR1L = ((65535 - POSITION)-(TMR1H*256)) 'EXTRACT LOW BYTE HSEROUT ["HIGH: ", DEC TMR1H," LOW: ", DEC TMR1L,10] SERVO1 = 1 HSEROUT ["SERVO1: ",DEC SERVO1,10,10] ENDIF IF SERVO1 = 1 THEN HSEROUT ["SECOND IF - TMROFF: ",DEC TMROFF,10] TMR1H = ((65535 - TMROFF)/256) 'EXTRACT HIGH BYTE INTO TIMER1 TMR1L = ((65535 - TMROFF)-(TMR1H*256)) 'EXTRACT LOW BYTE HSEROUT ["HIGH: ", DEC TMR1H," LOW: ", DEC TMR1L,10,10,13] SERVO1 = 0 HSEROUT ["SERVO1: ",DEC SERVO1,10,10] ENDIF INTCON.0 = 0 PIR1.0 = 0 RESUME ENABLE' INTERRUPT SETPULSE: POSITION = POSITION MIN 250 'MIN POSITION LIMITED TO 0 DEGREES POSITION = POSITION MAX 125 'MAX POSITION LIMITED TO 180 DEGREES HSEROUT ["POSITION = ",DEC POSITION,10,13] TMROFF = (((((10000 / FREQ) * 10) / PRESCALER)*10) - POSITION) 'HSEROUT ["TMROFF = ",DEC TMROFF,10,10] 'PERIOD = TMROFF + POSITION 'HSEROUT ["PERIOD = ",DEC PERIOD,10,10] RETURN STARTPULSE: HSEROUT ["PULSE STARTED",10,10] LOW SERVO1 'GIE = 1 'GLOBAL INTERRUPT ENABLE 'PEIE = 1 'PERIPHRIAL INTERRUPT ENABLE TMR1H = 255 'SETS TIMER1 TO 65535 TMR1L = 255 'NEXT TICK WILL INTERRUPT TMR1ON = 1 RETURN STOPPULSE: HSEROUT ["PULSE STOPPED",10,10] LOW SERVO1 PEIE =0 RETURN GETOSC: asm ifdef OSC MOVE?CB OSC, _PICOSC else MOVE?CB 4, _PICOSC endif endasm RETURN END
Bookmarks