Starting from scratch with a microcontroller in some cases can be faster than using boards already prepared for prototyping such as Arduino, Mbed-Nucleo, etc. and helps to acquire the basis for a thorough knowledge of the subject.
In this first post we see how to create the work environment, how to choose the microcontroller, how to make the first basic hardware configuration, and verify that everything is working by flashing a led.
Choice of microcontroller
I do not dwell on the reasons that lead to the choice of a particular microcontroller manufacturer; suppose we have to use Microchip PIC family microcontrollers. There are several factors involved in choosing the right micro, not last the price and availability. By focusing on technical motivations to meet the needs of the next posts we need:
- RS232 and I2C Communication.
- Large memory for data and program.
- Low consumption.
- High clock.
Microchip provides a nice tooll for micro selection, located on the microchip design center page, from which you can select the "PIC MCU Search" entry. You access a page as the one shown in the figure where you can specify filters to select the PICs closest to your needs.
With the features written above it is easy to verify the need to use a chip of the PIC18 family, as PICs of inferior families do not have the necessary communication ports. Regarding the availability and price level I selected the PIC18LF24K40/SP (the last two letters indicate the type of package that in the specific case is SPDIP ie it has pins needed for use in a breadboard, while the letter L specifies the model with low operating voltage from 1.8V to 3.6V).
Test bench setup
Only a few components are needed:
- Breadboard with cables.
- 5VDC 500mA power supply, or two 1.5V battery connected in series.
- Components listed in the following schematic.
Finding the inspiration to make the necessary electrical connections is not difficult, just look at the downloadable datasheet from the product page at the "Guidelines for getting started" chapter.
In the schematic the stabilizer to get 3.3V is only required if you use the 5V power supply or otherwise directly connect the series of two stylus batteries to the VDD of the micro.
Pin 1 is micro reset. On the production circuits, it must be suitably filtered to make the microcontroller immune from any electrical disturbances such as caused by switching on and off a fluorescent tube. For our purpose, it's enough to connect it to the power supply with a 10K resistance, as it is low active.
On the VDD and VSS pins there is a bypass capacity (as above to eliminate any disturbances). For production pourposes one capacitor is not enough, on this subject we will open a special chapter.
On the RB3 port connect the led with the resistor (470R), the connection type suggests that we will turn it on by bringing the port value to zero.
Finally there are the necessary micro-programming connections (ICSP); see below as it works.
The most common development boards have a chip for micro programming, starting from the microcontroller only, an external programmer must be found. For PICs, the market offers programmers for all pockets, from open source projects that allow you to build it, to programmers supplied by Microchip at a cost of around 50 € to the most powerful ones that costs few hundred euros.
I use MPLAB ICD3 that allows you to download the .hex file generated by the compiler to the microcontroller via a special application (IPE) or directly from the development ID (MPLABX).
Whatever the programmer you are using, you need to identify the pins to fit them properly on the breadboard. Using ICD3 the pins position on the connecting cable (RJ11) is as follows:
It would be a good idea to check the communication with the micro using the programming tool. Using IPE you can see if the programmer recognizes the microcontroller by making a connection and verifying the device id. Simply select the microcontroller model and connect.
For this project, I will use the Microchip MPLAB-XC compiler and the MPLAB-X-IDE development environment, which can be downloaded for free. It is also possible to use the cloud development environment MPLAB Xpress which allows you to avoid downloading and installing IDE and compilers. By registering you can have a remote development environment that keeps your codes and makes them accessible from any location.
I do not dig into the installation procedures because they are just a sequence of yes, accept and continue. The only thing I'm suggesting is the installation of MPLAB Code Configurator, which at this initial stage allows you to immediately reach the goal by developing a professional code and giving you a useful track to structure the program. This program is installed as an MPLAB-X-IDE plugin (tools -> plugins-> available plugins -> install).
Let's start with a pinch of theory. Normally, the LED blinking for a microcontroller corresponds to the "Hello World" program for a programming language. Paradoxically, every time this first step is disclosed, the delay() function in the main loop is used to determine the time for turning the LED on and off. Nothing more dangerous for correct embedded programming education. If there is a fundamental principle to be tatooed on body it is that the microcontroller can not disperse its limited resources to count sheep while a led stays on. For those who are old like me is a bit like getting back to the MS-DOS time when a whole computer locked up to format a floppy disk.
There are four ways to get a led blinking:
- Use the delay() inside the main loop (already mentioned my opinion).
- Use watchdog; but it would be more than worst than the delay().
- Counting the program cycles and reversing the status of the port at a certain number of counts.
- Use timers and possibly interrupts.
The third option leaves the micro resources free while the LED stays in one of the two states than it is a practice I can suggest under certain circumstances, but the fourth option uses one of the seven timers provided with the PIC18LF24K40 and allows us to use properly the hardware we have.
In order to deepen the subject, we find the datasheet that should always be considered as the only source of information. Before deciding how to set the timer, you have to decide at which frequency we put the micro running: we are going to move the first steps with the MCC tool.
Using IDE we create a new empty project: New project -> Microchip Embedded -> Standalone Project
We now have an empty project. Select the MCC icon and wait a few moments until the next window opens:
This is a fairly recent achievement that allows us, through a graphical interface, to set up the micro peripherals without going into the initialization of the registers.
The central window welcomes us with a promising tab labeled "Easy Setup", we use it by setting the selected oscillator to HFINTOSC 64MHz (ie high frequency internal oscillator). Now we know the speed of the heart of our micro.
Under the central window, where the pin list is listed, we set the Package on PDIP28. Our LED is connected to the RB3 port, we click on the padlock at the intersection of the GPIO output line with the Port B3 column, this way the PIC register is properly configured to set Port B3 as an output.
If we click the "Pin module" item in the upper left panel we can see that the "Easy Setup" tab shows the current settings of the RB3 pin. As we are concerned with the digital output of the pin, we uncheck the "Analog" box, and since our LED should be off at the start of the program we check the "Start High" box.
Now is the time of the timer. From the left pane, "Device Resources", scroll up to the "timer" option, open the drop down menu and double click on TMR0.
In the "Easy Setup" tab into the "Clock Source" list box, you can choose between several sources the clock that will give the time to the timer. Excluding the last three options, which are external clocks, we can choose between High Precision Internal Oscillator, Low Power Internal Oscillator and FOSC/4 which is 1/4 of the system frequency. Selecting this, since the system frequency is 64MHz, the timer will increase its value at a frequency of 16MHz or 62.5 nsec. We will not use an interrupt to check when the timer expires, there is a simpler way: the timer0, if set to 16bit, sets the T0IF flag to one every time it reaches the value 0xFFFF; this means that the timer goes into overflow every
62.5e-9 x 65535 = 4 msec (approx.).
If we want to blink the LED every second we have to use the prescaler or the postscaler to divide the timer working frequency. Write by hand "1 s" into the "Requested Period" field (we will see the meaning of this parameter in the next post), than set the values as in the figure.
In the upper left there is the "Generate" button by pressing which we will get the configuration files needed to set the micro as by our choices. We click the MCC icon to close the plugin, the list of generated files appears in the figure. The main.c file was also created.
During the next tutorials, we will understand the various files. Currently we are interested in knowing that MCC has created for us in the tmr0.c file the TMR0_HasOverflowOccurred() function to see if the timer has reached the maximum value, and in the pin_manager.c file we have the macro/function IO_RB3_Toggle() which allows us to drive the LED.
Add into the main program loop of main.c file the instructions for checking the timer overflow and to change the status of the RB3 port on which the LED is connected; we can see that once the PIC is configured the main program is only three lines long.
All you have to do is build and download the program on the PIC to get the status LED blinking once a second.