Jump to content


  • Content Count

  • Joined

  • Last visited

Everything 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. Those are the floating point math libraries. Documentation for their functions can be found in FloatMath.pdf in the install directory of SourceBoost. - Bill
  4. 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: Game.sol | --- 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: Game.sol | --- 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
  5. 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
  6. I guess I didn't realize exactly what you were doing. I assumed that the function pointers would fill themselves in at compile time. I don't know why I thought that. I'm glad that you were able to figure it out, though. - Bill
  7. 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
  8. 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
  9. 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) SENDPACKET = sendpacket.h $(I2C_INTERFACE) $(NOVOPROJ) $(STRUCTURES) $(PC_INTERFACE) 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 LIBDIR = $(BOOSTDIR)/Lib 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 PKFLAGPROG = -M PKFLAGVERIFY = -Y PKFLAGEXTPOW = -W all: $(PROJNAME).hex apartment_cpu.obj: apartment_cpu.c $(SETUP) $(I2C_INTERFACE) $(NOVOPROJ) \ $(STATUS_LED) $(HEART) $(INTERRUPT_H) $(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) \ $(I2C_INTERFACE) $(HEART) $(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) \ $(SENDPACKET) $(NV_DATABASE) $(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) clean: \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 $(PK2CMD) $(PKFLAGPROG) $(PKFLAGVERIFY) install_extpow: $(PROJNAME).hex $(PK2CMD) $(PKFLAGPROG) $(PKFLAGVERIFY) $(PKFLAGEXTPOW) - Bill
  10. 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
  11. 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: http://plans.thefrankes.com/tutorials/picmicrotrig/ 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
  12. That functionality is already in the SourceBoost IDE. If for some reason it stops working for you, try rebuilding your project. That works for me. You may need to comment out the line you're currently working on. - Bill
  13. 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%)
  14. 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: ww1.microchip.com/downloads/en/devicedoc/spi.pdf - Bill
  15. 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
  16. Since a PICmicro uses four clock cycles per instruction, 4MHz is 1MIPS (million instructions per second). This means that a nop is exactly 1us. So, yeah, a nop should work perfectly. - Bill
  17. 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
  18. 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
  19. If you don't mind a decrease in your trigonometry solution's precision, you can always use the 256-degree circle. http://www.codecreations.com/site/robotics...-trig?showall=1 Granted, that's in assembly, but it seems it can be adapted to C easily. - Bill
  20. 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
  21. 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
  22. If you just want a quick and easy way to do infrared communications, the MCP2120 from microchip will do all the encoding/decoding of the irda standard for you. http://www.microchip.com/wwwproducts/Devic...ocName=en010407 And by using that standard, you can communicate with other devices by Palm, Pocket PC, laptops, PCs, remote controls, etc. - Bill
  23. You have the chip configured to use _HS_OSC, which uses porta pins 4 and 5 (page 199 of the datasheet). According to page 62 of the datasheet, IOCA<5:4> will always be 1 when using HS oscillator mode. Port A IOC will probably work on a differect Port A pin. - Bill
  24. I missed that little fact. I guess I can save myself another instruction whenever I put an interrupt into my project. - Bill
  25. My post about timer0 may help you in this post: http://forum.sourceboost.com/index.php?showtopic=3717 Also, at the end of your interrupt routine, you need to set the GIE bit again. It is automatically cleared in hardware when an interrupt is triggered so the currently running interrupt routine can't itself be interrupted. (Page 208 of the data sheet). - Bill
  • Create New...