Posted by Trevor in Assembly to C book, PIC24, tags: Explorer 16, EXPLORER16_100P, HARDWARE_PLATFORM, heartbeat, LED, Microcontrollers, MPLab, PIC24, PIC24HJ, PIC24HJ256GP610, PIC24HJ256GP610A, pic24_libconfig.h, PIM, reset.c, UART
This fix refers to the library version release 12 April 2011. When using an Explorer 16 board and setting the Macro definition of EXPLORER16_100P in MPLab, parts of the library do not pick it up correctly rendering the heartbeat LED and the UART to not work. No compilor error is noticed.
In the file lib\include\pic24_libconfig.h at line 76, change the following section of code:
/** Select one of the hardware platform above to compile for. */
#ifndef HARDWARE_PLATFORM
#define HARDWARE_PLATFORM DEFAULT_DESIGN
#endif
// Verify that a valid hardware platform is selectd
#if (HARDWARE_PLATFORM != EXPLORER16_100P) && \
(HARDWARE_PLATFORM != DANGEROUS_WEB) && \
(HARDWARE_PLATFORM != STARTER_BOARD_28P) && \
(HARDWARE_PLATFORM != DEFAULT_DESIGN)
#error Invalid hardware platform selected.
#endif
//@}
Replacing the above code with this code:
/** Select one of the hardware platform above to compile for. */
/* The automated method expects the board is defined in MPLAB
using Use Project->Build Options-> Project, click on
the MPLAB C30 tab, and in Macro Definitions click 'Add',
and add:
- For the Explorer 16 board - EXPLORER16_100P
- For the Dangerous Prototypes web server - DANGEROUS_WEB
- For the Microchip 16-bit 28-pin Starter Board - STARTER_BOARD_28P
If the above is not set, the code will compile with the default
of DEFAULT_DESIGN
*/
#ifndef HARDWARE_PLATFORM
#ifdef EXPLORER16_100P
#define HARDWARE_PLATFORM EXPLORER16_100P
#elif STARTER_BOARD_28P
#define HARDWARE_PLATFORM STARTER_BOARD_28P
#elif DANGEROUS_WEB
#define HARDWARE_PLATFORM DANGEROUS_WEB
#else
#define HARDWARE_PLATFORM DEFAULT_DESIGN
#endif
#endif
// Verify that a valid hardware platform is selectd
#if (HARDWARE_PLATFORM != EXPLORER16_100P) && \
(HARDWARE_PLATFORM != DANGEROUS_WEB) && \
(HARDWARE_PLATFORM != STARTER_BOARD_28P) && \
(HARDWARE_PLATFORM != DEFAULT_DESIGN)
#error Invalid hardware platform selected.
#endif
//@}
This will now pick up the Macro definition set in MPLab and compile the components of the library needed for the Explorer 16 to function.
So far have tested the above with the Explorer 16, PIC24HJ256GP610A PIM, and the reset.c example from chapter 8 in the Microcontrollers: From Assembly Language to C Using the PIC24 Family.
No Comments »
Posted by Trevor in Assembly to C book, PIC24, tags: EXPECTED_REVISION1, Explorer 16, EXPLORER16_100P, library, MA240012, Microchip, Microcontrollers, PIC24, PIC24HJ256GP610, PIC24HJ256GP610A, PIM
For those that use the Explorer 16 board and have in the last 12 or so months purchased the PIC24HJ256GP610 PIM from Microchip (part number MA240012) may have noticed it’s got a different chip on it. It now uses the PIC24HJ256GP610A which has some issues when using the library included with the book Microcontrollers: From Assembly Language to C Using the PIC24 Family.
This article shows how I modified the library (12 Apr 2011 version) from http://www.ece.msstate.edu/courses/ece3724/main_pic24/labs/files/pic24_code_examples.zip
In lib\common\pic24_configbits.c at about line 261 fine the line that contains
#if defined(EXPLORER16_100P) && defined(__PIC24HJ256GP610__)
and change it to
#if defined(EXPLORER16_100P) && (defined(__PIC24HJ256GP610__) || defined(__PIC24HJ256GP610A__))
In lib\include\pic24_ports.h at about line 700 you will find the following:
00700 #elif defined(__PIC24HJ256GP610__)
00701
00702 #include "devices/pic24hj256gp610_ports.h"
Change line 700 to:
#elif defined((__PIC24HJ256GP610__) || defined(__PIC24HJ256GP610A__))
The above uses the same .h file for the 610A as for the 610 on the assumption the two are pin compatible in every way. I have not yet found they are not, or any other reason to use a seperate ports file for the chip.
In lib\include\pic24_chip.h at aprox line 336 you will find the following little block of code:
#ifdef __PIC24HJ256GP610__
#define DEV_ID 0x00007B
#define DEV_ID_STR "PIC24HJ256GP610"
#endif
#if (defined(__PIC24HJ64GP206__) || defined(__PIC24HJ64GP210__) || defined(__PIC24HJ64GP506__)
|| defined(__PIC24HJ64GP510__)\
|| defined(__PIC24HJ128GP206__) || defined(__PIC24HJ128GP210__) || defined(__PIC24HJ128GP306__)\
|| defined(__PIC24HJ128GP310__) || defined(__PIC24HJ128GP506__)|| defined(__PIC24HJ128GP510__)\
|| defined(__PIC24HJ256GP206__) || defined(__PIC24HJ256GP210__)|| defined(__PIC24HJ256GP610__))
#define EXPECTED_REVISION1 0x003002
#define EXPECTED_REVISION1_STR "A2"
#define EXPECTED_REVISION2 0x003004
#define EXPECTED_REVISION2_STR "A3"
#define EXPECTED_REVISION3 0x003040
#define EXPECTED_REVISION3_STR "A4"
#endif
Replace this block of code above with:
#ifdef __PIC24HJ256GP610__
#define DEV_ID 0x00007B
#define DEV_ID_STR "PIC24HJ256GP610"
#endif
#ifdef __PIC24HJ256GP610A__
#define DEV_ID 0x0000077B
#define DEV_ID_STR "PIC24HJ256GP610A"
#endif
#if (defined(__PIC24HJ64GP206__) || defined(__PIC24HJ64GP210__) || defined(__PIC24HJ64GP506__)\
|| defined(__PIC24HJ64GP510__)\
|| defined(__PIC24HJ128GP206__) || defined(__PIC24HJ128GP210__) || defined(__PIC24HJ128GP306__)\
|| defined(__PIC24HJ128GP310__) || defined(__PIC24HJ128GP506__)|| defined(__PIC24HJ128GP510__)\
|| defined(__PIC24HJ256GP206__) || defined(__PIC24HJ256GP210__)|| defined(__PIC24HJ256GP610__))
#define EXPECTED_REVISION1 0x003002
#define EXPECTED_REVISION1_STR "A2"
#define EXPECTED_REVISION2 0x003004
#define EXPECTED_REVISION2_STR "A3"
#define EXPECTED_REVISION3 0x003040
#define EXPECTED_REVISION3_STR "A4"
#endif
#if defined(__PIC24HJ256GP610A__)
#define EXPECTED_REVISION1 0x003003
#define EXPECTED_REVISION1_STR "A1"
#endif
I’m not sure what the second last line #define EXPECTED_REVISION1_STR “A1″ should be and have not been able to find it, but the above has been tested using the reset.c example from chapter 8 of the book on the Explorer 16 and is working (provided you have also performed the mod described in this article).
This will update the library to accommodate for the new version of the PIC24HJ256GP610 PIM which now uses a PIC24HJ256GP610A.
No Comments »
Posted by Trevor in Arduino, tags: Arduino, code, compass, HMC6352, I2C, logic level converter, Mega, SCL, SDA, Serial, Sparkfun, TWI, Two Wire Interface, Uno
This mini project shows how to connect the Sparkfun Compass Module (SKU SEN-07915) to both the Arduino Uno and the Arduino Mega 2560. As these two Arduino boards are 5V devices, and the Compass Module is a 3.3V module, the I2C bus must be translated. This is done using the Logic Level Converter from Sparkfun (SKU BOB-08745).
To help, included here are two diagrams of the wiring needed. Note that the Mega has specific I2C pins available while the Uno uses Analog pin 4 for SDA and Analog pin 5 for SCL. SDA is the data line, and SCL is the clock line.
The Arduino has pull up resistors built in and the Compass Module has them as well so there is no need to add them in this case.
Both the wiring diagrams and the code will read the compass module twice per second and send it out via serial to the computer where it can be viewed by a serial aware program like the serial viewer in the Arduino software.
Wiring up the Uno, connect the following:
- +5V and GND connects from the UNO to the “hv” side of the level converter
- +3.3V and GND connects from the UNO to the “lv” side of the level converter
- Connect Analog pin A4 from the UNO to Ch1 TXO on the level converter
- Connect Analog pin A5 from the UNO to Ch2 TXO on the level converter
- +3.3V from the UNO also connects to the VCC on the compas module
- GND from the UNO connects to the GND on the compas module
- SDA on the compas module connects to Ch1 TXI on the level converter
- SCL on the compas module connects to Ch2 TXI on the level converter
See the following picture for details

How to wire the compass module to the Arduino Uno via the level shifter from Sparkfun
Wiring up the Uno, connect the following:
- +5V and GND connects from the MEGA to the “hv” side of the level converter
- +3.3V and GND connects from the MEGA to the “lv” side of the level converter
- Connect pin 21 SCL from the MEGA to Ch1 TXO on the level converter
- Connect pin 20 SDA from the MEGA to Ch2 TXO on the level converter
- +3.3V from the UNO also connects to the VCC on the compas module
- GND from the UNO connects to the GND on the compas module
- SDA on the compas module connects to Ch1 TXI on the level converter
- SCL on the compas module connects to Ch2 TXI on the level converter
See the following picture for details

How to wire the Sparkfun Compass Module to the Arduino Mega 2560
The source code.
And here is the code, inspired by the code posted by Vaibhav Bhawsar. Note the source is the same for both boards.
#include <Wire.h> // Where all the routines for controlling
// the I2C bus are
int HMC6352 = 0x42; // device address from the data sheet
int slaveAddress; // variable to hold the slave address
int ledPin = 13; // LED on the Arduino board
boolean ledState = false; // state of the LED for the flash routine
byte headingFromCompass[2]; // array to store the two byte data from compass
int i; // array element id
int heading; // calculated heading for printing
void setup()
{
slaveAddress = HMC6352 >> 1; // The wire library only wants the 7 most significant
// bits of the address.
Serial.begin(9600); // Start Serial, change baud rate to suit
pinMode(ledPin, OUTPUT); // Set the LED pin as output to show program is running
Wire.begin(); // Initialise the Two Wire Interface (I2C)
}
void loop()
{
ledState = !ledState;
if (ledState)
{
digitalWrite(ledPin,HIGH);
}
else
{
digitalWrite(ledPin,LOW);
}
Wire.beginTransmission(slaveAddress);
Wire.send(0x41); // Send the Get Data command
Wire.endTransmission();
delay(10); // The HMC6352 needs 70us delay
Wire.requestFrom(slaveAddress, 2); // Request 2 bytes of data (MSB then LSB)
i = 0; // This is used as the array element pointer for
// data
while(Wire.available() && i < 2) // We're receiving data
{
headingFromCompass[i] = Wire.receive(); // Put the data into the array element
i++; // increment for the next data piece
}
heading = headingFromCompass[0]*256 + headingFromCompass[1]; // Combine MSB and LSB
// Change the following output to suit your application
Serial.print("Heading: ");
Serial.print(int (heading / 10)); // The whole number part of the heading
Serial.print(".");
Serial.print(int (heading % 10)); // The fractional part of the heading
Serial.println(" degrees");
delay(500);
}
No Comments »
Posted by Trevor in programming tools, tags: build, C, C18, code, compiler, error, linker, message, Microcontrollers, MPLab, MPLink, PIC18, processor, project
If your using a different linker file than what comes with the compiler you will need to set the /p option for the linker to specify your processor manually. For some reason v3.38 doesn’t pick this up automatically. If this is not done, the following error message will probably be recieved:
Error – Device not specified. Use /p option to specify a device.
Setting the /p option is simple, click ‘Project – Build Options – Project’, go to the MPLINK Linker tab. Then check the ‘Use Alternate Settings’ check box.
The default string will look like:
/m”$(BINDIR_)$(TARGETBASE).map” /w /o”$(BINDIR_)$(TARGETBASE).cof”
Change this to:
/m”$(BINDIR_)$(TARGETBASE).map” /w /p18F2450 /o”$(BINDIR_)$(TARGETBASE).cof”
using your processor instead of the /p18F2450 in the above example. Note, there is no space between the p and the 1. It’s just the font makes it look like there is.
No Comments »
Had the need to create some strings in the form of an array of hex codes for the charachters the other day which was a little cumbersom, so put together some quick php code to do it for me. So thought I’d share it with you. You can access it at http://electronics.trev.id.au/str2hex.php. Just enter your string and click convert.
No Comments »
Last Tuesday (27 Jul 2010) I attended a meeting at the South Australian PIC User Group (SAPUG) which was excellent. A great bunch of people that are all keen to help. Ian from The Leon Audio Company gave a talk on how to use MOSFET’s with a PIC and some things to watch out for. They are a great device, but needs to be used in the right way or you destroy your PIC MCU. The group is planning a weekend of activities in October so keep the weekend of 16th and 17th free and keep an eye on the groups web site for details at http://www.users.on.net/~sapug/
No Comments »
Posted by Trevor in Assembly to C book, PIC24, tags: checklist, configure, example, exercise, Explorer16, ICD2, LED, linker, MPLab, PIC24, PIC24FJ128GA010, processor, programmer, script
Hi again. Onto the next example, this time on page 295 (figure 8.28). The code for this one is called ‘ledtoggle_nofsm’ and it’s in the chap8 folder.
Now that we’ve defined EXPLORER16_100P in the pic24_all.h file, here is a new checklist to use:
- Double click on the project file for the exercise your wanting to do. (Make sure you don’t already have MPLAB open or it will complain)
- Set the processor type in the menu item Configure – Select Device. The default PIC24 that comes with the Explorer16 is PIC24FJ128GA010.
- Remove the linker script from the workspace files viewer under “Linker Scripts” (don’t add anything, MPLAB will manage it for you)
- Change from DEBUG to RELEASE in the drop down at top of MPLAB screen
- Select your programmer (Programmer – Select Programmer). I use the ICD2
- Make required changes to the code (see below for this exercise)
- CTRL-F10 to build all
- When you get the BUILD SUCCEDED message, program the chip (Programmer – Program)
- Click ok the the ICDWarn0046 warning (unless you’ve got sick of this message and clicked the “don’t show me again” like I did)
- disconnect the ICD2 when the programmer has completed.
Here is the modification needed for this one to work. Shown here is the code between the #include directive and the start of the main() function.
You should see the very left LED blinking. When you press the right of the 4 buttons, the second from left LED should toggle (light up if it’s the first press). Keep pressing and releasing and observe what happens. You will notice the LED state doesn’t change until the button is released.
#include "pic24_all.h"
/** \file
A program that toggles an LED whenever a pushbutton switch is pressed
and released. Does not use a finite statement approach.
*/
#if defined(EXPLORER16_100P)
/// LED1
#define CONFIG_LED1() CONFIG_RA6_AS_DIG_OUTPUT()
#define LED1 _LATA6 //_LATA6 is port register for RA6
#warning Were using the explorer16 version of the code
/// Switch1 configuration
inline void CONFIG_SW1() {
CONFIG_RD13_AS_DIG_INPUT(); //use RD13 for switch input
ENABLE_RD13_PULLUP(); //enable the pullup
}
#define SW1 _RD13 //switch state
#else // not Explorer16
/// LED1
#define CONFIG_LED1() CONFIG_RB14_AS_DIG_OUTPUT()
#define LED1 _LATB14 //led1 state
#warning If your using an Explorer16, this program wont work
/// Switch1 configuration
inline void CONFIG_SW1() {
CONFIG_RB13_AS_DIG_INPUT(); //use RB13 for switch input
ENABLE_RB13_PULLUP(); //enable the pullup
}
#define SW1 _RB13 //switch state
#endif // if defined EXPLORER16_100P
#define SW1_PRESSED() SW1==0 //switch test
#define SW1_RELEASED() SW1==1 //switch test
int main (void) {
.....
Example 7 which is Figure 8.30 on page 298 is called ledtoggle and is in the chap8 folder. It’s the same changes as example 6 above except the original code has some extra bits that example 6 didn’t have.
#include "pic24_all.h"
/** \file
A program that uses a finite state machine approach for
toggling an LED whenever a pushbutton switch is pressed
and released. Demonstrates the use of debounce delays when
polling a switch input.
*/
#if defined(EXPLORER16_100P)
/// LED1
#define CONFIG_LED1() CONFIG_RA6_AS_DIG_OUTPUT()
#define LED1 _LATA6 //_LATA6 is port register for RA6
#warning Were using the explorer16 version of the code
/// Switch1 configuration
inline void CONFIG_SW1() {
CONFIG_RD13_AS_DIG_INPUT(); //use RD13 for switch input
ENABLE_RD13_PULLUP(); //enable the pullup
}
#define SW1 _RD13 //switch state
#else // not Explorer16
/// LED1
#define CONFIG_LED1() CONFIG_RB14_AS_DIG_OUTPUT()
#define LED1 _LATB14 //led1 state
#warning If your using an Explorer16, this program wont work
/// Switch1 configuration
inline void CONFIG_SW1() {
CONFIG_RB13_AS_DIG_INPUT(); //use RB13 for switch input
ENABLE_RB13_PULLUP(); //enable the pullup
}
#define SW1 _RB13 //switch state
#endif // if defined EXPLORER16_100P
#define SW1_PRESSED() SW1==0 //switch test
#define SW1_RELEASED() SW1==1 //switch test
typedef enum {
.....
No Comments »
I enjoyed this example as it’s interfacing between the user and the MCU via a computer. It also showed some interesting concepts on power management within source code.
I did notice this time I needed to use a different approach to telling the compiler I’m using the Explorer16. For some reason, it would not maintain the setting using the preprogrammer directive. So open up the file include\pic24_all.h and right at the start of the code, add the directive
#define EXPLORER16_100P
Here is the snippit of the file.
// Documentation for this file. If the \file tag isn't present,
// this file won't be documented.
/** \file
* This header file includes the all the pic24_*.h files as detailed
* in the \ref index and also includes the necessary
* processor-specific include file (via a \#include p24h/fxxxx.h).
*/
// Added this define as I'm using the Explorer16 for these examples.
#define EXPLORER16_100P
#ifndef _PIC24_ALL_H_
#define _PIC24_ALL_H_
// Include processor-specific header file
#if defined(__PIC24H__)
You will also need to change the device to your processor as the default project uses the PIC24HJ32GP202. It should be PIC24FJ128GP010 if your using the default PIM on the Explorer 16. You do this in the menu item [Configure] – [Select Device].
No Comments »
The UART example on page 262 just needs the Explorer16 check list from the last article to make it work and the ASM example I skipped as it’s not needed at this stage of my journey.
The file name for the Figure 8.6 example is documented in the book. Well done to the author and publisher It’s called ‘echo’ for those that might have missed it.
No Comments »
Posted by Trevor in Assembly to C book, PIC24, tags: adventures, C30, configuration, CONFIG_RA6_AS_DIG_OUTPUT, Explorer16, ICD2, LED, macro, MPLab, PIC
Continuing with Chapter 8, the next file is the one referred to in Figure 8:5 Improved code example for flashing LED. It takes the previous one and modifies it using macro’s. Well we sort of used macros in the last one to break out the Explorer 16 version and the original. This file is called “ledflash” and it’s also in the chapter 8 folder.
You will see what the author had in mind. The use of macro’s certainly makes it easier to see what is going on. Here is the modified code that enables the Explorer 16 to run this. Don’t forget to define EXPLORER16_100P.
#if defined(EXPLORER16_100P)
#define CONFIG_LED1() CONFIG_RA6_AS_DIG_OUTPUT()
#define LED1 _LATA6 //_LATA6 is port register for RA6
#warning Were using the explorer16
#else // not Explorer16
#define CONFIG_LED1() CONFIG_RB15_AS_DIG_OD_OUTPUT()
#define LED1 _LATB15 //_LATB15 is port register for RB15
#warning Were not using the explorer16 because EXPLORER16_100P not defined
#endif // if defined EXPLORER16_100P
int main(void) {
configClock();
/********** GPIO config **********/
CONFIG_LED1();
LED1 = 0;
while (1) {
DELAY_MS(250); //delay long enough to see LED blink
LED1 = !LED1; // Toggle LED
} // end while (1)
}
This time all the configuration changes needed are done in the short macro section while leaving the actual code identical effectively creating a hardware abstraction layer between the code and the hardware.
Ok so now time to build. Here is a check list to follow for these examples.
- Define EXPLORER16_100P (Project – Build Options – Project. Then the MPLAB C30 tab. Add the preprocessor macro.
- Remove the linker script from the workspace files viewer under “Linker Scripts” (dont add anything, MPLAB will manage it for you)
- Change from DEBUG to RELEASE in the drop down at top of MPLAB screen
- Select your programmer (Programmer – Select Programmer). I use the ICD2
- CTRL-F10 to build all
- When you get the BUILD SUCCEDED message, program the chip (Programmer – Program)
- Click ok the the ICDWarn0046 warning
- disconnect the ICD2 when the programmer has completed.
You should now see the LED connected to RA6 (second from left) flash at about 1 per second.
One thing I do want to point out, I am not going to teach you about programming and the PIC etc. The intent of this blog is share my adventures and if you happen to learn something from that, well that’s good. The other thing I’m going to recommend is to buy the book referred to here. See the books web site here. This is also the web site where you will find all the original code the book discusses and what I refer to here.
No Comments »
|