Maria Montero

Firmware Design: How to Program an MSP430 Microcontroller to Collect Data …

This article reviews the firmware design for a custom PCB project – a precision inclinometer subsystem.

I recently designed a custom PCB with a muRata SCA103T-D04 IC inclinometer. My goal was to build a subsystem with really ridiculous precision, capable of accurately detecting down to a thousandth of a degree of tilt.

This article will cover some highlights of how I designed the firmware for the onboard MSP430 microcontroller to collect and process IC data.

To catch up on the project in general, check out the articles below:


It’s difficult to create an electronic circuit these days without having to do a certain amount of programming. Unfortunately, the knowledge you gain from learning how to create firmware for one manufacturer is not necessarily applicable to another.

For this reason, it is generally a good idea to purchase a Evaluation board so that you can learn how to program your microcontroller on a board that will surely work before you pull your hair out with your own design. It is also a good idea to familiarize yourself with the resources that the manufacturer has made available to you: forums, data sheets, user guides, videos, etc.

In this case, I used the MSP430FR2633, so I practiced with the MCU CapTIvate MCU development kit and approached the TI E2E community for advice.

This article does not cover every line of the source code; rather, it provides general information on firmware programming using the source code as an example.

Adding an ASCII Pinout Diagram

Finally, I want to add some extra reference for myself. Since this is a custom dashboard, I want to provide myself as much information in one place as possible. There’s a great chance that I won’t remember what my pin connections are in an hour, and I certainly won’t remember a week from now. If I make any changes to the programming it would be nice not to have to dig up the schematics.

For that reason, I included a connection diagram in the source code. There are a variety of The ASCII diagram generators available on the web make this a relatively quick operation.

                    // CP2102N ┌──────┬──────┐ ┌────────────┐
// ┌────────────┐ │ │ P1.0 │ → UCB0STE → │ EN (NC)
// │ USB │ → RX → │ P2.5 │ P1.1 │ → UCB0CLK → │ CLK │
// │ TO │ → TX ← │ P2.6 │ P1.2 │ → UCBSIMO → │ SIMO (NC)
// │ UART │ │ │ P1.3 │ ← UCBSOMI ← │ SOMI │
// └────────────┘ ├──────┼──────┤ │ │
// ST_IN1 ← │ P2.0 │ P2.4 │ ← BUSY ← │ BUSY │
// ST_IN2 → │ P2.1 │ P3.0 │ → RDL → │ RDL │
// │ │ P3.1 │ → CNV → │ CNV │
// └──────┴──────┘ └────────────┘
// MSP430FR2633 ADC


The first thing we’ll have to do is deal with our pins so the compiler knows which devices are connected to what. To do that, you will need to understand the concept of records. If you are already familiar with these concepts, feel free to jump to the “Defining record description shortcuts” section below.

What are logs?

Registers are locations in memory identified by hexadecimal numbers, and bits belong to the register. The bits in each register control a specific aspect of the microcontroller’s functionality.

Each register controls one byte (8 bits) or one word (16 bits). To keep the discussion simple, however, the following diagrams illustrate the registers that control a single byte.

Defining record description shortcuts

Now that we have a short summary of the records, let’s use it in context.

The record descriptions in the The MSP430FR2xx Family User Guide indicates which bits control which functions. When a register does not allow direct access to individual bits, you can use byte operations in conjunction with an appropriate bit mask; individual bits can be set with the “| =” operator, can be cleared with the “& =” operator, or can be toggled with the “^ =” operator.