Jump to content


  • Content Count

  • Joined

  • Last visited

Posts posted by animeranger

  1. A different, more "C-like" approach is to reference the function in some way. The most painless way I can think of besides calling the function is to assign it to a function pointer.


    #include <system.h>
    void removed (void)
    // This function is optimized out
    void main()
    for (;;)


    #include <system.h>
    void removed (void)
    // This function is no longer optimized out
    void main()
    void (*funcptr)(void);
    funcptr = removed;
    for (;;)


    This method burns a byte or two of RAM and ROM, but you won't have to worry where your code lands.

  2. Have you included "float.pic16.lib" from the SourceBoost install directory to your project? I believe it is in the "Lib" directory. By default, this means that you can find it under "C:\Program Files\SourceBoost\Lib".


    You still need to add

    #include <float.h>

    to the source file even after you add the float.pic16.lib file to you project.


    To add the library to your project, read the help files in MPLAB.


    However, just as a recommendation, you may want to find an alternative to using floats if you are a beginning programmer. I don't know about BoostC++, but in BoostC using floats is very different than they way they are used when writing computer software.


    Also, including some of your source code may help us help you faster.


    - Bill

  3. What I was referring to is similar, but based on projects rather than snippets.


    It's common in the corporate world when developing large projects, especially if you're working with .NET, to create libraries for commonly used classes. (I'm talking C++ now.)


    So, you would create a solution file, which is just a collection of projects. Take this for example:


     --- Monsters.proj
     |	  |
     |	  --- monsters.cpp
     |	  --- monsters.h
     |	  --- ...etc...
     --- GameGUI.proj
    	 --- ...more files...


    If I'm making the Monsters.proj, which will be compiled to a DLL, and my friend is making the Game's GUI, which will be compiled to an EXE, we can both work on our projects separately without competing with each other. Every time he compiles, it will test to see if he has the latest version of Monsters.dll on his computer. If nothing has changed, his program will compile, and he can test what he wrote. If I had made changes and checked them in, assuming the entire thing is under source control, his computer would realize that, compile the new code into the new Monsters.dll on his machine, and he would now be testing what he wrote using my new, bug-fixed code.


    In the *nix world, this would be the same as a Makefile calling other Makefiles.


    This method allows me to write a small program to test my portion. On my computer, I could have a project set up as:


     --- Monsters.proj
     |	  |
     |	  --- monsters.cpp
     |	  --- monsters.h
     |	  --- ...etc...
     --- MonstersUnitTest.proj
    	 --- ...more files...


    I would use my unit test project to debug my Monsters.proj. Once I feel that it is usable, I would check in the source, and everyone else that I work with would immediately see the changes.


    This is probably more info than anyone here either cares about or wants to know, so I'll cut myself here. If any of this sounds familiar to you, it could be because other IDEs have this feature, but sometimes they are called other names, such as workspaces.



    This does bring up an idea, though. Is it possible to add built-in integration with source control software, such as Subversion? I personally use BoostC for hobby purposes, so it's not something I crave, but I would imagine it would be useful for someone out there.


    Again, sorry for the length of the post.


    - Bill

  4. One thing I would love to see is the idea of a solution file like in Visual Studio. It's like a project of projects. You probably know what I'm talking about.


    I make a library file for each component I connect to outside of my microcontrollers so I don't have to remember each one's individual protocols. It would be nice to be able to work on and debug these libraries as I write the main project. Also, it'll let me write unit tests.


    Thanks for letting us add our input.


    - Bill

  5. Before I say anything, let me start by saying that I haven't tried this on a PIC. From my experience with C programming, I noticed a few things that might be causing problems:


    Issue 1


    typedef void (*fp) (void);

    This will cause the function pointer to point to a function that looks like:

    void samplefunc (void) {
    // Code here

    Since you are casting the output later in the program, I assume you wanted:

    typedef void * (*fp) (void);

    That will call something like:

    void * samplefunc (void) {
    // Code here


    Issue 2

    fp high = test1; //some function

    This will assign the pointer "high" the value of "test1". Since the pointer should point to an address, I believe it should be written as:

    fp high = &test1; //some function


    Issue 3

    unsigned short adrs = (unsigned short)high >> 1;

    Even though high takes no arguments, parentheses should still be included because it is a function call.

    unsigned short adrs = (unsigned short)(high()) >> 1;




    Again, I have no idea how well this works on the PIC. This is solely from my experience as a C programmer. I've never personally done this using BoostC.


    I'm curious to see how you manage to implement this. Good luck.


    - Bill

  6. In BoostC, registers like INTCON are assigned using lower case (intcon).


    All upper case (INTCON) is a #define with the register's address.


    So, change all your variables to be lower case.



    Also, although I'm not sure how true this is, but I tend not to put "#pragma DATA" statements inside of a header file. If the header is included in multiple source files, it could cause errors since you're initializing that register multiple times. I'm not sure how BoostC handles this, though.


    - Bill

  7. I had a hard time getting Eclipse to work with larger projects. I tend to write all my code on a USB key on a bunch of different computers. When I finally get to my PC to compile it, Eclipse yells at me.


    I found an easier time just creating a Makefile. Even if you don't use this approach, it might help you to understand the steps to take.


    This is the Makefile I use. A few notes first:

    1 - This is for a Linux system.

    2 - The "make install" directive is to burn the hex file to the chip using the PicKit2. I installed the PicKit2 software from Microchip (there's a Linux version) to /opt.

    3 - I invoke the compiler and linker through wine.

    4 - This project uses NOVO.

    5 - I tried to keep the macros as standard as possible.

    6 - The header macros are mostly for header files that include other header files. It's so I only have to change one spot in the Makefile for a modification to each source file.


    # Project specific setup
    # Note: Use "pic16" for pic12 devices
    CORE = pic18
    TARGET = PIC18F4553
    PROJNAME = apartment_cpu
    # NOVO requires -swcs
    LFLAGS += -swcs
    OBJECTS = apartment_cpu.obj setup.obj i2c_interface.obj novosys.obj \
    pc_interface.obj temperature_sensor.obj status_led.obj \
    heart.obj structures.obj nv_database.obj interrupt.obj
    # Header macros
    STRUCTURES = structures.h
    SETUP = setup.h
    I2C_INTERFACE = i2c_interface.h $(STRUCTURES)
    NOVO = novocfg_apartment_cpu.h
    NOVOPROJ = $(NOVO) novoenum_apartment_cpu.h
    PC_INTERFACE = pc_interface.h $(STRUCTURES)
    TEMPSENSOR = temperature_sensor.h
    STATUS_LED = status_led.h
    HEART = heart.h $(STRUCTURES)
    NV_DATABASE = nv_database.h
    INTERRUPT_H = interrupt.h
    # BoostC stuff
    BOOSTDIR = ~/.wine/drive_c/Program\ Files/SourceBoost
    CC = $(BOOSTDIR)/boostc.$(CORE).exe
    LD = $(BOOSTDIR)/boostlink.pic.exe
    INCDIR = $(BOOSTDIR)/include
    NOVODIR = $(BOOSTDIR)/novo
    LFLAGS += -ld $(LIBDIR)
    LIBS = libc.$(CORE).lib
    # PICkit2 stuff
    PK2DIR = /opt/pk2cmdv1-20Linux2-6
    PK2CMD = $(PK2DIR)/pk2cmd -B$(PK2DIR) -P$(TARGET) -F$(PWD)/$(PROJNAME).hex
    all: $(PROJNAME).hex
    apartment_cpu.obj: apartment_cpu.c $(SETUP) $(I2C_INTERFACE) $(NOVOPROJ) \
    $(CC) -t $(TARGET) -I $(INCDIR) apartment_cpu.c
    interrupt.obj: interrupt.c $(INTERRUPT_H) $(NOVOPROJ) $(SETUP) $(PC_INTERFACE)
    $(CC) -t $(TARGET) -I $(INCDIR) interrupt.c
    temperature_sensor.obj: temperature_sensor.c $(TEMPSENSOR) $(NOVOPROJ)
    $(CC) -t $(TARGET) -I $(INCDIR) temperature_sensor.c
    nv_database.obj: nv_database.c $(NV_DATABASE) $(NOVOPROJ)
    $(CC) -t $(TARGET) -I $(INCDIR) nv_database.c
    setup.obj: setup.c $(SETUP)
    $(CC) -t $(TARGET) -I $(INCDIR) setup.c
    pc_interface.obj: pc_interface.c $(PC_INTERFACE) $(STRUCTURES) \
    $(CC) -t $(TARGET) -I $(INCDIR) pc_interface.c
    i2c_interface.obj: $(I2C_INTERFACE) i2c_interface.c $(STRUCTURES) $(NOVOPROJ)
    $(CC) -t $(TARGET) -I $(INCDIR) i2c_interface.c
    status_led.obj: status_led.c $(STATUS_LED) $(NOVOPROJ)
    $(CC) -t $(TARGET) -I $(INCDIR) status_led.c
    heart.obj: heart.c $(HEART) $(NOVOPROJ) $(STRUCTURES) $(STATUS_LED) \
    $(CC) -t $(TARGET) -I $(INCDIR) heart.c
    structures.obj: structures.c $(STRUCTURES)
    $(CC) -t $(TARGET) -I $(INCDIR) structures.c
    novosys.obj: $(NOVO) novosys.c
    $(CC) -t $(TARGET) -I $(INCDIR) -I $(NOVODIR) novosys.c
    $(PROJNAME).hex: $(OBJECTS)
    $(LD) -t $(TARGET) $(LFLAGS) $(LIBS) -p $(PROJNAME) $(OBJECTS) 
    \rm -f $(OBJECTS)
    \rm -f *~
    \rm -f $(PROJNAME).asm
    \rm -f $(PROJNAME).casm
    \rm -f $(PROJNAME).cof
    \rm -f $(PROJNAME).hex
    \rm -f $(PROJNAME).lst
    \rm -f $(PROJNAME).stat
    \rm -f $(PROJNAME).tree
    install: $(PROJNAME).hex
    install_extpow: $(PROJNAME).hex



    - Bill

  8. Although the chips you have listed aren't specifically mentioned, chips such as PIC18F25J10 are supported. You may be able to use that as your target and just create variables at the locations of the second EUSART's registers.


    If you don't want to do that, you can use a supported chip with 2 EUSARTs, such as the PIC18F97J60. I have been using one of these with BoostC, and I haven't have any problems yet.


    - Bill

  9. I don't believe there is a native math library that has trigonometric functions for BoostC.


    You can always create a lookup table method similar to this:



    The author used assembly, but you can use the theory and the lookup table he already generated. I think what he did was a pretty clever idea to overcome the limitation of doing trigonometry on an 8-bit controller.


    - Bill

  10. I have written a program for 16F84 using char array and I want to move it to rom to save ram space.

    If I compile using

    const unsigned char patterns [26] =


    2, 7, 5, 3, 1, 13, 1, 15, 3, 8, 2, 11, 0, 1, 0, 9, 2, 5, 7, 0, 6, 14, 4, 6, 4, 3 } ;

    void main ( void )


    unsigned char a;

    a = patterns[1];


    ram usage is 27 bytes Heap 41 ROM used 58 words

    If I change it to

    rom const unsigned char patterns [26] =


    2, 7, 5, 3, 1, 13, 1, 15, 3, 8, 2, 11, 0, 1, 0, 9, 2, 5, 7, 0, 6, 14, 4, 6, 4, 3 } ;

    I get Ram usage 31 bytes Heap 37 bytes and ROM used 53 words


    Looking at the asm files it seems that Boostc is allocating the ram space for variable patterns in both cases.

    If rom keyword is used then a lookup table is written to rom while if rom is not used an equivalent use is made of rom to write the values in the ram. This explains why the rom usage is similar in both cases.

    However I do not understand why the Ram is allocated when the rom keyword is used


    Extract from asm when rom is used

    gbl_intcon EQU 0x0000000B ; bytes:1

    gbl_patterns EQU 0x0000000C ; bytes:26

    main_1_a EQU 0x00000026 ; bytes:1


    when rom is not used

    gbl_intcon EQU 0x0000000B ; bytes:1

    gbl_patterns EQU 0x0000000C ; bytes:26

    main_1_a EQU 0x00000026 ; bytes:1


    How do I stop the ram allocation when keyword rom is used?


    Don't use the [] syntax when using rom pointers (my example uses a PIC16F648A as the target):



    rom const unsigned char * patterns =
    2, 7, 5, 3, 1, 13, 1, 15, 3, 8, 2, 11, 0, 1, 0, 9, 2, 5, 7, 0, 6, 14, 4, 6, 4, 3 };
    void main ( void )
    unsigned char a;
    a = patterns[1];


    Memory Usage Report


    RAM available:256 bytes, used:6 bytes (2.4%), free:250 bytes (97.6%),

    Heap size:250 bytes, Heap max single alloc:95 bytes

    ROM available:4096 words, used:55 words (1.4%), free:4041 words (98.6%)

  11. All you have to do to use the hardware SPI module is set up the registers on pages 88 and 89 on the data sheet. Note that most of the bits are read-only and used only for I2C, so those can be ignored.


    In master mode:

    That's it. To send/receive data (both are done simultaneously with SPI), simply write the byte you want to send to sspbuf. From there you can either poll SSPIF or enable the respective interrupt. Once SSPIF is set or the interrupt is triggered, read the value in sspbuf to obtain the byte that was received.


    Slave mode isn't much more complicated, but since you are looking for a library, I'm assuming you want to use master mode to read/write to some EEPROM, RAM, port extender, or something of that nature.


    This address has a good overview of the SPI module in a PICmicro:




    - Bill

  12. Changing options under "Customize workspace..." only changes what files appear under the output folder of your project in the IDE.


    To redirect the output of the linker, go to Settings->Options... and under "Extra linker options" and this:

    -d "F:\"

    Replace "F:\" with your output directory, but you should probably keep the directory name in quotes.


    This will put all the linker output into that directory (*.asm, *.casm, *.cof, *.hex, *.lst, *.stat, *.tree). *.obj file will remain where they are since that's a compiler option and not a linker option.


    Another thing you can do if you want only the hex file and don't mind an extra step is to write a quick batch file:

    if exist "OLDPATH\project.hex" move "OLDPATH\project.hex" "NEWPATH\project.hex"


    Just run that after linking. Note that if you ever change the name of the project, you will have to edit the batch file as well.


    - Bill

  13. According to the BoostC manual (page 43), rom variables have to be initialized within they're declaration.


    Your struct has both rom variables declared, but you are initializing them when you create menuTest. That violates how rom variables must be used.


    They may be a work around you can figure out, but it may end up bloating your code to the point where it wasn't worth it.


    I hope this helps.


    - Bill

  14. tha latest sourceboost ide works great on the latest wine, but native linux support would be a dream come true. and a suitcase full of money... if you could get it to interface with the linux command line, any existing progger software could be used which would speed up development massively. thanks very much for considering linux and PLEASE go ahead with the project. for the widgets and stuff could i recomend wither QT (kde, but there's v3 and v4 for kde3 and kde4 or w.e.) which works with gnome and kde (the main desktops) or GTK2.0 for gnome which i THINK works with kde (?? correct me if im wrong anyone). or just think 'ah hell, well use the x toolkit', just MAKE IT FOR LINUX PLEASE!!


    james waples, 14


    ps. i will buy one of your licences if you do boostc for linux (SERIOUSLY)


    It's worth buying the license for use on Linux. I've been using it on Linux for a month or two now (ever since I found out registration worked via command line). It works almost flawlessly with PikLab, and it works just as well with Eclipse.

    Eclipse you have to modify a few settings and write your own Makefile, but if you've ever programmed using Linux before, you can probably already do that.


    Also, I'm not sure if you can run goodies.exe on Linux, but if you run it on Windows and move the NOVO sources to Linux, they work as well. Just remember to delete them off the Windows machine due to the license (only allowed on one node). If you are going to make large scale projects, I'd recommend NOVO. It's amazing how well it works and how simple it is.


    I should probably stop there before I start treading into BoostC fan-boy territory.


    - Bill

  15. Without looking a the code, I have one question about your hardware. Are you shifting your voltage levels as required by the RS-232 protocol?


    The RS-232 protocol uses -12V as "high" and 12V as "low." (Can actually be anywhere between -15V to -3V and 3V to 15V).

    UART uses 5V and 0V, respectively.


    If you do not have anything shifting the voltage levels, you will not be sending 1's and 0's. You will be sending 0's and undefined's.


    You need to put something like the MAX232 from Maxim-IC between the UART and the PC serial cable. I prefer the MAX233 since the required charge-pump capacitors are built in. Maxim-IC offers free samples of both of these chips.


    - Bill

  16. "C and D, are already defined " Yea, that's what I figured, so I tried changing to something more unique. But it doesn't make sense for the compiler to report that there's a missing bracket, and a missing semicolon. Looks like a bug.


    It's not a bug. Your code looks like this:


    enum PHASE {A,B,C,D};


    But C & D are already defined. So, after the preprocessor is run, the code the compiler gets looks like this:


    enum PHASE {A,B,0x00000000,0x00000005};


    These values are taken from the PIC18F4550 target header file. Since you are trying to enumerate a number instead of a variable, the compiler thinks that you forgot to close your brace and end the command. This code results in the same error:


    enum PHASE {A,B
    unsigned char a = 0;


    So, the compiler just thinks you made a typo.


    - Bill

  • Create New...