Difference between revisions of "PIC/C18 Compiler Tips and Troubleshooting"
Line 25: | Line 25: | ||
You should also beware that baud rates are usually not exact. The system's clock generally has to be an integer multiple of the baud rate, so if a device has a 1 MHz clock, it is likely to use a baud rate of 111,111.111 bps (1,000,000/9) instead of the standard 115,200 bps. Although these systems can generally tolerate small differences in the baud rate, the possibility of mismatched baud rates contributing to errors should be kept in mind. |
You should also beware that baud rates are usually not exact. The system's clock generally has to be an integer multiple of the baud rate, so if a device has a 1 MHz clock, it is likely to use a baud rate of 111,111.111 bps (1,000,000/9) instead of the standard 115,200 bps. Although these systems can generally tolerate small differences in the baud rate, the possibility of mismatched baud rates contributing to errors should be kept in mind. |
||
===Erratic |
===Erratic Behavior at End of Program=== |
||
If you have a program where the PIC runs through the program once and stops and does nothing until it is reset, place a <tt>while(1){}</tt> loop at the end of the program to make the PIC enter a trap state. |
If you have a program where the PIC runs through the program once and stops and does nothing until it is reset, place a <tt>while(1){}</tt> loop at the end of the program to make the PIC enter a trap state. |
||
Revision as of 13:36, 14 September 2007
Troubleshooting
MPLAB Has Trouble Connecting to the ICD2
If you see the following errors while trying to connect to the ICD2:
ICD0192: Failed to clear COM error. (RetVal = 0xFFFFFFF0, ErrRet = 0x0) ICD0021: Unable to connect with MPLAB ICD 2 ICD0019: Communications: Failed to open port: (Windows::GetLastError() = 0x2, 'The system cannot find the file specified. ') ICD0021: Unable to connect with MPLAB ICD 2
Disconnect the reconnect the ICD2 from the USB port, then open the Device Manager (Control panel>System>Hardware>Device Manager) and disable then re-enable the ICD2. Also, be sure that you followed in installation instructions in the manual when you installed the ICD2.
printf
Note that printing floating point types with printf is not supported.
Data Corruption/Erratic Behavior
Beware if you have large arrays as local variables; you run the risk of a stack overflow. Try making large arrays global variables or static variables.
Serial Communications Data Corruption
If you are having trouble with RS-232 communications with other devices, remember that the RS-232 standard uses -8V to -15V for a low signal and 8V to 15V for a high signal, whereas the PIC uses 0V and 5V, respectively. If you are interfacing the PIC with a standard RS-232 device, such as the serial port on a PC, you will need a voltage shifting chip such as the ST232 RS-232 Voltage Shifter.
You should also beware that baud rates are usually not exact. The system's clock generally has to be an integer multiple of the baud rate, so if a device has a 1 MHz clock, it is likely to use a baud rate of 111,111.111 bps (1,000,000/9) instead of the standard 115,200 bps. Although these systems can generally tolerate small differences in the baud rate, the possibility of mismatched baud rates contributing to errors should be kept in mind.
Erratic Behavior at End of Program
If you have a program where the PIC runs through the program once and stops and does nothing until it is reset, place a while(1){} loop at the end of the program to make the PIC enter a trap state.
Tips
Splitting Multi-Byte Data Types into Individual Bytes
There are some situations where you may need to split a multi-byte variable into its component bytes (for example, writing to 16-bit registers or sending data through the serial port).
Using Unions
One way to do this is to use the union data type. A union is like a struct, except all the members share the same location in memory. Therefore, if have a union with one int variable and an array of two char variables, writing to the int variable will automatically fill in the char fields as well, and vice versa.
Example:
union UINT_UCHAR{ unsigned int intVal; unsigned char charVal[2]; }; char byte1; char byte2; union UINT_UCHAR splitter; splitter.intVal=0xABCD; byte2=splitter.charVal[1]; //byte2 will equal 0xAB byte1=splitter.charVal[0]; //byte1 will equal 0xCD
In the memory, it looks like this:
(MSB=Most Significant Byte, LSB=Least Significant Byte)
Using Arithmetic
Another way of doing this is to use arithmetic. For a 16-bit integer, the most significant byte can be obtained by dividing the value by 256. The least significant byte can be obtained by using the modulus function with 256. Example:
int someInteger; char byte1; char byte2; someInteger = 0xABCD; byte2 = someInteger/256; byte1 = someInteger%256;
If you want to join two values:
int someInteger; char byte1; char byte2; byte2 = 0xAB; byte1 = 0xCD; someInteger = (unsigned int)byte2*256 + (unsigned int)byte1;
Beware that this isn't going to give you the correct result if you leave byte1 and byte2 as signed chars, because signed chars could be negative. Therefore, we place the (unsigned int) keywords to cast them as unsigned integers before performing the operations.