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.

bra & WDT Junebug

Status
Not open for further replies.

AtomSoft

Well-Known Member
Code:
;*** Blinky.asm will flash LED 4
;*** Junebug DIP switches 1,2,3 on all others off
list p=18F1320
include <p18f1320.inc>
CONFIG OSC=INTIO2,WDT=ON,WDTPS=256
ORG 0h               ; Originin or Start
movlw b'00111111'    ; Move Binary 00111111 aka $3F
movwf TRISA          ; to TRISA setting the input to all in execpt 7:6
MyTog:
btg LATA,6           ; Toggle bit 6 on/off on LATA (RA6) Which turns on LED4 
					 ; (check assembly schem)(7=0 and 6=1) to turn on LED4
bra $                ; Branch to current locataion  (endless loop)

END

Ok i commented the above code for me to better understand it. But i still get lost sort of.

blueroomelectronics you said:
"The program is actually depending on the WDT to reboot it about once per second."

i know for the 16F series devices the timing is 1/4 of the clock speed. How about the 18F?

for 16F it would be like:
at 4Mhz = 4,000,000 / 4 / 1,000,000 would equal 1us per instruction cycle.

So how would i calculate the time it would take to be reset by wdt ?
 
Last edited:
I think i read it does 1 cycle in 100 nanoseconds so

1,000,000 * 100 Nano = 100,000,000 / 4 = 25,000,000 = 25Mhz?

So that would be the fastest right.

So would it depend on the crystal i have installed right? I can use upto 25mhz so a 20 mhz crystal would be:

20mhz = 20,000,000 / 4 / 1,000,000 = 5 uS (microseconds) per instruction cycle
 
Last edited:
20 mhz

20 mhz xtal will result in .2 microsecond instruction cycle.

1 / 20,000,000 = .00000005

that * 4 = .0000002 or .2 microseconds.

:D
 
why not just use the mhz # ?

So it would be 1 / 20 * 4 - .2 microseconds
or 200 nanoseconds right ?

But using this would make 25mhz 160 nanosecond per instruction which wouldn't be correct.
 
Last edited:
All 16F & 18F divide the oscillator by 4
So a 4MHz osc works out to a 1MHz clock
Depending on what you need you can think in MHz or microseconds. A simple 1/x does the trick.
The WDT has it's own RC clock, it's slow & low power. Often used for rebooting a crash or lockup. That's how the blinky program works.
 
oh ok i lost some files and links earlier. And cant seem to find them even with search. How does one create a delay in ASM?

if i use a loop using a 4mhz/1Mhz clock its .250 microsecond per cycle so can i do a loop until COUNT is 4? Would that make approx 1 sec?
 
Ok Cool i get
Code:
; Delay = 0.5 seconds
; Clock frequency = 4 MHz

; Actual delay = 0.5 seconds = 500000 cycles
; Error = 0 %

	cblock
	d1
	d2
	d3
	endc

Delay
			;499994 cycles
	movlw	0x03
	movwf	d1
	movlw	0x18
	movwf	d2
	movlw	0x02
	movwf	d3
Delay_0
	decfsz	d1, f
	goto	$+2
	decfsz	d2, f
	goto	$+2
	decfsz	d3, f
	goto	Delay_0

			;2 cycles
	goto	$+1

			;4 cycles (including call)
	return

So i just throw that into my code and have fun?
 
It's for the 16F but will work on the 18F.
You have to multiply the $+x by 2 and it's a good idea to use bra (short branch) instead of goto (long branch)

So goto $+1 would become bra $+2
goto $+2 becomes bra $+4

Aside from that it's fine.
 
Code:
;*** Blinky.asm will flash LED 4
;*** Junebug DIP switches 1,2,3 on all others off

list p=18F1320
include <p18f1320.inc>
CONFIG OSC=INTIO2,WDT=ON,WDTPS=256
ORG 0h               ; Originin or Start
movlw b'00111111'    ; Move Binary 00111111 aka $3F
movwf TRISA          ; to TRISA setting the input to all in execpt 7:6
MyTog:
btg LATA,6           ; Toggle bit 6 on/off on LATA (RA6) Which turns on LED4 
					 ; (check assembly schem)(7=0 and 6=1) to turn on LED4
					 ; The rest is a .5 second delay
	cblock
	d1
	d2
	d3
	endc

Delay
			;499994 cycles
	movlw	0x03
	movwf	d1
	movlw	0x18
	movwf	d2
	movlw	0x02
	movwf	d3
Delay_0
	decfsz	d1, f
	bra 	$+4
	decfsz	d2, f
	bra	    $+4
	decfsz	d3, f
	goto	Delay_0
	goto	MyTog

END

This seems to work in MPLab Sim will try it on junebug when i receive it :)
 
Last edited:
Code:
Delay_0
	decfsz	d1, f
	bra 	$+4
	decfsz	d2, f
	bra	    $+4
	decfsz	d3, f
	goto	Delay_0
	goto	MyTog

This puts me in a loop that doesnt go back to the MyTog
Are you sure i just shouldn't add 1 to x ?
 
to find the delay cycle amount is easy:
4 Mhz is used here

4mhz / 4 = 1 million instruction cycles per second
now multiply delay for this im going to use 1/2 a second .5 seconds

.5 x 1,000,000 = 500,000 instruction cycles every .5 seconds

for 2 seconds would be

2 x 1,000,000 = 2,000,000

Now how do i create my own loop?(manually) like what if i dont have internet where im at? Im going to study this cal output more to try to find out how it works but any info would be awsome. Oh yeah :

Thanks for helping along this long painful learning curve for me :D
 
It has to be even on the 18F, that will eventually branch to MyTog.

Ahh got it, you've left the WDT on!, you either need to reset (CLRWDT) it before it times out or disable it.
Code:
CONFIG OSC=INTIO2,WDT=OFF,LVP=OFF
 
Here it is, working
Code:
;*** Blinky.asm will flash LED 4
;*** Junebug DIP switches 1,2,3 on all others off

    list p=18F1320
    include <p18f1320.inc>
    CONFIG OSC=INTIO2,WDT=OFF,LVP=OFF
    cblock 0x00
    d1
    d2
    d3
    endc
    ORG 0h               ; Originin or Start
    movlw     b'00111111'    ; Move Binary 00111111 aka $3F
    movwf     TRISA          ; to TRISA setting the input to all in execpt 7:6
    movlw    0x62    ; 4MHz
    movwf    OSCCON
MyTog:
    btg LATA,6           ; Toggle bit 6 on/off on LATA (RA6) Which turns on LED4 
Delay
            ;499994 cycles
    movlw    0x03
    movwf    d1
    movlw    0x18
    movwf    d2
    movlw    0x02
    movwf    d3
Delay_0
    decfsz    d1, f
    bra     $+4
    decfsz    d2, f
    bra    $+4
    decfsz    d3, f
    goto    Delay_0
    goto    MyTog

END
 
wouldnt it be simpler to make 3 loops:

Loop 1: FF to 00
Loop 2: goto Loop1 FF times
Loop 3: goto Loop2 07 Times

that would make 455175 cycles. Close to the 500,000 mark not so exact but heh.
but im not sure how to even start this.

decfsz d1, f (confuses me)

Decrement f, skip if 0

f would be d1 but then whats that f there for ?
 
Yes if you don't need exact delays, the delay calc assumes you want exact delays.
The other way to do it is run the PIC at it's slowest speed 31.25KHz.

The f tells it where to store the result, w is the other choice.
 
Code:
The contents of register ‘f’ are decremented.
If ‘d’ is ‘0’, the result is placed in W. 
If ‘d’ is ‘1’, the result is placed back in register ‘f’ (default).

If the result is 0’, the next instruction, which is already fetched, is discarded and a NOP is executed instead, making it a two-cycle instruction.

If ‘a’ is ‘0’, the Access Bank will be selected, overriding the BSR value.
If ‘a’ = 1, then the bank will be selected as per the BSR value (default).
Code:
    decfsz    d1, f
    bra     $+4
    decfsz    d2, f
    bra    $+4
    decfsz    d3, f
    goto    Delay_0
    goto    MyTog

if d1 is h03 and d2 is h18 and d3 is h02 on start its like

1. wait till d1 reaches 00
2. since d1 was 00 we have to minus 1 from d2 so d2-1 and d1
3. d1 = d1-1 = FF
4. start from d1 = ff till reaches 00 and minus d2 again until d2 gets to 0
5. then minus d3 and d1 so d1=FF
6. once d1 = 00 minus d3 again untill d3 = 00 then goto MyTog

or

A. -d1
B. -d2
C. -d3

1. do A until 00
2. do B set d1 to FF and do A
3. do #2 until d2 = 00
4. do C set d1 to FF and do A
5. do A until 00 and do C
6. do #5 until d3 = 00

Is it something like that?
 
If it helps, here's a 20 word Delay subroutine for 18F' devices with Macro "front ends" which make it easy to specify 'exact' delays in Cycles (Tcy), microseconds (US), or milliseconds (MS) with parameter ranges which depend on your Clock frequency.

Enjoy, Mike

Code:
;******************************************************************
;                                                                 *
;  DelayMS() and DelayUS() Macros     Mike McLaren, K8LH, Jun'07  *
;                                                                 *
;  simple 'front end' macros for 24-bit DelayTcy() routines that  *
;  allow you to specify delays in 'usecs' and 'msecs'.            *
;                                                                 *
;  the delay parameter range is based on clock frequency          *
;                                                                 *
;    4 MHz,  1   cycle /usec, 21..16,777,215 us, 1..16,777 ms     *
;    6 MHz,  1.5 cycles/usec, 14..11,184,810 us, 1..11,184 ms (1) *
;    8 MHz,  2   cycles/usec, 11...8,388,607 us, 1...8,388 ms     *
;   10 MHz,  2.5 cycles/usec,  9...6,710,886 us, 1...6,710 ms (1) *
;   12 MHz,  3   cycles/usec,  7...5,592,405 us, 1...5,592 ms     *
;   16 MHz,  4   cycles/usec,  6...4,194,303 us, 1...4,194 ms     *
;   20 MHz,  5   cycles/usec,  5...3,355,443 us, 1...3,355 ms     *
;   24 MHz,  6   cycles/usec,  4...2,796,202 us, 1...2,796 ms     *
;   28 MHz,  7   cycles/usec,  3...2,396,745 us, 1...2,396 ms     *
;   32 MHz,  8   cycles/usec,  3...2,097,151 us, 1...2,097 ms     *
;   36 MHz,  9   cycles/usec,  3...1,864,135 us, 1...1,864 ms     *
;   40 MHz, 10   cycles/usec,  3...1,677,721 us, 1...1,677 ms     *
;   48 MHz, 12   cycles/usec,  2...1,398,101 us, 1...1,398 ms     *
;                                                                 *
;   (1) 6 and 10 MHz clocks produce inprecise timing              *
;                                                                 *
;  DelayMS() and DelayUS() macros require a 'clock' equate;       *
;                                                                 *
clock   equ   32                ; insert your clock freq (MHz)
;                                                                 *
;  DelayMS() and DelayUS() macros;                                *
;                                                                 *
DelayMS macro   msecs           ; delay range: see list above
        DelayUS(msecs*1000)
        endm
DelayUS macro   usecs           ; delay range: see list above
        DelayTcy(usecs*(10000/(4000/clock))/10)
        endm
;                                                                 *
;******************************************************************
;                                                                 *
;  DelayTcy(), 24-bit                 Mike McLaren, K8LH, Jun-07  *
;                                                                 *
;  simple macro for simulation testing;                           *
;                                                                 *
DelayTcy macro  delay           ; parameter 21..16777215
   if delay < 256
        movlw   delay           ; 2 instructions, 3 cycles
        rcall   DelayTcy.byte   ;
   else
     if delay < 65536
        movlw   ~(high(delay))  ; 4 instructions, 5 cycles
        movwf   TMRH            ;
        movlw   low delay       ;
        rcall   DelayTcy.16     ;
     else
        movlw   ~(upper(delay)) ; 6 instructions, 7 cycles
        movwf   TMRU            ;
        movlw   ~(high(delay))  ;
        movwf   TMRH            ;
        movlw   low delay       ;
        rcall   DelayTcy.24     ;
     endif
   endif
        endm
;                                                                 *
;  code for simulation testing;                                   *
;                                                                 *
SimTest DelayMS(2000)           ; DelayTcy(), DelayUS(), DelayMS()
        nop                     ; put simulator breakpoint here
;                                                                 *
;                                                                 *
;******************************************************************
;                                                                 *
;  DelayTcy() subroutine              Mike McLaren, K8LH, Jun-07  *
;                                                                 *
;  20 words, 2 RAM variables (16 bit core)                        *
;                             ^^^^^^^^^^^                         *
DelayTcy.byte
        clrf    TMRH            ;
        comf    TMRH,F          ; compliment TMRH
DelayTcy.16
        clrf    TMRU            ;
        comf    TMRU,F          ; compliment TMRU
DelayTcy.24
        addlw   -24             ; subtract "overhead" + 1 cycle
        bnc     DelayHi         ; borrow?  yes, branch, else
        addlw   1               ; replace unused 'borrow' cycle
DelayLo
        addlw   -3              ; subtract 3 cycle loop time
        bc      DelayLo         ;
DelayHi
        addlw   -3              ; subtract 3 cycle loop time
        incfsz  TMRH,F          ; TMRH done? yes, skip, else
        bra     DelayLo         ; loop again

        addlw   -3              ; subtract 3 cycle loop time
        incfsz  TMRU,F          ; TMRU done? yes, skip, else
        bra     DelayLo         ; loop again
;
;  account for delay%3 timing (3, 4, or 5 cycles before return)
;
        xorlw   0xF7            ;  F7 (1), F8 (1), F9 (1)
        bz      DelayXit        ;  F7 (2), F8 (1), F9 (1)
        xorlw   0xF9^0xF7       ;          F8 (1), F9 (1)
        bz      DelayXit        ;          F8 (1), F9 (2)
DelayXit                        ;  ----------------------
        return                  ;  F7=(3), F8=(4), F9=(5)
;                                                                 *
;******************************************************************
 
Status
Not open for further replies.

Latest threads

New Articles From Microcontroller Tips

Back
Top