Electronic Projects, forums and more.

Go Back   Electronic Circuits Projects Diagrams Free > Electronics Categories > Micro Controllers


Micro Controllers Discuss all aspects of micro controllers - building them, coding them, etc. All controllers are welcome - PIC, BASIC, Z8 Encore!, etc.

Reply
 
Tools
Old 18th September 2005, 03:41 PM   #1
Default Delay routine not working

I've tried the delay generator from piclist and I can't seem to get it working. It compiles without errors but the delay doesn't seem to work:

Code:
	LIST	p=16F628		;tell assembler what chip we are using

#include <p16F628.inc>
	__CONFIG   _CP_OFF & _WDT_OFF & _PWRTE_ON & _INTRC_OSC_NOCLKOUT & _LVP_OFF & _BODEN_ON & _MCLRE_OFF

	org	0x0000			;org sets the origin, 0x0000 for the 16F628,
					;this is where the program starts running	
				movlw 7
				movwf CMCON

				clrf PORTA
				clrw
				tris PORTA ; porta all output
				clrf PORTB
				movlw 0xf0 
				tris PORTB
				bsf STATUS, RP0 ; bank 1
				bcf OPTION_REG, NOT_RBPU ;internal pullups on port B enabled
				bcf STATUS, RP0 ;bank 0

	

Loop	
	movlw	0xff
	movwf	PORTA			;set all bits on
	movwf	PORTB

	call Delay

	movlw	0x00
	movwf	PORTA			;set all bits on
	movwf	PORTB

        call Delay

	goto Loop

Delay
; Delay = 2 seconds
; Clock frequency = 4 MHz

; Actual delay = 2 seconds = 2000000 cycles
; Error = 0 %

	cblock
	d1
	d2
	d3
	endc

	;1999996 cycles
	movlw	0x11
	movwf	d1
	movlw	0x5D
	movwf	d2
	movlw	0x05
	movwf	d3
Delay_0
	decfsz	d1, f
	goto	$+2
	decfsz	d2, f
	goto	$+2
	decfsz	d3, f
	goto	Delay_0

			;4 cycles (including call)
	return
end
If however I use the following delay code from Nigels blinking lights tutorial it works fine:

Code:
	LIST	p=16F628		;tell assembler what chip we are using

#include <p16F628.inc>
	__CONFIG   _CP_OFF & _WDT_OFF & _PWRTE_ON & _INTRC_OSC_NOCLKOUT & _LVP_OFF & _BODEN_ON & _MCLRE_OFF

	cblock 	0x20 			;start of general purpose registers
		count1 			;used in delay routine
		counta 			;used in delay routine 
		countb 			;used in delay routine
	endc

	org	0x0000			;org sets the origin, 0x0000 for the 16F628,
					;this is where the program starts running	
				movlw 7
				movwf CMCON

				clrf PORTA
				clrw
				tris PORTA ; porta all output
				clrf PORTB
				movlw 0xf0 
				tris PORTB
				bsf STATUS, RP0 ; bank 1
				bcf OPTION_REG, NOT_RBPU ;internal pullups on port B enabled
				bcf STATUS, RP0 ;bank 0

	

Loop	
	movlw	0xff
	movwf	PORTA			;set all bits on
	movwf	PORTB

	call Delay			
	call Delay	
	call Delay	
	call Delay	
	call Delay
	call Delay	
	call Delay	
	call Delay				; end of 2 secs

	movlw	0x00
	movwf	PORTA			;set all bits on
	movwf	PORTB

	call Delay			
	call Delay	
	call Delay	
	call Delay	
	call Delay
	call Delay	
	call Delay	
	call Delay
	goto Loop


Delay	movlw	d'250'			;delay 250 ms (4 MHz clock)
	movwf	count1
d1	movlw	0xC7
	movwf	counta
	movlw	0x01
	movwf	countb
Delay_0
	decfsz	counta, f
	goto	$+2
	decfsz	countb, f
	goto	Delay_0

	decfsz	count1	,f
	goto	d1
	retlw	0x00
end
gregmcc is offline  
Old 18th September 2005, 04:24 PM   #2
Default

That's what you get for not writing your own code, or at least not understanding it. The way cblock is used is wrong in your program. The article on the Piclist probably assumed readers to know how to properly use cblocks... From MPASM's Help File, cblock section :

cblock - Define a Block of Constants
Syntax
cblock [expr]
label[:increment][,label[:increment]]
endc
Description
Defines a list of named sequential symbols. The purpose of this directive is to assign address offsets to many labels. The list of names end when an endc directive is encountered.

expr indicates the starting value for the first name in the block. If no expression is found, the first name will receive a value one higher than the final name in the previous cblock. If the first cblock in the source file has no expr, assigned values start with zero.
__________________
Time is nature\'s way of keeping everything from happening at once.
http://membres.lycos.fr/jrainville/
Joel Rainville is offline  
Old 18th September 2005, 04:41 PM   #3
Default

Joel, thanks for the reply. I've got it to work using:

Code:
	cblock 0x20
	d1
	d2
	d3
	endc
but if "the first cblock in the source file has no expr, assigned values start with zero" and in the code I have:

Code:
	movlw	0x11
	movwf	d1
	movlw	0x5D
	movwf	d2
	movlw	0x05
	movwf	d3
then whats the difference? why does it work with the 0x20? What am I missing?
gregmcc is offline  
Old 18th September 2005, 04:55 PM   #4
Default

Quote:
Originally Posted by gregmcc
Joel, thanks for the reply. I've got it to work using:

Code:
	cblock 0x20
	d1
	d2
	d3
	endc
but if "the first cblock in the source file has no expr, assigned values start with zero" and in the code I have:

Code:
	movlw	0x11
	movwf	d1
	movlw	0x5D
	movwf	d2
	movlw	0x05
	movwf	d3
then whats the difference? why does it work with the 0x20? What am I missing?
d1, d2 and d3 are variables that you would normally define with equ. Using a cblock is just like using equ, only you don't have to type equ three times and write 3 sequential memory addresses. You tell it the first address, in your case 0x20, and it's gonna increment that number for each line in the cblock after the first variable name. So d2 is given the address 0x21 and d3 0x22.

In the Piclist code, since there is no expr (which means no starting address, unlike Nigel's code which specifies 0x20), d1 is then given address 0x00, d2 0x01 and d3 0x02. This is bad.

Your program is probably gonna wreak havoc writing to these addresses.
For example, take your code

Code:
	movlw	0x5D
	movwf	d2
Remember, d2 points to address 0x02. You will write 0x5D to this location in the above code. The 16F628A datasheet states that address 0x02 contains PCL. Writing to it will make your program execution jump to the instruction at address 0x005D you just wrote to d2, which actually points to PCL instead of a free data location!
__________________
Time is nature\'s way of keeping everything from happening at once.
http://membres.lycos.fr/jrainville/
Joel Rainville is offline  
Old 18th September 2005, 05:05 PM   #5
Default

Ahh - thanks!

that explains why it kept jumping around when I tried it with a simulator
:lol:
gregmcc is offline  
Old 18th September 2005, 05:33 PM   #6
Default

I have tried to understand how many cycles the code takes but could not get exactly the required value of 1,999,996 cycles.

Code:
Delay
			;1999996 cycles
	movlw	0x11
	movwf	d1
	movlw	0x5D
	movwf	d2
	movlw	0x05
	movwf	d3
Delay_0
	decfsz	d1, f
	goto	$+2
	decfsz	d2, f
	goto	$+2
	decfsz	d3, f
	goto	Delay_0

			;4 cycles (including call)
	return
My calculation is Delay_0 takes 1,999,984 cycles, setting up d3..d1 takes 6 cycles, return/call takes 4. Total is 1,999,994. But I guess that's close enough.

Thanks
__________________
L.Chung
eblc1388 is offline  
Old 18th September 2005, 06:23 PM   #7
Default

Quote:
Originally Posted by eblc1388
My calculation is Delay_0 takes 1,999,984 cycles, setting up d3..d1 takes 6 cycles, return/call takes 4. Total is 1,999,994. But I guess that's close enough.
How do you come up with 1,999,984 cycles? I can't even come close to that...

I don't know how to calculate the number of times decfsz takes 2 cycles instead of 1, that's what bugs me.
__________________
Time is nature\'s way of keeping everything from happening at once.
http://membres.lycos.fr/jrainville/
Joel Rainville is offline  
Reply

Tags
delay, routine, working

Thread Tools
Display Modes




All times are GMT. The time now is 11:50 PM.


Electronic Circuits  |  Learning Electronics
eXTReMe Tracker