Making PBP code more modular


Closed Thread
Results 1 to 31 of 31

Hybrid View

  1. #1
    forgie's Avatar
    forgie Guest


    Did you find this post helpful? Yes | No

    Default

    I just feel much more comfortable having 6 files of around 50-100 lines each, each file having a specific task to complete, rather then having one monolithic 400-500 line file. Maybe I just have to break out of the PC programming (C) mentality, where you try and hide code away somewhere else (inside a module) once it is finished and debugged - this is perhaps one of the reasons for the "PBP /= Professional quality" attitude that many have: on a PC one always strives for modular, portable code 100% of the time. On a PIC, by the very nature of the beast that isn't always possible.

    Do you guys follow PC convention in so far as removing 'magic numbers' from your code and using constants to control registers? By this I mean saying something like:

    SLEEP_PORTE CON %00000101
    WAKE_PORTE CON %00000010
    ~

    Sleep:
    PORTE = SLEEP_PORTE
    Sleep
    PORTE = WAKE_PORTE
    Return

    This gives you a convenient place up the top where you can define the PORT states for each 'program state'. Just to give an idea of where I'm coming from.... maybe I need to completely reset my perspective on this whole issue. (Could someone please pull the MCLR attached to my mentality to ground?)

  2. #2
    Join Date
    Jul 2003
    Posts
    2,358


    Did you find this post helpful? Yes | No

    Default

    I've written many programs, the biggest almost six and a half thousand lines (that's a 200kb .BAS file which reated a 8Mb .LST by MPASM!!!)... Like the other replies, I never use include files, but my programs stick to a very rigid and repeatable format... so it is 'modularised' in that form...

    1. Define Configuration Fuses
    2. Define Hardware (usually sequential in Port order)
    3. Define EEPROM (in address order)
    4. Define RAM (always in alphabetical order)
    5. Define Constants (always in alphabetical order)
    6. Subroutines (always in alphabetical order)
    7. Hardware Initialisation
    8. Main Program Loop
    9. Interrupt Handlers (always in alphabetical order)
    10. Error Handlers (always in alphabetical order)

    I don't redefine things that are already included by PBP... ie things like TRISB or OPTION_REG, but I will use the same Label Names as are in the Datasheet and am consistant to use the same variable, hardware or constant names across all my programs if they are doing the same job. Once I have a routine for a particular function (ie reading a keypad or ADC), that routine is replicated EXACTLY and I don't reinvent the wheel. Changes like Timeout values are always predefined constants. Section 2 in my program structure (Hardware Definition) will reassign the pins so that my Keypad routine for example will still work without change or worry regardless of the PIC or PCB layout.

    Keeping to a consistant structure allows me to create programs quickly, with the minimum or errors, allows me find what I'm looking for and best of all, allows me to refamiliarise myself with the program easily, when it needs to be revisted several months down the road. Life is too short, if you have a formula that works, flog it for all that it's worth... (here we go, back to whips and things again)...

  3. #3
    Join Date
    Feb 2003
    Location
    Delaware
    Posts
    30


    Did you find this post helpful? Yes | No

    Default Magic numbers and aliases.

    I write a bit of software and I very seldom use includes. I follow a routine similar to Melanie's in that I tend to structure all of my programs the same way, pretty much as Melanie described. One differance, I usually write my ISR in assembly and stick it at the very top. I also define magic numbers (constants) for things like timer preloads and initial variable states. I also use aliases to define registers. This way my code looks the same, regardless of PIC, because I try and use the same names. I too find that I cut and paste routines when writing code.

    All in all code portablity is pretty good but remember we are talking about micros. I mean, its not like you are gonna run your PBP code on an AVR! Now that would be portable!

    Regards,

    Joe.

  4. #4
    forgie's Avatar
    forgie Guest


    Did you find this post helpful? Yes | No

    Default I've taken your advice and....

    Following the PBP experts lead I went through the task of converting my 7 files project into a single, big momma file. In the process it has helped me tidy up alot of my PBP coding style as well as variable naming. It's taken me a while to adjust to a different style of indenting (and the visual appearance of PBP code is so different to C style code it's really hard to find it readable without doing a hell of a lot of it):

    If oranges = apples Then
    Do something
    Endif

    vs

    If (oranges = apples) {
    Do something;
    }

    Overall I am much more happy with PBP as a language since forcing myself to do it the 'hard' way. I can see perfectly well why C-experienced PC-programming people don't take to it, but I think it's perfectly up to the task that it has in front of it (programming pics, not multimedia software packages).

    Thanks for the tips guys,
    Nick

    EDIT: damn these auto-formatting forums.... the guys who wrote the code must have thought they were being so clever. oh well i hope you get the picture of what i tried (and failed) to show. if not.... well it doesn't really matter, does it?
    Last edited by forgie; - 26th July 2005 at 20:00.

  5. #5
    Join Date
    Jul 2003
    Location
    Colorado Springs
    Posts
    4,959


    Did you find this post helpful? Yes | No

    Default

    WOW, this is very surprising. Nobody uses Includes???

    I can't imagine NOT using them.

    Reasons for my thinking. :

    -- Version Control -- Back when I wasn't using Includes, I'd have the same routine Cut&Pasted into several different programs. While working on one of them I'd have a brainstorm and figure out a better way to do it. Now all the other programs are either stuck with the old version, or I'd have to go back through every program I've written in the past to update their in-line code. Ugg.

    -- Thought Grouping -- As in Melanie's modularized list, Typically any variables, aliases etc. will be placed at the top of the program. But more than likely, the routines in question will be buried deep in the middle of the program, completely isolated from all the other things that go with it. By using Include files, you can keep things grouped together so that you always know what variables or other subroutines are needed to be able to use the said routine.

    -- Ease of use -- If I need an interrupt driven clock or a buffered UART routine. All I need to do is type in 1 or 2 lines. No cut&paste, no variable searching, nothing. Just boom, there it is.

    I always wondered when I wrote an include file for sombody else, why they would take it apart and paste it in 4 different places in their own program. Just doesn't make sense to me. And seemed rude to me at the time.
    But apparently, everybody would do the same thing.

    ----------------

    And, about those "Magic Numbers", don't like 'em
    Do you know how many problems on both the List and the forum have been tracked down to Magic Numbers. The newbie just cut&pastes the code we give them without having a clue how it works. They spend a week trying to figure out why the Code doesn't work, and it turns out to be that T1CON=%00001001 should have been T1CON=%00000001 or something similar.

    Granted, doing it all in one shot saves instruction cycles, and code space. But it sure can cause problems when sharing your code in public forums.

    Best regards,
       Darrel Taylor

    P.S. scroll down to the bottom of the page and click on the vB Code link. There are several ways to format your posts.

  6. #6
    Join Date
    Feb 2003
    Location
    Delaware
    Posts
    30


    Did you find this post helpful? Yes | No

    Default To each his own.

    Darrel,

    I guess that I just never got into the habit of using includes. I almost always have an assembly language ISR at the begining of my programs and I could probably make different ones up with different features and then just include them. But I guess I just never took the time to make sure it would work properly so I don't trust it. I might try it on my next program. If I do I will post a follow up.

    As for magic numbers...I am not sure you follow. A magic number is a nicely named constant that allows you to more easily control your code parameters from one place. Magic numbers make your code easier for newbies to understand because the numbers are given meaningful names.

    Your example of
    T1CON=%00000001

    might look like this
    'CONSTANTS and MAGIC NUMBERS
    TMR1_ON = %00000001 'constant to plug into T1CON to start timer
    TMR1_OFF = %00000000 'constant to plug into T1CON to stop timer
    Some really nice code goes here!
    Main:
    T1CON = TMR_ON 'start timer1
    Some more code.
    T1CON = TMR_OFF 'stop timer1
    goto main

    I usually don't do it this way. I usually alias the register bit and set it equal to 0 or 1.

    TMR1_enable = T1CON.0 'set TMR1_enable to start clr to stop.
    TMR1_enable = 1 'start timer 1
    TMR1_enable = 0 'stop timer 1

    A better example of magic numbers would be
    'Constants--------------------
    buffer_size = 16 'This is how big the buffer is (in chars).
    'Variables----------------------
    buffer var byte[buffer_size] 'This is were the serial in characters go.


    I think that these examples show that magic numbers can make it easier to make changes to your code and they make your code easier to read.

    What do you think?

    Regards,

    Joe.

  7. #7
    Join Date
    Jul 2003
    Location
    Colorado Springs
    Posts
    4,959


    Did you find this post helpful? Yes | No

    Default

    I think the same thing applies there too. If TMR1_ON = %00000001, and the next person is trying to use an external crystal on timer1. It can cause problems.

    Apparently I do things different than everyone else, but I try to do things in as Low Level as possible when controling SFR's.

    This is also where Includes can come in handy.
    In that file you can have predefined macro's that give good names to common functions. For the above example it might look like this...
    Code:
    ASM
    TMR1_ON  macro
        bsf  T1CON, TMR1ON
        endm
    
    TMR1_OFF  macro
        bcf  T1CON, TMR1ON
        endm
    ENDASM
    Along with many other Timer related macro's.

    Then in the main program, you no longer need to worry about what registers, and what bit's need to be in a Magic Number or an Aliased variable. Just call the macro like this...
    Code:
    @  TMR1_ON
    
    '-- OR --
    
    @  TMR1_OFF
    As a side benefit, those macros only take 1 instruction cycle, instead of the 2 required to copy a constant to a byte variable.

    I don't think the buffer_size example applies here because it's not a bitwise operation. It's a whole number that still requires a constant. (CON, not =)

    Darrel
    Last edited by Darrel Taylor; - 26th July 2005 at 23:37.

  8. #8
    Join Date
    Jul 2003
    Location
    Colorado Springs
    Posts
    4,959


    Did you find this post helpful? Yes | No

    Default

    OR ---

    Here's another version that allows you to work with Timers 0-3
    Code:
    ASM
    TMR_ON  macro T
        if (T==0)
            bsf  T0CON, TMR0ON
        else
            if (T==1)
                bsf  T1CON, TMR1ON
            else
                if (T==2)
                    bsf T2CON, TMR2ON
                else
                    if (T==3)
                        bsf T3CON, TMR3ON
                    endif
                endif
            endif
        endif
        endm
    
    TMR_OFF  macro T
        if (T==0)
            bcf  T0CON, TMR0ON
        else
            if (T==1)
                bcf  T1CON, TMR1ON
            else
                if (T==2)
                    bcf T2CON, TMR2ON
                else
                    if (T==3)
                        bcf T3CON, TMR3ON
                    endif
                endif
            endif
        endif
        endm
    ENDASM
    This still only takes 1 instruction cycle but allows you to select which timer is being used.
    Code:
    @  TMR_ON  1
    @  TMR_ON  3
    @  TMR_OFF 0
    After awhile, your include files start to define your own personal language. No longer stuck with the standard commands that are defined in the PBP compiler. You'll spend a lot less time looking at the datasheets, and more looking at your program.

    Best regards,
       Darrel
    Last edited by Darrel Taylor; - 27th July 2005 at 00:09.

Similar Threads

  1. PBP Extensions, What are they?
    By PJALM in forum PBP Extensions
    Replies: 9
    Last Post: - 28th September 2021, 11:26
  2. PBP code to read R/C signal from receiver
    By malc-c in forum mel PIC BASIC Pro
    Replies: 9
    Last Post: - 28th October 2009, 21:51
  3. Making Program Code Space your playground...
    By Melanie in forum Code Examples
    Replies: 15
    Last Post: - 19th July 2008, 08:26
  4. 4 Chanel Dmx512 ready assembly code to PBP ?
    By syscoder in forum mel PIC BASIC Pro
    Replies: 10
    Last Post: - 21st March 2007, 23:55
  5. convert code "c" lcd graphic to pbp
    By nicolasronan in forum mel PIC BASIC Pro
    Replies: 2
    Last Post: - 19th June 2006, 15:49

Members who have read this thread : 1

You do not have permission to view the list of names.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts