check my first attempt?

Discussion in 'Programmer's Corner' started by ke5nnt, Oct 6, 2009.

  1. ke5nnt

    Thread Starter Active Member

    Mar 1, 2009
    384
    15
    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


    Code ( (Unknown Language)):
    1.  
    2. ;************************************************************************
    3. ;LED Flasher
    4. ;4 MHZ XT OSC
    5. ;Ryan Goff
    6. ;************************************************************************
    7. ;
    8.         LIST    p=PIC16F628A
    9.         INCLUDE p16f628A.INC
    10. ;
    11. ;************************************************************************
    12.         __CONFIG B'10000100000001'   ;code protection off, low-voltage programming off,
    13.                                     ;Brown-out reset off, MCLRE tied to Vdd, power-up timer on
    14.                                     ;watch-dog-timer off, XT oscillator
    15. ;************************************************************************
    16. COUNT1  EQU     11
    17. ;
    18.         ORG      0x00
    19.         GOTO    START
    20. ;
    21.         ORG        0x04
    22.         GOTO    START
    23. ;
    24. ;************************************************************************
    25. ;Subroutines
    26. QUARTER    MOVLW    .5
    27.         MOVWF    COUNT1
    28. LOOP1    CALL    DELAY2
    29.         DECFSZ    COUNT1
    30.         GOTO    LOOP1
    31.         RETLW    0
    32. ;
    33. DELAY2    CLRF    TMR0
    34. LOOP2    MOVF    TMR0,W
    35.         SUBLW    .60
    36.         BTFSS    STATUS,2
    37.         GOTO    LOOP2
    38.         RETURN
    39. ;
    40. ;*************************************************************************
    41. ;Initialize
    42. START    BSF        STATUS,5        ;SELECT BANK 1
    43.         MOVLW    B'10010111'
    44.         MOVWF    OPTION_REG        ;SELECT TMR0 OPTIONS AND PRESCALER TO 256
    45.         MOVLW    B'00000000'        ;Select all portb pins as outputs
    46.         MOVWF    TRISB            ;Port B according to above
    47.         BCF        STATUS,5        ;setting PR0 to 0 to select bank 0
    48. ;
    49. ;*************************************************************************
    50. QUAD    BSF        PORTB,1            ;TURN ON LED
    51.         GOTO    QUARTER            ;FOR ONE QUARTER SECOND
    52.         BCF        PORTB,1            ;TURN OFF LED
    53.         GOTO    QUARTER            ;FOR ONE QUARTER SECOND
    54.         GOTO    QUAD            ;LOOP FOREVER
    55.         end
    56.  
    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 ;)
     
  2. Tahmid

    Active Member

    Jul 2, 2008
    344
    25
    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).
    Code ( (Unknown Language)):
    1. ;************************************************************************
    2. ;LED Flasher
    3. ;4 MHZ XT OSC
    4. ;Ryan Goff
    5. ;************************************************************************
    6. ;
    7.         LIST    p=PIC16F628A
    8.         INCLUDE p16f628A.INC
    9. ;
    10. ;************************************************************************
    11.         __CONFIG B'10000100000001'   ;code protection off, low-voltage programming off,
    12.                                     ;Brown-out reset off, MCLRE tied to Vdd, power-up timer on
    13.                                     ;watch-dog-timer off, XT oscillator
    14. ;************************************************************************
    15. COUNT1  EQU     11
    16. ;
    17.         ORG      0x00
    18.         GOTO    START
    19. ;
    20.         ORG     0x04
    21.         GOTO    START
    22. ;
    23. ;************************************************************************
    24. ;Subroutines
    25. QUARTER MOVLW    .5
    26.         MOVWF    COUNT1
    27. LOOP1   DECFSZ    COUNT1
    28.         GOTO    LOOP1
    29. ;
    30. DELAY2   CLRF    TMR0
    31. LOOP2    MOVF    TMR0,W
    32.         SUBLW    .60
    33.         BTFSS    STATUS,2
    34.         GOTO     LOOP2
    35.         RETURN
    36. ;
    37. ;*************************************************************************
    38. ;Initialize
    39. START   BSF        STATUS,5        ;SELECT BANK 1
    40.         MOVLW    B'10010111'
    41.         MOVWF    OPTION_REG        ;SELECT TMR0 OPTIONS AND PRESCALER TO 256
    42.         MOVLW    B'00000000'        ;Select all portb pins as outputs
    43.         MOVWF    TRISB            ;Port B according to above
    44.         BCF      STATUS,5        ;setting PR0 to 0 to select bank 0
    45.         CLRF     PORTB
    46. ;
    47. ;*************************************************************************
    48. QUAD    BSF     PORTB,1            ;TURN ON LED
    49.         CALL    QUARTER            ;FOR ONE QUARTER SECOND
    50.         BCF     PORTB,1            ;TURN OFF LED
    51.         CALL    QUARTER            ;FOR ONE QUARTER SECOND
    52.         GOTO    QUAD            ;LOOP FOREVER
    53.         end
    Thanks.
     
  3. ke5nnt

    Thread Starter Active Member

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

    Code ( (Unknown Language)):
    1.  
    2. DELAY2  CLRF     TMR0
    3. LOOP2   MOVF     TMR0,W
    4.         SUBLW    .60
    5.         BTFSS    STATUS,2
    6.         GOTO     LOOP2
    7.         RETURN
    8.  
    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.
     
  4. Tahmid

    Active Member

    Jul 2, 2008
    344
    25
    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.

    Code ( (Unknown Language)):
    1. delay         movlw       .169
    2.               movwf       Reg_1
    3.               movlw       .69
    4.               movwf       Reg_2
    5.               movlw       .2
    6.               movwf       Reg_3
    7.               decfsz      Reg_1,F
    8.               goto        $-1
    9.               decfsz      Reg_2,F
    10.               goto        $-3
    11.               decfsz      Reg_3,F
    12.               goto        $-5
    13.              return
    14.  
    15.  
    Thanks.
     
    Last edited: Oct 7, 2009
  5. jpanhalt

    AAC Fanatic!

    Jan 18, 2008
    5,699
    905
    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

    Code ( (Unknown Language)):
    1.  
    2. ; Delay = 0.25 seconds
    3. ; Clock frequency = 4 MHz
    4.  
    5. ; Actual delay = 0.25 seconds = 250000 cycles
    6. ; Error = 0 %
    7.  
    8.     cblock
    9.     d1
    10.     d2
    11.     endc
    12.  
    13.             ;249998 cycles
    14.     movlw   0x4F
    15.     movwf   d1
    16.     movlw   0xC4
    17.     movwf   d2
    18. Delay_0
    19.     decfsz  d1, f
    20.     goto    $+2
    21.     decfsz  d2, f
    22.     goto    Delay_0
    23.  
    24.             ;2 cycles
    25.     goto    $+1
    26.  
    John
     
  6. Tahmid

    Active Member

    Jul 2, 2008
    344
    25
    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.
     
  7. ke5nnt

    Thread Starter Active Member

    Mar 1, 2009
    384
    15
    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...

    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).

    Code ( (Unknown Language)):
    1.  
    2. QUARTER    MOVLW    0x4F
    3.                 MOVWF    COUNT1
    4.                 MOVLW    0xC4
    5.                 MOVWF    COUNT2
    6. LOOP1       DECFSZ    COUNT1
    7.                GOTO       $+2
    8.                DECFSZ    COUNT2
    9.                GOTO       LOOP1
    10.                RETURN
    11.  

    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
     
Loading...