Connect with us

16F84A Beginners questions

Discussion in 'Hobby Electronics' started by Mike, Mar 17, 2007.

Scroll to continue with content
  1. Mike

    Mike Guest

    Hi,

    I'm trying to learn some basic embedded programming and I thought I would
    start out with writing a few little programs for gold smart cards.

    I've started out using MPLAB IDE and running my code in the simulator.
    I've written a little program that writes a sequence to the file registers
    0x0020 to 0x004F. The program works, sometimes. After resetting the
    processor and clearing the memory the program will occasionally fail.
    Rebuilding, adding a nop, deleting a blank line all seem to make it work
    again, mostly.

    The first three lines are:

    CLRW
    MOVLW 0x010
    MOVWF FSR

    I've set a break point after this and WREG is showing 0x006 and FSR is
    0x0013.

    I'm sure its something simple and I have no idea what it could be, can any
    one suggest where I should be looking or any tests I can use to try to get
    more info?

    Thanks

    -- Michael Heydon
     
  2. Andy Wood

    Andy Wood Guest

    Why do you clear W if you are going to load 0x010 into it in the next
    instruction?
    You are doing this because you are going to use FSR to address the
    file registers that you want to write the sequence to? If so, why do
    you put 0x010 in it if you want to write to file regs 0x20 to 0x4f ??
    How about you show us a bit more...
    What do you see if you step through it one instruction at a time?


    Andy Wood
     
  3. Mike

    Mike Guest

    That is just me trying to figure out why it wasn't working. I have now
    removed this instruction.
    Sorry typo, I'm writing to registers 0x10 to 0x4f
    Actually, thats a bit wierd, I reset the processor, clear the memory. WREG
    becomes 0, on the first instruction WREG becomes FF, each step WREG
    is decremented by 1. The actual instructions seem to be ignored, FSR
    doesn't change.
     
  4. Mike

    Mike Guest

    I dont have anything setup to trigger interrupts but I'm also not
    disabling them. I don't have any interrupt handling code either.

    Below is the entire program:


    list p=16F84A
    #include <p16F84A.inc>

    ORG 0x000
    goto main

    main

    movlw 0x010
    movwf FSR

    movlw 0x030
    movwf 0x00f

    movlw 0x000

    loop
    addlw 1
    movwf INDF
    incf FSR
    decfsz 0x00f,1
    goto loop

    END

    -- Michael Heydon
     
  5. Copied your code and made a complete program of it:

    #include <p16f84a.inc>
    CLRW
    MOVLW 0x010
    MOVWF FSR
    nop
    end

    Running it on MPLAB IDE v7.20 showed no problem at all. The simulator just
    showed the expected changes. While animated, step by step or run. The latter
    with a breakpoint on the nop of course. So your problem is outside the smal
    part of code you provided. (As expected on my side.)

    BTW. What's the use of clearing W just before writing 0x10 to it?

    petrus bitbyter
     
  6. Mike

    Mike Guest

    *slaps head* of course! I knew it would be something silly like that. That
    explains why adding a nop or removing a blank line makes it work, the IDE
    sees the file has changed and prompts me to rebuild.

    Thanks alot :)

    -- Michael Heydon
     
  7. Mike

    Mike Guest

    I've just been reading about end vs loops/sleep in another thread. I'll
    have to have a play with that.

    Anthony Fremont actually figured out what I was doing wrong in the thread
    above. I was clearing all memory, turns out that includes program memory.
    I'm fairly new at this, and haven't gotten that far yet. Its on my TODO
    list.

    Thanks for your help

    -- Michael Heydon
     
  8. Mike

    Mike Guest

    So your problem is outside the smal
    Turns out it was a user problem rather than a code problem, I was messing
    up the simulator.
    That was me trying to figure out why it wasn't working, it is gone now.

    -- Michael Heydon
     
  9. Alex Gibson

    Alex Gibson Guest

    Best thing to start with is flash a led or two.
    Then build up from there.

    Haven't use an 16f84 or 84A for years.

    A good habit to get into is putting the config fuse line into the asm file,
    so you can always find it easily.

    ; Program works for both 16F628 and 16F877 just change processor
    definition
    ;
    ;
    ;------------------------------------------------------------------------------------------------------------------------
    #define Processor 16F877 ; or 16F628
    ;************************************************************


    if Processor == 16F628
    list p=16f628 ; set processor type
    #include <P16f628.INC>
    __config _CP_OFF & _PWRTE_ON & _HS_OSC & _WDT_OFF & _BODEN_ON &
    _LVP_OFF
    else ;Must be the 16F877
    LIST P=16F877, F=INHX8M
    #include <P16F877.inc>
    ; code protect off debug off program memory write protection off
    ; low voltage programming off brown out detection on , watch dog timer
    off
    ; High speed(>4MHz) xtal program write on
    __config _CP_OFF & _DEBUG_OFF & _WRT_ENABLE_OFF & _LVP_OFF & _BODEN_ON
    & _WDT_OFF & _HS_OSC & _PWRTE_ON
    endif

    ;-------------------------------------------------------------------------------------------------------------------------
    ; VECTORS
    ;-------------------------------------------------------------------------------------------------------------------------

    org 0x00
    reset
    call Setup
    goto Main
    org 0x04
    goto IntService
    Stop
    goto Stop


    ;-------------------------------------------------------------------------------------------------------------------------
    ; Interrupt Service Routine
    ;-------------------------------------------------------------------------------------------------------------------------

    IntService
    retfie

    ;--------------------------------------------------------------------------------------------------------------------------
    ; Setup
    ;--------------------------------------------------------------------------------------------------------------------------
    Setup
    bsf STATUS,RP0 ;
    bcf STATUS, RP1 ; Bank 1 selected
    movlw H'F0'
    movwf TRISB ; High Nibble input, low outputs
    bcf STATUS, RP0 ; Bank 0 selected
    clrf PORTB ; All outputs of Port B reset
    return
    ;--------------------------------------------------------------------------------------------------------------------------
    ; Main
    ;--------------------------------------------------------------------------------------------------------------------------

    Main

    MainLoop
    btfss PORTB,4
    goto LedOff
    bsf PORTB,0
    goto MainLoop
    LedOff
    bcf PORTB,0
    goto MainLoop


    end

    Another simple one but using a delay.

    ;--------------------------------------------------------------------------
    list p=16f877 ; list directive to define processor
    #include <p16f877.inc> ; processor specific variable definitions
    ; configuration fuse settings
    ; code protect off watch dog timer off, brown out enable , program
    write on , high speed oscillator on
    ; write enable on , low voltage programming off and code protect data
    off
    __CONFIG _CP_OFF & _WDT_OFF & _BODEN_ON & _PWRTE_ON & _HS_OSC &
    _WRT_ENABLE_ON & _LVP_OFF & _DEBUG_OFF & _CPD_OFF

    DT0 EQU 0X20 ; name location 0x20 to DT0
    DT1 EQU 0x21 ; name location 0x21 to DT1
    DT2 EQU 0x22 ; name location 0x22 to DT2

    ORG 0x0000 ; program start address

    MAIN ; Main loop
    banksel 0 ; bit set flag RP0 in status
    register ->select bank 0
    clrf TRISB
    clrf PORTB
    banksel 0 ; bit clear flag -> select bank 0
    ;MOVLW .7
    ;MOVWF ADCON1 ;PortA and PortE all digital I/O

    NOW CALL DELAY ; call subroutine delay
    BSF PORTB,0 ; bit set flag porta location 0 to 1
    CALL DELAY ; call subroutine delay
    BCF PORTB,0 ; bit clear flag porta location 0 to 0
    GOTO NOW ; goto label NOW

    ;********* DELAY LOOP ********

    DELAY ; subroutine delay
    MOVLW 0X05 ; move literal 0x05 to W register ->puts 5 in the w reg
    MOVWF DT0 ; move contents of w reg to memory location DT0
    SDEL
    CLRF DT1 ;clear flag DT1
    SD2
    CLRF DT2 ;clear flag DT2 -> set it to 0
    SD1
    DECFSZ DT2 ; decrement DT2 skip next if DT2 is zero
    GOTO SD1 ; GOTO label SD1

    DECFSZ DT1 ; decrement DT1 skip next if DT10 is zero
    GOTO SD2 ; GOTO label SD2

    DECFSZ DT0 ; decrement DT0 skip next if DT0 is zero
    GOTO SDEL ; GOTO label SDEL
    RETURN ; return to calling location

    END ; END of assembly file
     
  10. Alex Gibson

    Alex Gibson Guest

    Don't depend on the simulator to much.

    The more recent versions of mplab are good but old versions pre mplab 5/6
    had all sorts of weirdness.



    Few tips

    1. Always intialise your variables.
    Pic micro controller file registers are not initialised to any specific
    value by
    default. Always initialise your variables to zero to start with, this avoids
    unexpected surprises.

    2. Indent conditionally executing code after a skip instruction
    Doing this makes conditionally executing instructions stand out especially
    when
    debugging.

    3. Let the assembler do the calculations for you.
    Helps make your code more portable to other applications. Saves you having
    to
    work it out and potentially making a mistake.

    4. Use microchip include files without modification

    5. Keep your code as simple as possible
    Makes it a lot easier to debug.

    6. Develop your application in terms of functional blocks and interfaces
    Instead of one large application, develop it as a series of steps or blocks.
    Each
    block should be simulated and tested on hardware before proceeding.

    7. Establish a plan to test and confirm your code is correct
    Test your code each step of the way and do not move on to the next step
    until you
    are 100% satisfied with the performance of the code up to that point.

    8. Avoid changing register banks unless it is absolutely necessary
    Ideally, an application should be designed so that all of the bank 1
    registers and
    hardware are initialised after reset and then execute in bank 0 for the rest
    of the
    application.

    9. Don't allow code to go over page boundaries
    If your code is larger than 2048 instructions place subroutines in the upper
    page.
    Code that is allowed to drift over page boundaries can have problems with
    the
    correct PCLATH register contents.
    Beware when using large tables in your programs place them at the beginning
    if necessary.

    10. Use the __Config for fuse settings
    Look in the definition (include or *.inc) file for the fuse settings for the
    pic you
    are using. Make sure to enable the fuse options you need and disable the
    rest.
    Makes it easy to see what the configuration fuses you are using and stops
    the
    tutors asking difficult questions when you are demonstrating your
    assignments.
    Usually using hex values for config fuses means you don't understand them
    and
    just copied it from someone else or from the net.
    If you are using the watchdog timer, keep it disabled until you have
    finished
    debugging all the other functions.

    11. Simulate as much of your application as possible
    The time used to develop a stimulus file and single step through it will be
    saved
    several times over in the time needed to debug the application if simulation
    has
    not been carried out.

    12. Keep subroutine calling to a minimum
    Pics have a limited stack and are not designed for recursive functions in
    applications. This means minimize calling subroutines from inside other
    subroutines. For both 16f628 and 16f877 make sure, the maximum calling depth
    is less than eight.
    NB interrupt handlers use the same stack. To work out maximum calling depth,
    add the maximum depth of the interrupt handler execution with the maximum
    depth of the main part of the program.

    13. Double check the part number on the pic you have.
    Some pics have two versions - original and 'A' version.
    Differences in hardware can be nil or quite a lot. Check the datasheet.
    If the pic your trying to use with your Digital Systems kit is an 'A'
    version you
    Will need to download version 1.95 or higher of winpicprog
    (Look in the winpicprog forum under announcements www.winpicprog.co.uk)
    Taken from "A bakers dozen rules to help avoid application software
    problems"
    pg 520 Programming and Customizing PICmicro Microcontrollers
    by Myke Predko ISBN 0-07-136172-3 2002.
    Alex Gibson version 2.1 01.02.2004
     
Ask a Question
Want to reply to this thread or ask your own question?
You'll need to choose a username for the site, which only take a couple of moments (here). After that, you can post your question and our members will help you out.
Electronics Point Logo
Continue to site
Quote of the day

-