If Only I Had One More [insert function here]!
There is one essential difference between embedded programmers and general computing programmers, and it has to do with the amazing variety of hardware we embedded programmers get to play with. I like to think of us as test pilots. While the larger community of pilots fly the same airplane and often the same routes every day, we enjoy a variety of machines and configurations that change often, searching for optimal cost, speed and utility in response to the market needs and/or our customers’ desires. As a result, our job is never boring - although, at times, we wish it was. Hence our somewhat bipolar approach to innovation. On one side, we try to find any excuse to play with the latest and greatest product/model prizing innovation and revolutionary advancements. On the other hand, we hate the learning curve that comes with it, and we wish everybody would use the same compiler, library and tools we just got familiar with and we learned to love… Only incremental changes, please…
Take Your Pick
We are in the year 2018, and when it comes to microcontrollers’ variety, there is no doubt in anyone’s mind that we have more than enough to choose from. We can pick any number of pins, any number of bits, any architecture and almost any combination of Flash and RAM memory. In fact, much of the competition among vendors in recent years has been focused on adding more of the above and expanding the resulting matrix of choices.
Some will argue that given sufficient clock speed and program memory space, any application can be written using only a bunch of general purpose I/Os (and I’ll throw in an ADC and a PWM for good measure). This sounds almost like a trivial corollary of Alan Turing’s original work on the General Purpose Computing Machine, extended to serve our embedded use case.
But, hopefully, we all agree that that this is not a sensible or practical strategy. After all, Alan Turing himself never built or used one of the machines that carry his name today.
Hopefully we all agree the embedded applications we develop today need a rich set of peripherals (functions) and this complicates matters, expanding the matrix, quite a bit.
So, even in 2018, in the world of ample embedded control choices, it is not uncommon for us designers to start working on a project using a given microcontroller model, only to realize we have to switch to a different one mid-project. Mind you, this is not for a lack of trying – it happens to lazy engineers who skipped proper analysis at the start and also to those who have done ample preparation and analysis. It is more often a matter of complexity: much like in a chess game where we can only play so many moves ahead in our mind. It can be hard to see how the peripheral functions interact with each other as we put them to use in our applications, or it may be hard to predict the evolution of the hardware solution as the project requirements drift (as they always do) and deadlines loom ahead.
At best, a microcontroller change can be a minor disruption, and we are lucky enough to find a close match in the same family of devices from the same vendor. Things get more difficult when that option is not available, forcing us to change the device family, which often produces a domino effect as pinout changes and possibly other peripheral functions follow.
Core Independent Peripherals to the Rescue
The best way to deal with these types of issues is to plan ahead for them. Most recent microcontroller families do provide smart ways to rearrange the pins for each of the peripherals offered. I am not referring to a single alternate pin function (that is so 90’s) – I am talking about full pinout remapping for analog and digital functions. For example, in the Microchip portfolio of 8-, 16- and 32-bit microcontrollers this is known as the Peripheral Pin Select (PPS), every pin on the device will be able to operate as an input for any number of peripherals (up to 64 different ones in some models), and any peripheral output can be published on up to 16 different pins (even 32 in some models). Analog inputs to the ADC will be similarly multiplexed among the vast majority of the device pins (up to 35 out of 40 pins, for example).
While this is already great insurance against future migration incompatibilities, the real game changers in the Microchip devices are the Core Independent Peripherals (CIPs). Keep in mind, this is not the primary reason CIPs were created. The goal of Core Independent Peripherals was to reduce the workload of the microcontroller CPU by automating as many of the low level and coordination activities normally required by traditional peripheral functions as possible. But the extra connection available and the flexible nature of the CIPs make them a perfect tool to solve the mid-project crisis.
A practical example: creating a new PWM function out of thin air
For a practical example, I want to bring your attention to a case that occurred recently. We were designing an enhanced version of an automotive sensor, which involved the use of several timers, a pair of 10-bit Pulse Width Modulation (PWM) modules and an analog comparator, all easily found in a humble 28-pin PIC16F18855 microcontroller. We quickly realized that we reached a hard limit in the resolution of our current design, and if we proceeded any further, we would need a 12-bit or higher resolution PWM register. Unfortunately, that option was not on the menu. Any similar 8-bit PIC microcontroller that shared a compatible form factor (and pinout) was either offering too small a program memory or adding a much larger/richer set of peripherals and higher cost. All we needed was one more PWM register with 12-bit or better resolution.
Luckily, PWM peripheral functions are quite simple to synthetize on a chip if you have a few flexible blocks and a bit of glue logic. Any PWM can be assembled by combining two elements in particular: a periodic pulse and a limit counter. In Figure 1 you can see how the two can be combined to provide the period and the duty cycle of the resulting square wave.
Figure 1 – A PWM as the sum of a base timer and a limit counter
The time base can be implemented with any standard timer as long as it can produce a periodic pulse with the desired frequency (~500 Hz in our case). For our application, the timer can be an 8-bit basic timer/counter and can be shared with other functions (PWMs or otherwise). In our application, we reused TMR2, a basic (8-bit) timer with a match register (PR2).
The limit counter is a little more sophisticated, but not an unreasonably complex or rare function. Once triggered, this timer needs to be able to count up to a limit (as the name implies) and generate a pulse and stop. It will reset and start again upon the next trigger input. This function is often referred to as a retriggerable monostable, or in the PIC literature it is known as a Hardware Limit Timer (HLT).
The HLT in the SMT
Unfortunately, if we desire a 12-bit or higher resolution on the PWM duty cycle, the typical HLT available on a PIC microcontroller is not going to cut it. On modern PIC microcontrollers, even numbered timers offer the HLT function but provide only an 8-bit counter. However, there is another less-known peripheral that can get us the resolution we crave. This is the Signal Measurement Timer (SMT) represented in Figure 2.
Figure 2 – Block diagram of a Signal Measurement Timer (SMT)
If the HLT is little more than a timer with one extra trigger/reset input, the SMT is essentially a timer with two such inputs. It happens that there are a number of interesting ways to combine those two inputs to obtain a variety of time, frequency and duty cycle measurements -- hence the name.
The device datasheet lists as many as 11 such modes, which is enough to scare most novice users and make the SMT the most misunderstood and under-utilized among the CIPs. I have no room here to dive into the details of all the modes, but it will suffice to mention that one of them – perhaps misleadingly named Window Measurement Mode – essentially turns the SMT into a HLT. In fact, it’s a very large HLT, as the SMT has a 24-bit counter and a period register of matching size.
Combining the base timer and the limit counter is the job of a set/reset (S/R) latch. This function is available on many PIC microcontrollers, but in the past five years it has been integrated as one of the eight functions provided by the Configurable Logic Cells (CLCs), a staple among the Core Independent Peripherals (CIPs). Figure 3 illustrates how the two signals are fed to the S/R latch inputs, as visually configured when using the MPLAB Code Configurator (MCC) tool.
Figure 3: Configuring the S/R Latch using MPLAB Code Configurator
Since the PIC16F188xx devices used in our application offered as many as two of the SMT modules, we were able to synthetize not one, but two, new PWM modules with as much as double the resolution required.
PWM Effective Resolution
It is a common misconception among novice users that the resolution of a PWM register is simply given by the nominal number of bits of the timer controlling the duration of the on pulse (duty cycle). By that definition, we would have just assembled a 24-bit PWM function - but that is not true.
The fact is, period and duty cycle of a PWM are not fully independent quantities: They are both controlled by timers/counters as we have seen above, and there is a common relationship with the peripheral clock of the microcontroller.
For any given peripheral clock, the counter that is responsible for the on time will only be able to count up to a MaxCount value before the time base period repeats. At that point the PWM register will have reached 100 percent duty cycle and no additional number of bits in its register will ever be used. The formula below determines the effective resolution of the newly constructed PWM register in our previous example:
MaxCount = Tperiod * Fclock
Or in our case for Tperiod = 2 ms and a peripheral clock frequency of 32 MHz
(Note that the SMT can be clocked directly with the maximum system oscillator frequency, and is not limited to the CPU instruction clock, which is divided by 4, as most other PIC peripherals)
Max Count = 64,000
The logarithm in base two of the MaxCount value is the effective resolution of our PWM in bits, which just happens to be close to 16 bits (MaxCount < 65536).
This result is a confirmation that the new PWM module is indeed more accurate than the 10-bit standard PWM modules we started with, but it can also help us decide to safely ignore the upper 8-bit of the SMT timer and its match registers to simplify set up and general management of the newly constructed function.
Notice how we assembled a new and effective 16-bit PWM module without using any additional external component(s). Instead, we simply configured, inter-connected and re-used a small number of functions available on the chip. Perhaps even more of note, we can replace the newly-constructed one in the pre-existing solution without modifying the board layout, as the Peripheral Pin Select (PPS) feature allows us to deploy the new function on any pin(s). Further, the newly constructed module is behaving as a fully autonomous function (the nature of CIPs), as no processor time is required to maintain its continuous operation aside from the initial set up and occasional duty cycle adjustment.
Lucio Di Jasio is the EMEA Business Development Manager for Microchip Technology Inc. He has been covering various technical and marketing roles within the company’s 8-, 16- and 32-bit divisions for the past 18 years. As an opinionated and prolific technical author, Lucio has published numerous articles and several books on programming for embedded control applications. Following his passion for flying, he has achieved both FAA and EASA private pilot license certifications.