Continue to Site

Welcome to our site!

Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

  • Welcome to our site! Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

RS232/Timer0/INT code problems.

Status
Not open for further replies.

gregmcc

Member
I'm busy working on a project and have gathered code from a few sources, mainly from Nigel's pic tutorials.

Basically what my code does, or is supposed to do is as follows:

Using a 16F628 I've setup the INT pin to trigger when it detects a pulse from a external source. This calls a interrupt routine which changes a variable.

In my my loop I check if the variable has changed and increment a counter a flash a LED.

I'm also using Timer2 with a counter so that after 60 seconds, another LED is flashed and the value in the counter is sent out pin RB0 via a serial routine to a serial to RS232 converter to the PC when I display the value using hyperterm.

Ok, so most of this works. The pulse is detected which triggers the LED to flash. Every 60 secs the other LED is flashed.

The problem comes in with the RS232 routine. If I jump directly to the routine and bypass the timer0/int checking and get it to send TEST out it works and it displayed correctly on hyperterm. So I presume the hardware is all working and the serial routine is fine.

What I did have to do is comment out 3 x "call Delay255" routines. (At the bottom of the code) With those enabled it somehow breaks the detection of the pulse and flash LED routine. It only works with one Delay255 enabled? Very odd.

The other problem is once I include the RS232 routine with all my other code garbage gets written out to the serial port. A 0x00 value is written out to the serial port everytime INT is triggered?

I"m going crazy trying to figure out where the problem is.

Hope you can make sense of what I'm trying to accomplish.

I've attached the code.

Is there something basic I"m overlooking?
 

Attachments

  • counter.asm
    6.8 KB · Views: 130
I've had a quick look at your code and think that flash_flag is getting higher than 1 when you have any long delays. This wouldn't be a problem except that you check for flash_flag being equal to one. If you change your code to check for non zero then it may solve your problem.
Code:
Loop	
	; check if pulse detected on INT
	movf	flash_flag,f
	btfsc	STATUS,Z
	goto	continue1			; no pulse detected

Also, at the start of the code, you don't select bank 0 and so flash_count may not get zeroed.

Mike.
 
Thanks for the tips. I've added in the select bank 0, and change the flash_flag to no use a increment. Still having problems :( Anything else that might be causing problem?
 
Been thinking about my problem and am still no where near finding a solution. I think its back to basics and need to check if I'm doing things the right way.

Basically I need to monitor a I/O pin, when it goes high increment a counter. Then every 1 minute write the value out to the serial port.

I've got a routine which writes out values to the serial port (from Nigel's tutorial) and this works great. I've also got another routine which uses Timer2 to increment a value. When that value=x I know 60 secs have elapsed. This also works, but when combining the routines together it falls over.

So my question now is, is this the best way to accomplish what I want to do. Was thinking of changing it so that I use Timer0 as a counter and then every 60 secs (determined by Timer2) read the value of the counter and write to serial port? Would this work?

The logic seems so simple but do you think I can get it to work? :(
 
May I suggest a different approach?

Setup B0 interrupt and timer2 to interrupt 100 times per second.

In your ISR do,
Code:
		movwf	w_temp		; save off current W register contents
		movf	STATUS,w	; move status register into W register
		movwf	status_temp	; save off contents of STATUS register
		btfss	INTCON,INTF	;Did B0 cause interrupt
		goto	NotB0		
		incf	flash_flag,f	; change flash flag
		bcf	INTCON,INTF	; clear interrupt flag
NotB0		btfss	PIR1,TMR2IF	;was it timer 2
		goto	Continue
		bcf	PIR1,TMR2IF
		incf	Hundreths,f
		movlw	.100
		xorwf	Hundreths,w
		btfss	STATUS,Z
		goto	Continue
		clrf	Hundreths
		incf	Seconds,f
		movlw	.60
		xorwf	Seconds,w
		btfss	STATUS,Z
		goto	Continue
		clrf	Seconds
		incf	Minutes,f
Continue	movf	status_temp,w	; retrieve copy of STATUS register
		movwf	STATUS		; restore pre-isr STATUS register contents
		swapf	w_temp,f
		swapf	w_temp,w	; restore pre-isr W register contents
		retfie			; return from interrupt

In you main loop you can now do,
Code:
Loop		movfw	Minutes
		btfsc	STATUS,Z
		goto	Loop
		movfw	flash_count
		clrf	flash_count
		clrf	Minutes
		;send it here
		goto	Loop

And the setup code would be,
Code:
		clrf	flash_count	; make sure fash counter is cleared
		clrf	Hundreths
		clrf	Seconds
		clrf	Minutes
		movlw	b'01001101'	;pre=4 post=10
		movwf	T2CON
		bsf	STATUS,RP0
		movlw	.249		;period = 250
		movwf	PR2		;will interrupt 100 times per second
		bsf	PIE1,TMR2IE
		bcf	STATUS,RP0
		bsf	INTCON,GIE
		bsf	INTCON,PEIE
		bsf	INTCON,INTE

Note that the line
Code:
		__config 0x3F25		; use 4Mhz crystal
is really sloppy programming and should be avoided. It has the watchdog timer turned on but you cant tell from the hex. Do this instead
Code:
	__CONFIG _CP_OFF & _WDT_OFF & _BODEN_OFF & _PWRTE_ON & _XT_OSC & _MCLRE_ON & _LVP_OFF

Mike.
 
You sir are a genius! The code works perfectly - just had to change code in the ISR to "incf flash_counter,f"

Otherwise it works perfectly. Ever minute the value gets written out to the serial port using my serial routine.


Been struggling for ages with this! Thanks again!!
 
Status
Not open for further replies.

Latest threads

Back
Top