Continue to Site

Welcome to EDAboard.com

Welcome to our site! EDAboard.com is an international Electronics Discussion Forum focused on EDA software, circuits, schematics, books, theory, papers, asic, pld, 8051, DSP, Network, RF, Analog Design, PCB, Service Manuals... and a whole lot more! To participate you need to register. Registration is free. Click here to register now.

RCTIME + TMR0 interrupt problem! headache...

Status
Not open for further replies.

wylee

Full Member level 1
Joined
Feb 17, 2004
Messages
98
Helped
6
Reputation
12
Reaction score
3
Trophy points
1,288
Location
Malaysia
Activity points
1,031
tmr0 interrupt

Hi people,

I currently facing a strange PicBasic interrupt timer problem,

I wanted to create a light sensor using CDS (refer to picture attached) which will take light intensity reading every 3 seconds and send out the result through RS232. PIC used here is PIC16F84A

But whenever the program reaches instruction set call "readCDS" routine, it just hung there, not executing the subsequent "serout" command and rebooted!

I noticed the 'hanging' because when I commented out "readCDS", replacing with "pause 100", it will pause for 100ms and then execute "serout" command

I can't understand why this is happening...why can't it execute "readCDS" which uses RCTIME command. I tested & realized that RCTIME command run prefectly well if no interrupt was used.

The TMR0 prescalar is set to 1:256, TMR0 interrupt is generated every 256us x ( 255 - 38 ) = 55.552ms. A "cntint" is use to count 54 ticks for approx. 3 seconds

Another IMPORTANT thing need to point out, PicBasic Pro in MPLab does not show any error on my codes!

The attached is my PicBaisc code:

'****************************
'Light sensor for PIC16F84A

include "modedefs.bas"

symbol CDS = PORTB.3
CDS_raw var word
CDS_val var byte

symbol TX = PORTB.2
output TX

symbol LED = PORTB.4
output LED

DEFINE OSC 4
DEFINE CHAR_PACING 1000

'Interrupt counter
intcnt var word
int_tick con 54 '3 seconds

Wsave VAR BYTE $20 SYSTEM ' Save-location for the W register
Ssave VAR BYTE bank0 SYSTEM ' Save-location for the STATUS register
Psave VAR BYTE bank0 SYSTEM ' Save-location for the PCLATH register
Fsave VAR BYTE bank0 SYSTEM

DEFINE INTHAND isr 'Tell PBP what code to execute on an interrupt

goto start

ASM
isr
Movwf Wsave
Swapf STATUS,w
Clrf STATUS
Movwf Ssave
Movf PCLATH,w
Movwf Psave
Movf FSR,w
Movwf Fsave

Endasm

TMR0 = 38

intcnt=intcnt+1

if intcnt=int_tick then '3 seconds
intcnt=0

toggle LED
' pause 100
call readCDS 'read light intensity

Serout TX,T2400,["CDS=",#CDS_val,10,13]

endif

ASM
Exit
bcf INTCON,2 ;reset TMR0 overflow
Movf Fsave,w
Movwf FSR
Movf Psave,w
Movwf PCLATH
Swapf Ssave,w
Movwf STATUS
Swapf Wsave,f
Swapf Wsave,w
Retfie
Endasm

start:
intcnt=0
TMR0 = 38
OPTION_REG = %00000111 'prescaler 256us
INTCON = %10100000 'TMR0 overflow timer on

start1:
goto start1

readCDS:
high CDS ' Make CDS pin high
PAUSE 5 ' Let cap charge
RCTIME CDS,1,CDS_raw ' Time & record discharge time

CDS_val = NCD CDS_raw
return

end

'***************************
 

define a timer 0 interrupt routine

IanP,
start1:
goto start1
True, this is an endless loop. it is design to be like that

Here is brief description of how the code supposed to work:
-> when there is no interrupt, the program run a endless loop
-> when interrupt occur (cause by Timer TMR0 overflow, occur every ≈56ms), it will increase the counter tick "intcnt" by 1 and compare if 54 ticks (3 seconds) has pass?
-----> if no, exit interrupt and resume endless loop
-----> if yes, toggle LED output, read light intensity using RCTIME, RS232 out the results using SEROUT, reset "intcnt" to 0, exit interrupt and resume endless loop


The loop will run forever until an interrupt event is occur.
 

picbasic pro rctime example

That is understood.

What do you think about just setting a flag when iterrupt is called (very short interrupt subroutine) and then continuing within the endless loop .. where you execute the rest of the code ..
 

pic tmr0 asm

Hi wylee,
Im also not a PICBASIC but here are my toughts:

I dont like to do that because PIC doesnt like to be in a fast endless loop. when i was a newbe i once tried that and my program also got stuck somewhere. The best way is to put your main code in the endless lope. Run that code only if a flag was set.
i.e. When the interupt will happen, you will set a flag. Then the PIC will return to the main loop. in the loop you will have if (flag), then you will run your main code. You will need to reset the flag again in the main code.

Try that and see...
Good luck.
 

    wylee

    Points: 2
    Helpful Answer Positive Rating
interrupts measure pulse width picbasic pro

Hello

Peplace the position of the CDS and the capacitor

Change port B to O/P and discharge the cap by driving it to OV

Change Port B to I/P and start the timer for counting clock pulse until port b change to high

The count value is relative to the light senstivity

All the best


Bobi
 

picbasic pro timer interrupt routine

gidimiz said:
best way is to put your main code in the endless lope. Run that code only if a flag was set.
i.e. When the interupt will happen, you will set a flag. Then the PIC will return to the main loop. in the loop you will have if (flag), then you will run your main code. You will need to reset the flag again in the main code.
This is actually a really brilliant idea!!!
I will try it out and tell you my result later
 

no interrupts from timer 0

wylee said:
This is actually a really brilliant idea!!!
I will try it out and tell you my result later
Well, I'll tried, shifting all the main code to the endless loop and left a flag in the interrupt routine, it still face the same problem.

The following are my psedo-code
main:
nop
nop

if flag=1 then
readCDS
serout "....."
flag=0
endif
goto main

isr:
tmr0=38
intcnt=intcnt+1

if intcnt=54 then
intcnt=0
flag=1
endif

INTCON.2=0
exit interrupt
 

picbasic rctime

Hi,

Ok. Let look at the function that you are having a problem with:
readCDS:
high CDS ' Make CDS pin high
PAUSE 5 ' Let cap charge
RCTIME CDS,1,CDS_raw ' Time & record discharge time
CDS_val = NCD CDS_raw
I also use a cap to charge, but for somehting else.
I can see that you charge the cap, but where do you cange the pin back to input?
If you charged the cap, then after 5ms ( or what ever time you are using ) the cap is charged. Now you want to count how long it will disscharge. So you have to stop charging it. If you will chage the pin to 0, it will disscharge very fast. Then the only way is to change it to input, and use the internal current flow of the pin to disscharge the cap.
Can you do step by step and see where exactly is gets stuck?
You can uncomment each line at a time and see where you are having the problem.
Let me know...
 

rctime picbasic capacitor

gidimiz,

well, until the command "PAUSE 5", it is still working fine.

Is RCTIME command that give the problem.

Unfortunately RCTIME is a built-in library in PicBasic and I don't have the knowledge to debug their code...all I can guess is that the "RCTIME" routine might had screwed up some registers or stack values

I think the best way to get around this is to write my own RCTIME routine

Anyway, appreaciate for your effort trying to help me...
 

rctime picbasic

Hi,

I searched google and thats what i found:
RCTIME Measure pulse width on a pin
Ok, so from that i understand that you are trying to measure the puls on the pin. What i didnt find is how large is the timer...
So, if you are trying to do what i think you should do it this way:
1. Change pin to output.
2. Make pin charge cap.
3. Wait 10ms
4. Change pin back to input.
5. Check pin = 1. Means that their is a cap there and not floating.
6. Start counter size long.
7. Stop counting when you get interupt on pin low.
8. If counter reaches max. Stop counting and do something else.

Can you draw what you are connecting to this pin with all the values?
Good luck.
 

Status
Not open for further replies.

Similar threads

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Back
Top