Click here to view the PDF newsletters. Interested in receiving our newsletters in your inbox? Click here to subscribe.

Type Conversions

Monday 12 June, 2023

In order to evaluate expressions the C compiler uses a complex set of rules to get a result that is consistent and as intuitive as possible. Sometimes the coder needs to add an explicit typecast in order to nudge the compiler to do something specific.

To understand this topic we will start with a simple example that will show a possible problem:

int8 x,y;
int16 z;


z = x * y;

There are two expression evaluations here. One is the * and the second is the =. The order is *, and then =, and that is controlled by operator precedence, another topic. The two operands for the * are eight bit so the eight bit multiply is used, yielding an eight bit result. In this case the result of the multiply will be 244. Then because the = operator has an 8 bit operand and a 16 bit operand, the 8 bit operand is automatically converted (Integral Promotion because of Usual Arithmetic Conversion) to 16 bit by the compiler. Then the assignment is done.

Probably the coder expected a 500 in z, not 244. To fix the situation we can do a typecast on either 8 bit operand like this:

z = (int16)x * y;

Now when the multiply is done the second eight bit operand is converted to 16 bit to match the other operand and the multiply and result are now 16 bit (500).

Note that this concept is not an invention of the CCS C compiler although people who have never had this trouble with another compiler might think it is. A C compiler for a PC for example where an int is 32 bit by default may never cause a problem because the numbers used are much smaller than the default type. Because the CCS C compiler starts with an eight bit int by default, problems are more common.

Having said that, because the rules are somewhat complex and not always fully understood and sometimes not very specific in the specification, the CCS C compiler has tweaked the rules over the years. Sometimes to match the latest interpretation of the spec or sometimes to match a GNU compiler or the Microchip compiler to help in code portability.

Explicit Conversion, or Explicit Cast, or Explicit Typecast, or Tyepcast:
This is where the coder has a typecast that will force a conversion from one type to another. The syntax is (new type)expression and if the new type is compatible the value will be the same. That is to say this is more than a bit for bit movement, for example a float to an integer will have the same value to the extent possible.

Implicit Conversion, or Automatic Conversion:
This is where the compiler uses a set of rules to be detailed later to perform a conversion.

Type Conversion:
Either an Explicit Conversion or Implicit Conversion.

Integral Promotion:
In this case any type conversion where a smaller integer is converted to a larger one (or superior one). The value does not change when promoted.

Usual Arithmetic Conversions:
These are implicit conversions that are made according to the rules when an operator and operands are involved. One operand is converted based on the type of the other operand BEFORE the operator is invoked.

The Rules:
The way to read this table is for each group start at the top and go down until you find the first rule that applies. Use that result and stop.

Be aware that by default the CCS C compiler for 24 bit parts is signed and the size is 16 bits. For all other compilers the default is unsigned and the size is 8 bits. This can be changed using #type so this needs to be taken into account when considering the rules.

The syntax in this table is not real C, just pseudo-code that a C coder should be able to understand.

The table as follows:
Integer Constant Types
Leading 0 in constantUnsigned
Trailing u in constantUnsigned
Else if default type is signed || is preceded by a minus
Else if default type is unsigned
Find the smallest of these types the constant will fit intoint8, int16, int32, int48, int64
Integral promotion anytime X is used in an expression (int is the default type)
issigned (X) && bitsin(X)<bitsin(int) && (X>max(signed(X))X=>unsigned int
Any type conversion from signed to unsigned
bitsin(signed(X)) <=bitsin(unsigned(X))X+>unsigned(X) sign extend
X+>unsigned(X) truncate
Usual Arithmetic Conversions for Binary operations
isfloat(X) && !isfloat(Y)Y=>typeof(X)
isfloat(X) && bitsin(X)>bitsin(Y)Y=>typeof(X)
Only if both operands are integer:
bitsin(X)>bitsin(Y) && (X & Y are both signed or unsigned)Y=>typeof(X)
bitsin(X)>bitsin(Y) && unsigned(X) && signed(Y)Y=>typeof(X)
bitsin(X)>bitsin(Y) && signed(X) && unsigned(Y)Y=>typeof(X)
bitsin(X) = bitsin(Y) && unsigned(X) && signed(Y)Y=>unsigned(Y)

Column Editing IDE Feature

Monday 12 June, 2023

The Editor in the V5 IDE has a column editing feature. This is useful if there are several lines that start or contain the same block of text but need to be replaced or edited. To use this feature, press the CTRL key on the keyboard while using the left mouse button on the mouse to select a block of text. Pressing DEL will delete that block of text, or typing will replace the text within the block with new text you type on each line.

This can also be used to simply insert the same text at a given spot on a group of lines. To do that select a thin column where you want the text inserted.

There are situations wherein there is a need to make repetitive but identical changes to each line, or copy a block of text and then add the same text or spacing to each line when editing source code. Column editing allows a way to enter or delete text on multiple rows at once.

Access this feature by pressing the CTRL key while making a selection with the left mouse button. This enables selecting a rectangular region to be able to type to replace its contents, paste over it, or delete it.

The following are some examples.

1. Editing identical variable types

Column Editing

In the above illustration, column select the "int" type, and then simply type "unsigned int", to all 3 lines at once.

2. Working with Enums

Maintain Tabbing

Above shows a selected rectangle consisting of all of the enum variants to avoid copying the spacing. Pasting it into the switch statement maintains its tabbing. Next insert "case" into each line by simply column select the space before "SHAPE" and type "case".

Bootloaders for Field Up-Gradable Programs

Monday 12 June, 2023

One of the most difficult things to deal with is upgrading a products firmware to fix a bug for products that are already in the field. It can be expensive and time consuming to do a recall of the products or send technicians to update the firmware. One option is to add a bootloader to the product. By using a bootloader it is possible to update a products firmware automatically or by the end user. One of the easiest types of bootloaders to implement is a serial bootloader.

A serial bootloader uses a serial connection, RS232 for example, to transfer the new firmware from a PC to the product, which is then programmed onto the product by a small program that runs on the device. To aid in quickly developing a serial bootloader, the CCS C Compiler has bootloader code that can be included in your project, as well has a PC program that can be used to transfer the firmware to product.

The CCS C Compiler provides the following bootloader examples, ex_bootloader.c and ex_pcd_bootloader.c. The first is an example of a serial bootloader for PIC16 and PIC18 devices, PCM and PCH compilers, and the second is an example of a serial bootloader for PIC24, dsPIC30 and dsPIC33 devices, PCD compiler. Both are an example of a standalone bootloader. Standalone bootloaders are small programs that run on the device that are responsible for both receiving the firmware and for programming it onto the device. In general, standalone bootloaders do not require the application for them to work. The size of a serial bootloader program depends on the device they are being used on, for example the CCS serial bootloader for PIC18 devices use 1280 instructions or 2560 bytes of ROM and always remains at the same location in ROM. Some PIC® MCUs allow you to specially code protect the bootloader area in ROM. Additionally the CCS C Compiler provides the following bootloader applications, ex_bootload.c and ex_pcd_bootload.c. Both are examples of applications that can be bootloaded onto a device using the ex_bootloader.c and ex_pcd_bootloader.c bootloaders. The key difference between a standard application and one that can be bootloaded is that the bootloadable application reserves an area of ROM for the bootloader. Frequently that area includes the reset and interrupt vectors so the application will use an alternate area that the bootloader can link to. In general #including the same bootloader.h file that the bootloader uses is all that needs to be done to build an application that is compatible with the bootloader.


A key consideration for bootloaders is deciding when to bootload. The bootloader program starts when the chip starts. If there is no application program in memory then it goes into bootload mode. That is the easy case. For reloading, a button could be used, for example hold that button down, power up and the bootloader sees the button down and starts the loading process. The application itself could trigger a bootload by writing a value to EEPROM and then resetting, the bootloader would see the special value and could force a bootload.

Finally CCS provides a PC program, CCS Bootloader, that can be used to transfer firmware (a .hex file) from a PC to a device that is running a CCS C Compiler bootloader. The CCS Bootloader program is a command line utility that may be distributed as part of the user's end product.

CAN Bus on a PIC® MCU

Monday 12 June, 2023

CAN bus is a message-based protocol allowing individual systems, devices, and controllers within a network to communicate. In general, a bus is a multi-node communication system that transfers data between components. A Controller Area Network allows for robust, low-latency, data transfer between sensors and compute units in a system. Without CAN Bus, wiring harnesses could contain miles of wire, with bundles of wires required to carry various signals to and from interconnected systems. In contrast, CAN bus utilizes a high-speed (25kbps - 1Mbps) twisted pair wiring system, greatly reducing the amount of wire necessary to allow system components to communicate.

The CAN protocol is a serial communication protocol that is used in the automotive industry for communicating between devices inside of a vehicle, the engine control unit and dashboard for example. Data is sent in frames and is done in such a way that if more than one device transmits at the same time the highest priority device is able to continue while the other devices back off. There are two CAN standards that are in use today, CAN 2.0 and CAN FD. CAN 2.0 is the older of the two protocols and has two parts; part A is for the standard format with an 11-bit identifier, commonly called CAN 2.0A, and part B if for the extended format with a 29-bit identifier, commonly called CAN 2.0B. Both parts can transmit data with bit rates up to 1MBit/s with up to 8 data bytes. CAN FD is a newer protocol that has flexible data-rate, an option for switching to a faster data rate, up to 5 Mbits/s, after the arbitration bits, which is limited to 1Mbits/s for compatibility with CAN 2.0, and it increases the max number of data bytes that can be transmitted in a frame to 64. CAN FD is compatible with existing CAN 2.0 networks so new CAN FD devices can coexist on the same network with existing CAN 2.0 devices.

There are several PIC® microcontrollers that have a built-in CAN 2.0 or CAN FD modules. For these devices, the CCS C Compiler comes with drivers for communicating with these protocols. There are separate drivers depending on the device being used. Additionally, the CCS C Compiler comes with several external CAN controllers. The following are a list of can drivers that are currently available in the CCS C Compiler:

  • can-pic18f_ecan.c - PIC18 CAN 2.0
  • can-pic24_dsPIC33.c - PIC24 and dsPIC33 CAN 2.0
  • can-dspic30f.c - dsPIC30 CAN 2.0
  • can-mcp2515.c - External MCP2515 controller CAN 2.0
  • can-dspic33_fd.c - dsPIC33 CAN FD
  • can-mcp2517.c - External MCP2517 controller CAN FD

J1939 is an upper level protocol that specifies how to send messages in a vehicle using the CAN 2.0 and CAN FD protocols. J1939 is maintained by SAE and the full J1939 specifications can be obtained from them. The J1939 is broken into several layers including, but not limited to, the Data Link Layer, Network Layer and Application Layer. These layers contain information about how to communicate on the network, how to claim an address, the format of messages, how often a message can be transmitted, etc. The CCS C Compiler comes with a J1939.c driver which is a library for the Data Link Layer running on a CAN 2.0 protocol network. The library has functions for claiming an address, responding to address claim messages, transmitting J1939 messages and receive J1939 messages.

Additionally, CCS also has several CAN development kits that can be used to aid in developing CAN Bus and J1939 projects. Each development kit has four nodes on it that can communicate with each other, as well as headers allowing the kit to be connected to an external Bus.

The first development kit CCS has is the CAN Bus development kit which has a PIC18F45K80 on the primary node and a PIC16F1938 on the secondary node. The primary node the PIC® MCU uses its built-in CAN peripheral for communicating on the Bus. The secondary node the PIC® MCU uses an external MCP2515 CAN controller for communicating on the Bus.

The second development kit CCS has is the CAN Bus 24 development kit which has a PIC24HJ256GP610 on the primary node and a dsPIC30F4012 on the secondary node. Like the previous kit, the primary node the PIC® MCU uses its built-in CAN peripheral for communicating on the Bus and the secondary node PIC uses an external MCP2515 CAN controller for communicating on the Bus.

The third development kit CCS has is CAN Bus FD which features a dsPIC33CH128MP506 on the primary node and a PIC16F18346 on the secondary node. The primary node the PIC® MCU uses its built-in CAN FD peripheral for communicating on the bus, and the secondary node the PIC® MCU uses an external MCP2517 CAN FD controller for communicating on the Bus.

Why Does the .LST File Look Out of Order?

Friday 10 February, 2023

The list file is produced to show the assembly code created for the C source code. Each C source line has the corresponding assembly lines under it to show the compiler's work. The following three special cases make the .LST file look strange to the first time viewer. Understanding how the compiler is working in these special cases will make the .LST file appear quite normal and very useful.

1. Stray code near the top of the program is sometimes under what looks like a non-executable source line.

Some of the code generated by the compiler does not correspond to any particular source line. The compiler will put this code either near the top of the program or sometimes under a #USE that caused subroutines to be generated.

2. The addresses are out of order.

The compiler will create the .LST file in the order of the C source code. The linker has re-arranged the code to properly fit the functions into the best code pages and the best half of a code page. The resulting code is not in source order. Whenever the compiler has a discontinuity in the .LST file, it will put a * line in the file. This is most often seen between functions and in places where INLINE functions are called. In the case of an INLINE function, the addresses will continue in order up where the source for the INLINE function is located.

3. The compiler has gone insane and generated the same instruction over and over.

For example:

This effect is seen when the function is an INLINE function and is called from more than one place. In the above case, the A=0 line is in an INLINE function called in four places. Each place it is called from gets a new copy of the code. Each instance of the code is shown along with the original source line, and the result may look unusual until the addresses and the * are noticed.

Program and Debug with Mulitiple ICD Units

Friday 10 February, 2023

CCS has implemented the ability to use multiple ICD units on the same PC. This allows you program or debug different target devices in separate projects without needing to close out of any files.

How to Do It with PCW:
Need two ICD units and target devices.

To run two PCWs → use the command-line option force_new

c:ProgramFilesPICCpcw → will open the first PCW

c:ProgramFilesPICCpcw+force_new → will open the second PCW

The USB port used by each target device will be visible in the Debug Configure tab within the Advanced Debugger under "port". You can select which ICD the Debugger should talk to using this setting.

How to Use with ICD Control Panels:
Need two ICD units and target devices

Open two ICD control panels by running the executable from your desktop.

At the start-up, the USB port will automatically be assigned for each ICD unit. You can then go the "Configure Port" button the control panel to switch ports.


Friday 10 February, 2023

These options lets the user configure the Pulse Width Modulation (PWM) pins. They are only available on devices equipped with PWM. The options for these functions vary depending on the chip and are listed in the device header file.

Relevant Functions:

  • setup_power_pwm(config) - Sets up the PWM clock, period, dead time etc.
  • setup_power_pwm_pins(module x) - Configure the pins of the PWM to be in Complementary, ON or OFF mod.
  • set_power_pwmx_duty(duty) - Stores the value of the duty cycle in the PDCXL/H register. This duty cycle value is the time for which the PWM is in active state.
  • set_power_pwm_override(pwm,override,value) - This function determines whether the OVDCONS or the PDC registers determine the PWM output.

Relevant Preprocessor:

Relevant Interrupts:
  • #INT_PWMTB - PWM Timebase Interrupt (Only available on PIC18XX31)

Relevant Include Files:
None, all functions are built-in

Relevant getenv() Parameters:

Example Code:
long duty_cycle, period;
// Configures PWM pins to be ON,OFF or in
// Complimentary mode.
// Sets up PWM clock , postscale and period. Here
// Here period is used to set the PWM Frequency as follows
// Frequency=Fosc/(4* (period+1)*postcae)
// *postscale)


set_power_pwm0_duty(duty_cycle)); // Sets the duty cycle of the PWM 0,1 in
// Complementary mode

USB Made Easy with the Compiler and USB Project Wizard!

Friday 10 February, 2023

The CCS C Compiler from the beginning has made it easy to communicate over an RS232 like port. Many of our users have used this extensively, not only for communicating with serial devices but also for diagnostics and debugging. Now, PC's and many other devices have replaced their RS232 ports with USB ports. The USB hardware and software is much more complex than RS232. This has discouraged many from migrating over or they have used a crutch like an external chip to do the USB magic (like FTDI). This article shows how to easily add a USB port to your PICR MCU application.

Microchip has a number of chips with built in USB. For example, the PIC16F1459 ($1.38/100) or PIC18F14K50 ($1.79/100). Here is an example schematic: (note: pin numbers apply to PDIP, SOIC, and SSOP packages)

Shown here is a USBmicro style connector. The more common type B connector is the same pinout except there is no pin 5 and 4 is the ground. The D+ and D- pins are for the data and sometimes there will be a 27 ohm series resistor and/or zener protection diodes on those pins. When using a peripheral device, pin 1 will supply 5 volts (up to a half amp). The board can be powered from that 5 volts; however, in this schematic it is to simply detect if the USB cable is plugged in. Although users can do that from the data lines, it is easier to detect the 5 volts like this. Sometimes users will put series coils on the 5 volts and ground to reduce noise.

The Vusb on this chip simply needs a cap for an internal voltage regulator. Some chips have a dedicated Vbus pin for the 5 volts detect. Careful with the pin names, as they are not consistent between chips.

The USB bus has a number of protocols that can be used, each with many options and configurations. HID (human Input device) is used for keyboards and mice and is easy to use on any OS because the drivers are built in. There is a data limit however, (like 8 bytes per ms) that makes it impractical for many applications. CDC is a protocol designed to emulate an RS232 port. The Windows drivers will create a virtual COM port for a CDC USB device so the PC application can use COM1... just like an RS232 port.

When a Windows 10 sees a CDC device, it automatically installs a driver for it. For older versions of Windows, users need a short .inf file to describe their device and include the device VID (vendor ID) and PID (product ID). Examples .inf files are in the CCS C Compiler examples directory. Every USB device is supposed to have a unique VID/PID and serial number. If users have two of the same devices plugged in, the VID/PID will match but they are differentiated by serial number. To get a VID users need to register with the USB standards organization.

USB is point to point and one point is a host and the other a device. Hub's can also be involved but that is beyond our concern for this article. The host initiates all activity. For example, a PC is a host and it will poll every device about once a millisecond and transfer any data needing transferring. When the device is first plugged into a port, there is a handshaking that takes place that involves the device identifying itself along with the protocol it will use and various parameters. For example, how much current it expects to draw off the bus. This handshake is called enumeration. In Windows users know it happened by the beep.

Some PIC24 parts have USB hardware that can also be a host. For example, this might be used to read a USB flash drive.

#include <16F1459.h>
#use delay(internal=48MHz,USB_FULL,ACT=USB)

#define USB_CON_SENSE_PIN PIN_A5 // Connected to USB +5V


#define USB_CONFIG_VID 0x2405 // CCS VID
#define USB_CONFIG_PID 0x8001

#define USB_STRING(x) (sizeof(_UNICODE(x))+2), \
//Microsoft Defined for US-English

char const USB_STRING_DESC[]={
USB_ENGLISH_STRING, //string 0 - language
USB_STRING("CCS"), //string 1 - manufacturer
USB_STRING("My-PIC-Device") //string 2 - product

#include <usb_cdc.h>

USB Wizard
The wizard allows the use of one of three communication protocols:

Communication Device Class, or CDC, creates a virtual COM port on a PC. On Windows PCs, this is the legacy COM ports (such as COM1) which can be opened with legacy terminal software. The CCS CDC library allows the use of printf(), putc() and getc() to communicate to the host PC using the virtual COM port.

Human Interface Devices, or HID, is a simple protocol for things like Mice and Keyboards. This wizard allows the user to create a HID project using a vendor specific HID descriptor report. CCS also provides a PC program written in VB.NET to communicate with the PIC in this manner. CCS also provides HID keyboard and HID mouse examples for the PIC.

Bulk transfers is a method of reading/writing directly to the buffer endpoint. Using this method does require drivers for your operating system, but since XP Microsoft has been shipping WinUSB which is compatible with this mode. CCS does provide a VB.NET demo application to show how to use this driver to communicate with the PIC.

CCS IDE Project Wizard includes USB. The IDE requires a minimum operating system of Windows 95(or later) or Linux.

Unique Compiler Features to Try

Tuesday 04 October, 2022

Add Flow Control and Buffering to Serial Routines
A feature of the compiler is the powerful #use rs232() library that has added transmit buffering, receive buffering, and flow control. While the API for the serial library remains unchanged ( getc(), putc(), printf() ), existing code using this API allows for buffering and flow control by simply modifying the #use rs232() parameters. A user may specify:
* size of transmit buffer
* size of receive buffer
* interrupt usage or no interrupt usage
* pin for CTS and pin for RTS

Click through to:
to review a usage example of the #use rs232() and additional details on each new usage. Additional configurations and control options are also available.

Notifications From the Serial Library on Data Reception
The compiler provides an extremely flexibly serial library; it has the ability to use the hardware peripheral or bit bang the pins, to control and monitor flow control, to specify parity, to use a one wire bus, and more. One feature it has is the ability to specify a receive buffer, and the library will automatically use the receive interrupt to buffer incoming characters. Here is an example of creating a stream called STREAM_UART1 on the UART1 hardware peripheral with a 16 byte receive buffer:

#use rs232(UART1, baud=9600, receive_buffer=16, stream=STREAM_UART1)

Essentially the stream works like a file handle that can be used with C standard I/O functions like fputc, fgetc, etc. Using the stream created above, here is a simple loop that echoes data received on the UART back to the UART:

while (kbhit(STREAM_UART1))
fputc(fgetc(STREAM_UART1), STREAM_UART1);

This example shows the flexibility of the #use rs232() library provided by CCS. The 'receive_buffer' option creates an interrupt on the UART receive to buffer incoming characters and kbhit() and fgetc() accesses that buffer, but if the 'receive_buffer' was removed from the #use rs232(), then kbhit() and fgetc() would instead check for any received data being held by the UART.

The 'receive_buffer' example as shown above has no way of notifying the users software that data is available, except by polling the receive buffer status with kbhit(). The 5.095 version of the CCS C Compiler adds a new option called 'callback' that allows the user to specify a function to be called when the receive buffer goes from empty to not empty. This could be used to mark a semaphore or enable a routine to start parsing data in the receive buffer. Here is an example of adding this new option:

#use rs232(UART1, baud=9600, receive_buffer=16, stream=STREAM_UART1, \

As stated earlier, this example will call the 'Uart1OnRx' function whenever the receive buffer goes from empty to not empty. Here is how the earlier echo example can be changed to use an RTOS with a semaphore to mark when the receive buffer is ready:

#use rtos(timer=0)
int uart_sem = 0;

static void Uart1OnRx(void) {


static void Uart1Task(void) {
for(;;) {
while(kbhit(STREAM_UART1)) {
fputc(fgetc(STREAM_UART1), STREAM_UART1);

Alternatively, a function for parsing data in the receive buffer can be queued for execution with the timeouts library:

#include <timeouts.c>

void Uart1OnxTimeout(void* pArgs) {
while(kbhit(STREAM_UART1)) {

static void Uart1OnRx(void) {
TimeoutsAdd(Uart1OnxTimeout, NULL, 0);

How can I use two or more ports on one PIC®?
The #USE RS232 (and I2C for that matter) is in effect for GETC, PUTC, PRINTF and KBHIT functions encountered until another #USE RS232 is found.

The #USE RS232 is not an executable line. It works much like a #DEFINE. The following is an example program to read from one port (A) and echo the data to both the first port (A) and a second port (B).

void put_to_a( char c ) {
char get_from_a( ) {

void put_to_b( char b ) {

main() {
char c;
while(TRUE) {

The following will do the same thing but is more readable and is the recommended method:

main() {
char c;
while(TRUE) {
c = fgetc(COM_A);
fputc(c, COM_A);
fputc(c, COM_B);

EZ Web Lynx

Tuesday 04 October, 2022

CCS sells a simple Ethernet network integration device which can be embedded into any product or into industrial equipment, appropriately named EZ Web Lynx. Essentially it connects products or equipment to an HTML programmable website with no other protocol language skills needed! The website will allow the user to view the equipment status and the user can receive emails from the device. The emails are triggered by changes in the state of the pins, which are configured through the easy-to-use EZ Web Lynx IDE.

EZ Web Lynx is available in either 3.3 or 5 volt, as well as a 3.3V Wi-Fi versions at a very low cost to make implementation to the Ethernet very affordable. EZ Web Lynx enables products and equipment to become Ethernet-ready without having to design a new circuit board which can drastically increase development time.

HTML is the only programming language needed to program the website. However, if you prefer to program in C, the CCS PCH or PCWH compiler is compatible with EZ Web Lynx. To find out more about this product and for detailed pricing please go to

 Displaying 1 to 10 (of 224 articles)   Result Pages:  1  2  3  4  5 ...  [Next >>]