check my first attempt?

Thread Starter

ke5nnt

Joined Mar 1, 2009
384
Ok, so I wrote up my first attempt at a program using assembly for the 16F268A (its what I've got). I was wondering if you could look over what I wrote and tell me if I made mistakes.

I should mention I hooked it up and its not operating properly, so I know there's got to be something wrong.

It is supposed to flash an LED on and off, on for 1/4 second (250ms) off for 1/4 second, repeat.

What its actually doing when hooked up: Keep LED on forever

Something to keep in mind: RB1 is going through THIS LL MOSFET before it goes to the LED. I'm doing this because I'm using an existing project as a prototype for the PIC in an effort to enhance the original project, and it will ultimately be flashing 2 banks of 30 LEDs alternately.

Pin RB1 to mosfet gate through resistor to ground.
MOSFET source to ground
MOSFET drain to LED cathode
LED anode to 9V


Rich (BB code):
;************************************************************************
;LED Flasher
;4 MHZ XT OSC
;Ryan Goff
;************************************************************************
;
        LIST    p=PIC16F628A
        INCLUDE p16f628A.INC
;
;************************************************************************
        __CONFIG B'10000100000001'   ;code protection off, low-voltage programming off,
                                    ;Brown-out reset off, MCLRE tied to Vdd, power-up timer on
                                    ;watch-dog-timer off, XT oscillator
;************************************************************************
COUNT1  EQU     11
;
        ORG      0x00
        GOTO    START
;
        ORG        0x04
        GOTO    START
;
;************************************************************************
;Subroutines
QUARTER    MOVLW    .5
        MOVWF    COUNT1
LOOP1    CALL    DELAY2
        DECFSZ    COUNT1
        GOTO    LOOP1
        RETLW    0
;
DELAY2    CLRF    TMR0
LOOP2    MOVF    TMR0,W
        SUBLW    .60
        BTFSS    STATUS,2
        GOTO    LOOP2
        RETURN
;
;*************************************************************************
;Initialize
START    BSF        STATUS,5        ;SELECT BANK 1
        MOVLW    B'10010111'
        MOVWF    OPTION_REG        ;SELECT TMR0 OPTIONS AND PRESCALER TO 256
        MOVLW    B'00000000'        ;Select all portb pins as outputs
        MOVWF    TRISB            ;Port B according to above
        BCF        STATUS,5        ;setting PR0 to 0 to select bank 0
;
;*************************************************************************
QUAD    BSF        PORTB,1            ;TURN ON LED
        GOTO    QUARTER            ;FOR ONE QUARTER SECOND
        BCF        PORTB,1            ;TURN OFF LED
        GOTO    QUARTER            ;FOR ONE QUARTER SECOND
        GOTO    QUAD            ;LOOP FOREVER
        end
One more thing to keep in mind. I started trying to learn assembly and PICs a month ago having known nothing about either at all. My learning material consists of one book, one website, the uC datasheet and this forum. So if my mistakes are wretched, give me a smidge of credit and patience ;)
 

Tahmid

Joined Jul 2, 2008
343
Hi,
I have made corrections and slightly modify the Code so that it works. In one month your progress is rapid.

Subroutine is always called not goto. If you use goto,then at the end it will not return proper place, which happened in your case. If absolutely not necessary, it is wise not to call another subroutine within a subroutine. Always clear the ports before using them so that there is no initial high state(latch).
Rich (BB code):
;************************************************************************
;LED Flasher
;4 MHZ XT OSC
;Ryan Goff
;************************************************************************
;
        LIST    p=PIC16F628A
        INCLUDE p16f628A.INC
;
;************************************************************************
        __CONFIG B'10000100000001'   ;code protection off, low-voltage programming off,
                                    ;Brown-out reset off, MCLRE tied to Vdd, power-up timer on
                                    ;watch-dog-timer off, XT oscillator
;************************************************************************
COUNT1  EQU     11
;
        ORG      0x00
        GOTO    START
;
        ORG     0x04
        GOTO    START
;
;************************************************************************
;Subroutines
QUARTER MOVLW    .5
        MOVWF    COUNT1
LOOP1   DECFSZ    COUNT1
        GOTO    LOOP1
;
DELAY2   CLRF    TMR0
LOOP2    MOVF    TMR0,W
        SUBLW    .60
        BTFSS    STATUS,2
        GOTO     LOOP2
        RETURN
;
;*************************************************************************
;Initialize
START   BSF        STATUS,5        ;SELECT BANK 1
        MOVLW    B'10010111'
        MOVWF    OPTION_REG        ;SELECT TMR0 OPTIONS AND PRESCALER TO 256
        MOVLW    B'00000000'        ;Select all portb pins as outputs
        MOVWF    TRISB            ;Port B according to above
        BCF      STATUS,5        ;setting PR0 to 0 to select bank 0
        CLRF     PORTB
;
;*************************************************************************
QUAD    BSF     PORTB,1            ;TURN ON LED
        CALL    QUARTER            ;FOR ONE QUARTER SECOND
        BCF     PORTB,1            ;TURN OFF LED
        CALL    QUARTER            ;FOR ONE QUARTER SECOND
        GOTO    QUAD            ;LOOP FOREVER
        end
Thanks.
 

Thread Starter

ke5nnt

Joined Mar 1, 2009
384
I'm confused on this timer operation. I'm following it in MPLAB SIM, and it keeps getting stuck in LOOP2.

Rich (BB code):
DELAY2  CLRF     TMR0
LOOP2   MOVF     TMR0,W
        SUBLW    .60
        BTFSS    STATUS,2
        GOTO     LOOP2
        RETURN
Help me understand this:
CLRF TMR0 starts TMR0
MOVF TMR0,W Reads TMR0 into W register
SUBLW .60 subtracts W register from 60. W register = 0? So this would be like 60 (minus) 0 = 60?
BTFSS STATUS,2 This tests the zero bit in the status register and skips the next instruction if bit is set (W register=0)

My biggest question on this sequence is, on each loop, shouldn't the W register be decremented by 1 on each pass through LOOP2? I don't see where that is happening.
 

Tahmid

Joined Jul 2, 2008
343
Hi,
W register is decremented but with the increment of timer0, W register is overwritten with timer0 value and by that way, after 60 repetitions,when timer0 value becomes 60, it will make W value 60 and the subtraction value will be zero and then the zero flag will be raised and the PC will be out from loop2.

timer0 is actually not required here. You could do it with another variable like count2 and can do like loop1 by assigning a value to count2 and using decfsz instr.

I am not sure if your delay routine can delay 250ms exactly.

Let me show you an example of accurate delay routine using 3 variables which will delay exactly 250ms when 4MHZ osc is used.

Rich (BB code):
delay         movlw       .169
              movwf       Reg_1
              movlw       .69
              movwf       Reg_2
              movlw       .2
              movwf       Reg_3
              decfsz      Reg_1,F
              goto        $-1
              decfsz      Reg_2,F
              goto        $-3
              decfsz      Reg_3,F
              goto        $-5
             return
Thanks.
 
Last edited:

jpanhalt

Joined Jan 18, 2008
11,087
I think it is good to learn how to do it yourself, then using a site like this makes life easier:

http://www.piclist.com/techref/piclist/codegen/delay.htm

The following code is directly from that site for a delay of 250 mS @ 4 MHz

Rich (BB code):
; Delay = 0.25 seconds
; Clock frequency = 4 MHz

; Actual delay = 0.25 seconds = 250000 cycles
; Error = 0 %

	cblock
	d1
	d2
	endc

			;249998 cycles
	movlw	0x4F
	movwf	d1
	movlw	0xC4
	movwf	d2
Delay_0
	decfsz	d1, f
	goto	$+2
	decfsz	d2, f
	goto	Delay_0

			;2 cycles
	goto	$+1
John
 

Tahmid

Joined Jul 2, 2008
343
Hi Ke5nnt,
Instead of using variables, you can try to use the Timers to make Delay Routine.
Please don't hesitate to ask if you have further queries. We will try to help as much as possible.

I actually liked your inquisitiveness to learn Pic Microcontroller. Thanks.
 

Thread Starter

ke5nnt

Joined Mar 1, 2009
384
Tahmid,

Again, you've been very helpful and informative, and I appreciate your responses. I have a drive to learn this, and I'll stop at nothing in the effort to get there. In response to your explanation about TMR0 and the W register, I understand how it works now. For some reason, MPLAB SIM always gets stuck in loop1 but the program works just fine in the hardware so...

jpanhalt said:
I think it is good to learn how to do it yourself, then using a site like this makes life easier:

http://www.piclist.com/techref/picli...egen/delay.htm
It's actually funny you should bring that to my attention. I managed to find that myself only hours ago and with it, successfully completed the segment of code I needed, and I understand how it works, which is the important thing. See my adjusted code below for the 250ms delay (249.998ms exactly).

Rich (BB code):
QUARTER    MOVLW    0x4F
                MOVWF    COUNT1
                MOVLW    0xC4
                MOVWF    COUNT2
LOOP1       DECFSZ    COUNT1
               GOTO       $+2
               DECFSZ    COUNT2
               GOTO       LOOP1
               RETURN

I know for sure I'll have more questions coming in the near future. Next I will begin working on how to change the flash pattern of my LEDs via a push button input switch. FUN!:D

Thanks to both of you again though, for taking the time to help.

Ryan
 
Top