PDA

View Full Version : DT_INT trying to use INT_INT, TMR1_INT, HPWM and lots of issues.



lilimike
- 23rd April 2010, 22:44
Hi,
Using 16F627A with 4MHz resonator.
I am having lots of issues here I don't know where to start...

Ok I am driving an ultrasonic Transducer from RB3 and RA3
RB3 is sending HWPM to one pin of the Tx and also feeding RA0 (the input of the chip's comparator. The inverted output (RA3) is connected to the other pin of the Tx.

The Rx is on a different circuit, amplified and going through an external comparator and the final output fed into RB0.

Mesurments on the scope is as expected, see bellow:
CH1 is the 40KHz burst lasting 169uS
CH2 is the signal from the Rx showing my sealing at about 6 feet high.
The time scale is 2.5mS
4276

and this is my code:

@ __config _XT_OSC & _WDT_OFF & _MCLRE_ON & _LVP_OFF & _CP_OFF

DEFINE OSC 4
FLAGS = 0
TRISA = %10111
TRISB = %00000001
CMCON = %110
;T1CON.0=1 ; Start timer1
;INTCON = %10011000
TMR1H = 0:TMR1L = 0

INCLUDE "DT_INTS-14.bas" ; Base Interrupt System
INCLUDE "ReEnterPBP.bas" ; Include if using PBP interrupts

ASM
INT_LIST macro ; IntSource, Label, Type, ResetFlag?
INT_Handler INT_INT, _SignalDetect, PBP, yes
INT_Handler TMR1_INT, _SignalTimeOut, PBP, yes

endm
INT_CREATE ; Creates the interrupt processor
ENDASM

;@ INT_ENABLE INT_INT ; enable external (INT) interrupts
;@ INT_ENABLE TMR1_INT ; Enable Timer 1 Interrupts


;-------------------temp lcd display ----------------------------
LCD_DB4 VAR PORTB.4 ; Set port for 4 bits bus
LCD_DB5 VAR PORTB.5
LCD_DB6 VAR PORTB.6
LCD_DB7 VAR PORTB.7
LCD_RS VAR PORTB.2 ; Set RS bit port
LCD_E VAR PORTB.1 ; Set Enable bit port
LCD_Lines CON 2 ; # of Lines on LCD, 1 or 2 (Note: use 2 for 4 lines)
LCD_DATAUS CON 50 ; Data delay time in us
LCD_COMMANDUS CON 2000 ; Command delay time in us
INCLUDE "LCD_AnyPin.pbp" ; Must go after LCD initialization
Pause 500: LCDOUT $FE,1: pause 250
LCDOUT $FE,$80,"Display test OK"
;------------------------lcd--------------------------------------

Goto main

Main:
hpwm 1, 127,40000 ; Send burst, Ch1, D.Cycle50%, Freq 40Khz
pauseus 169 ; length of burst.
CCP1CON = 0 ; Stop sending HPWM
pauseus 950 ; To prevent Rx from picking up local burst
pause 60
goto main

'---[INT - interrupt handler]-------Got Signal within 60mS
SignalDetect:
@ INT_DISABLE INT_INT
@ INT_DISABLE TMR1_INT
LCDOUT $FE,$C0,dec TMR1H," "
pause 500
@ INT_ENABLE INT_INT
@ INT_ENABLE TMR1_INT
@ INT_RETURN

'---[TMR1 - interrupt handler]------TMR1 Overflow, got no signal
SignalTimeOut:
@ INT_DISABLE INT_INT
@ INT_DISABLE TMR1_INT
LCDOUT $FE,$C0,"No Signal"
pause 500
LCDOUT $FE,$C0," "
@ INT_ENABLE INT_INT
@ INT_ENABLE TMR1_INT
@ INT_RETURN

end

If I REM-out INT_INT or TMR1_INT I endup getting either nothing on the scope orthe HPWM burst is nonstop. For one thing I know I have to somehow define the 60mS timeout for TMR1 but I can't figure it out.

To make a long story short, I would like to accomplish 2 things:
1 - Use INT_INT to pick up the signal from the Rx at RB0 and calculate the distance based on TMR1.
2 - If I get no signal after 60mS I would like to use TMR1_INT to display a different mesage.

I think my code looks simple but obviously too good to be true.

Hopefully someone can help.

Thanks

Mike

HenrikOlsson
- 24th April 2010, 07:16
Hi Mike,
The first thing I noticed was:

;@ INT_ENABLE INT_INT ; enable external (INT) interrupts
;@ INT_ENABLE TMR1_INT ; Enable Timer 1 Interrupts
Which, since you habe these commented out, means that you don't have the interrupts enabled when you get to your Main routine.

Secondly, if you want to use TMR1 to measure the "time of flight" you'll have to set it up as a timer and then start it (T1CON.0=1) when you want to start measuring - probably just as you start sending the 40kHz pulse I guess? (I see you have a T1CON.0 = 1 in there (commented out) but letting the timer free run probably won't work very good.

Third, TMR1 is 16bits wide, at 4Mhz you'll have 1us/tick so if starting at 0 you'll get an interrupt after ~65ms. If that's good enough, simply set TMR1H and TMR1L to 0 before starting it and it'll time out after ~65ms generating the interrupt (if enabled). If you need 60ms you'll have to preload TMR1 with a value other than 0, in this case 5535.

When the SignalDetect interrupt fires you stop the timer and grab the value, then you reset or preset it so it's ready for the next measuring cycle.

Forth, I'm pretty sure you don't need to turn off and on the interrupts in the handlers - what's the reason for doing that?

Just some pointers, I hope it helps.
/Henrik.

lilimike
- 24th April 2010, 13:09
Thanks for the response Henrik,

I had remed out the INT_ENABLE so that I can take a scren shot of my scope results.
removing the ; makes things ugly.

After a while I figured out how to setup the timer delay.

About turning off the interrups in the handlers, I get your point, SignalDetect could not happen since I am not sending HPWM during this stage and I guess I can just have T1CON.0 = 0 at the start of SignalTimeOut.

Well I have started to split my code in sections and just try to make the timer1 overflow and then just make the interrupt on RB0 but unfortunately I burned my last 16F627A.
I had a spare 16F627 but doesn't seam to work so I have to wait for UPS for a couple of days before I can continue.

Thanks,

Mike

Acetronics2
- 24th April 2010, 13:59
Hi, LLMike,

The first thing for me is ...

HPWM max frequency with PBP is ...32767 Hz ...

so, 40 Khz need to use the PWM module " hand configured " .


The second one is ...

DT Interrupts handles by itself the interrupt enable and disable ... as you answered YES for resetFlag ...


The Third one is ...

I would stop TMR1 as it continues to run ... first, to read it comfortably, and second, to avoid a timer overflow ... note you'll have to reset it somewhere ... sooooo ... HAVE to stop it !!!

Alain

lilimike
- 24th April 2010, 14:16
Hi Acetronics,

I saw in the PBP manual the 32767 Hz limit but when I do

HPMW 1,127,40000
I get a straight 40KHz reading on the scope! could it be that it is a maximum suggested and that's why I burned my chip? Cause I would really like to figure out why I burned my chip.

I've rewrote my code but obviously not been able to test until I receive my order.
Does this make more sens?

@ __config _XT_OSC & _WDT_OFF & _MCLRE_ON & _LVP_OFF & _CP_OFF
clear
DEFINE OSC 4
FLAGS = 0
TRISA = %00111
TRISB = %00000001
CMCON = %110
INTCON = %10011000
OPTION_REG = %10000000
TMR1H = 5535
TMR1L = 0
I var byte
tTime var word


INCLUDE "DT_INTS-14.bas" ; Base Interrupt System
INCLUDE "ReEnterPBP.bas" ; Include if using PBP interrupts

ASM
INT_LIST macro ; IntSource, Label, Type, ResetFlag?
INT_Handler INT_INT, _SignalDetect, PBP, yes
INT_Handler TMR1_INT, _SignalTimeOut, PBP, yes

endm
INT_CREATE ; Creates the interrupt processor
ENDASM

@ INT_ENABLE INT_INT ; enable external (INT) interrupts
@ INT_ENABLE TMR1_INT ; Enable Timer 1 Interrupts


;-------------------temp lcd display ----------------------------
LCD_DB4 VAR PORTB.4 ; Set port for 4 bits bus
LCD_DB5 VAR PORTB.5
LCD_DB6 VAR PORTB.6
LCD_DB7 VAR PORTB.7
LCD_RS VAR PORTB.2 ; Set RS bit port
LCD_E VAR PORTB.1 ; Set Enable bit port
LCD_Lines CON 2 ; # of Lines on LCD, 1 or 2 (Note: use 2 for 4 lines)
LCD_DATAUS CON 50 ; Data delay time in us
LCD_COMMANDUS CON 2000 ; Command delay time in us
INCLUDE "LCD_AnyPin.pbp" ; Must go after LCD initialization
Pause 500: LCDOUT $FE,1: pause 250
LCDOUT $FE,$80,"Display test OK"
;------------------------lcd--------------------------------------

Goto main

Main:
hpwm 1,127,40000 ; Send burst, Ch1, D.Cycle50%, Freq 40Khz
pauseus 169 ; length of burst.
CCP1CON = 0 ; Stop sending HPWM
pauseus 950 ; To prevent Rx from picking up local burst
T1CON.0 = 1 ; Start timer1
for I = 1 to 65 ; Do not send another pulse until 65ms+ later.
pause 1
next
goto main

'---[INT - interrupt handler]-------Got Signal within 60mS
SignalDetect:
T1CON.0 = 0 ; Stop timer1
tTime = 255 * TMR1H + TMR1L
LCDOUT $FE,$C0,dec tTime
pause 1000
LCDOUT $FE,$C0," "
TMR1H = 5535
TMR1L = 0
@ INT_RETURN

'---[TMR1 - interrupt handler]------TMR1 Overflow, got no signal
SignalTimeOut:
T1CON.0 = 0 ; Stop timer1
LCDOUT $FE,$C0,"No Signal"
pause 1000
LCDOUT $FE,$C0," "
TMR1H = 5535
TMR1L = 0
@ INT_RETURN


end

Acetronics2
- 24th April 2010, 15:20
as timer1H is a 8 bits register ...

trying to preset it to 5535 will surely show surprising effects ...

might be:

timer1h = $15
timer1l = $9F

...

Alain

lilimike
- 25th April 2010, 04:45
I Thought I knew how to preload the value to get the right timing but you've made me realize that I didn't really know!

But now I know :o

Thank you,

Mike