Cool Cap Engineer

Implementing PWM On PIC18F Microcontroller

PWM output with 20% duty cycle.

What is PWM?

As you guys know, microcontrollers, FPGAs, and other embedded processors can only output a high or low signal based on the power supplied to it. In other words, embedded processors cannot output a variety of voltages. Despite this, we have the processor “pretend” to output different voltages using a series of pulses and varying the width of the pulses. The technique of varying the width of a series of pulses is called Pulse Width Modulation (PWM).

The picture above shows an example of a simple pulse train.  The time it takes for each pulse to start again is referred as its period (Ts).  In each pulse train, the pulse is on for a certain amount of time before turning off. The percentage which the pulse’s on time compared to its time off is called the duty cycle.  Duty Cycle is expressed as…

$D=\frac{T_{on}}{T_{on}+T_{off}}$

PIC18F And PWM

As you’re already aware of, all microcontrollers feature a set number of PWM pins. But what pins are specifically designed for PWM? When reading your PIC18F datasheet, look for pins that have CCP (compare capture pwm) labeled. So let’s look at a picture featuring the PIC18F4553

As you see in the picture, RC1, RC2 and RB3 can be configured as PWM pins.

PWM Calculations

So there are three crucial registers you must take in account for PWM: PR2, and CCPRXL:CCPXCON[5:4]. Configuring the PR2 register, will allow you to configure the PWM period while selecting a proper the value for CCPRXL:CCPXCON[5:4] will allow you to choose the right duty cycle. For choosing the right value for the PR2 register, use the following equation…

$PR2=\frac{PWM Period}{4*T_{osc}*TMR Prescale Value}-1$

Keep in mind that Tosc is the the inverse of the frequency that your microcontroller is running at. Also, we will use a prescale of 16 as we will use this in the upcoming code example. For CCPRXL:CCPXCON[5:4], we will use the following equation…

$CCPRXL:CCPXCON[5:4]=\frac{PWM Duty Cycle}{T_{osc}*TMR Prescale}$

CCPRXL:CCPXCON[5:4] is a 10 bit number. To make things easier on you guys, make sure you convert your number to a 10 bit binary number. After you convert the number to a binary number, set your CCPRXL register to the first 8 MSB numbers. Finally, take the last 2 LSB and you use it for your CCPXCON[5:4].

PWM Coding Procedure

Now that I talked about the calculations, let’s talk about how to code your PIC18F microcontroller to use PWM. For this tutorial, we will use the PIC18F4553’s  CCP1 pin, set the PWM period at 1KHZ, a time prescale of 16, a clock frequency of 8*10^6 and a 50% duty cycle.Parts of the final code can be found in my Beginner’s Guide To PIC18F Microcontroller.

First we need to configure the CCP1 pin as an output pin,which is RC2.To do this we set the TRISCbits.RC2 to 0 and PORTCbits.RC2 to 0.

TRISCbits.RC2=0;
PORTCbits.RC2=0;


Now, we need to choose a value for PR2 register. Here is my calculation for PR2.
$PR2=\frac{10^{-3}}{4*16*\frac{1}{8*10^{6}}}-1=124$
Now that we found the number, let’s convert it to a binary number and use it.

PR2 = 0b1111011;

PWM uses timer2 to work. So we need to not only turn on timer2, but we must set the time scale to 16. This can be done by properly configuring T2CON by setting T2CON’s TMR2ON to 1, and T2CKPS1 to 1.

T2CON = 0b00000111 ;

CCPR1L:CCP1CON[5:4] is the last thing to compute.
$CCPR1L:CCP1CON[5:4]=\frac{\frac{1}{10^{3}}*.5}{\frac{1}{8*10^{6}}*16}=250$
When we convert 250 to its binary value, we get 0011111010. However, we take the first 8 MSB for CCPR1L and the last 2 LSB for CCP1CON bit 5 and CCP1CON bit 4.

CCPR1L = 0b00111110;
CCP1CON = 0b00101100;


Since you guys been so swell, here’s the final code for this example.

#include <p18f4553.h>
#include <stdio.h>
#include <stdlib.h>
#include <usart.h>
#include <delays.h>
#include <portb.h>

#pragma config FOSC = HS
#pragma config WDT = OFF
#pragma config LVP = OFF
#pragma config PWRT = ON
#pragma config DEBUG=OFF

int main(void)
{
TRISCbits.RC2=0;
PORTCbits.RC2=0;
PR2 = 0b01111100 ;
T2CON = 0b00000111 ;
CCPR1L = 0b00111110;
CCP1CON = 0b00101100;

while(1);
}


Mojo Makes FPGA Board Design Open Source

Last January, I’ve been learning how to use FPGAs, which I talked about in my Getting Started With FPGAs post.  To learn how to use FPGAs, I brought FPGA development boards, which can cost up to $110, from Digilent.com. Fast forward to March, and I found Mojo, an open source$75 FPGA development board, on Kickstarter.com. Based on what I’ve seen and tested thus far, I honestly think the Mojo board is a great introduction to digital design for electronic hobbyists and electrical engineering students.

What’s Under The Hood?
Unlike the Basys 2 that I commonly use, the Mojo uses a Spartan 6 XC6SLX9 FPGA. The Spartan 6 uses a 50MHZ clock, which is 10MHZ higher than the maximum clock frequency that a PIC18F can run.  In layman terms, it can run faster than most of my microcontroller/FPGA boards. The board can accept between 5V-12V, but can only output 3.3V for each digital I/O pin. Because of the Mojo’s 3.3V limitation, you’ll need extra hardware to use electronic items like servos, solenoids, etc. Finally, the Mojo uses an Atmega16U4 for the USB connection among other things.

What’s So Special About The Mojo?

The Mojo board is geared towards making digital design easy for hobbyists and electrical engineering students by taking advantage of the board’s Atmega16U4 microcontroller, which is used to implement your digital designs on to the board. However, the Atmega16U4 is not just used for uploading your designs to the Mojo. The Atmega16U4 is used to communicate serial objects like serial LCDs, XBee wireless modules, and even Sparkfun’s FTDI breakout boards, with the Mojo.  You can even use the analog to digital converters included with the Atmega16U4 to allow the Mojo to take in analog signals.

What I Love About The Mojo ?

Although this seems like a petty thing, one of the key qualities I look for in a FPGA development board these days is the number of accessible I/O pins.  When I first heard that the Mojo will offer 84 accessible I/O lines, I immediately gave my pledge for the project  In fact, the lack of accessible pins for the Basys 2 FPGA board severely limited me in terms of FPGA projects. Embedded Micro even added 8 LEDs on the board for FPGA beginners to use. These LEDs are prefect for beginners as they implement simple modules using these LEDs. During the early stages of testing the board, not only did I create a blinking module for one LED, but I also used the same module to control the other seven LEDs on the board.

Despite the sheer number of I/O pins available, one cannot forget the fact that the Mojo is open hardware, which simply means that the Mojo’s schematic is available to view. This is crucial if you want to create your own FPGA development board, but do not know where to start. In fact, I will probably use the Mojo’s schematic in the future.

Work Done Thus Far ?

Currently, I do not have any project plans for the Mojo board. My focus has been learning how to effectively use the Mojo board. Recently, I learned how to control a servo using the Mojo board, even though most servos can only powered using 5V. I was able to control the servo by connecting one of the Mojo’s pins to the optoisolator’s input pin, and the servo’s signal pin to the optoisolator’s Vo pin. Although I could not find a power supply around, I used my Arduino board to provide the right power to the servo.

Where Can I Learn How To Use The Mojo Board?

Although I am planning to write tutorials on how to use the Mojo board for this blog, you can visit Embeddedmicro.com, where you can read tutorials on how to implement serial communication, servo control, and other digital modules onto the Mojo. If you want to purchase your own Mojo board, then visit this URL. Please keep in mind that the Mojo board only cost \$75.

Tutorials: Getting Started With FPGAs

So today, I thought I would talk about something other than microcontrollers. Today, I will talk about how to get started with FPGAs.

What is a FPGA?

An FPGA is a field programmable gate array. Instead of programming a FPGA  like your standard microcontroller, you actually “implement” digital circuits using a hardware description language (HDL). The two common hardware description languages includes VHDL and Verilog. For today’s tutorial, we’ll implement our design using Verilog.

FPGA vs Microcontrollers

So what are the advantages of using a FPGA rather than a microcontroller?  The problem with microcontrollers is that they cannot run co-currently, or only run sequentially, and very time limited. A FPGA runs in parallel, or able to run multiple things at once, and much faster than microcontrollers.  However, FPGAs are very space limited and initially does not come with all of the fancy peripherals that microcontrollers have. Things like timers, UART, and SPI must be implemented by hand on the FPGA. Also, to have your design stay with the FPGA,  you have to use a re-programmable flash memory IC.

Parts List

To get started, you need only the following items

Hardware

Software

Installing Xilinx Web ISE

• To learn how to install the Xilinx Web ISE, I highly recommend visiting this URL .They have all the necessary information on properly installing the ISE.

• To program the Basys 2 board, you need to download Adept from Digilent’s website. Just follow the on screen prompts for proper installation.

Starting A Project

• To create a new project, go to file->new project
• At the create project screen, select a name and location for the project. For this example, let’s name the project “First_Project” and set the location to any location on your computer. Make sure you select “HDL” as your Top-level source type.
• For project settings, make sure you have the following set…
1. Family is set to Spartan3E
2. Device is XC3S100E
3. Package is CP132
4. Speed is ~4
5. Synthesis Tool is XST (VHDL/Verilog)
6. Simulator is ISim (VHDL/Verilog)
7. Preferred Language is Verilog

• At Project Summary, select Finish.

Creating Verilog Module

• At the project menu, you should see x3s100e-4cp132. Right click on this and select “New Source”
• At the new source menu, select Verilog module and set the name to blink.
• When prompted at the define module, just click next. We’ll define the inputs and outputs later on. Afterwards select finish.
• In your blink.v file, copy and paste the following code into the file.
• Make sure to hit save.

Creating UCF File

Although we created the module, the FPGA does not know which pins on it should be connected to the module’s inputs and outputs. This is where the UCF file comes in.

• Right click you blink.v file and select “New Source”
• In your new source menu, select ” Implementation Constraints File.” We’ll name this file “blink”. Don’t worry, this will not replace the blink.v file.

• Hit next and select finish
• Make sure to hit save.

Creating Bit File

Okay, so we’re almost ready to program- I mean ” implement”- our digital design on the FPGA. FPGAs are usually programmed using a bit file. We’re going to create a bit file using the Web ISE.

• Your should see ” Generate Programming File” in the Processes menu. Click on it.

• Wait for a little bit for the ISE to finish creating the bit file.

Checking Connections

It is very important to check to see if the FPGA really routed the inputs and outputs correctly. To do this…

• In the Processes menu, select ” Design Summary/Reports”
• In Design Overview click on ” Pinout Report”
• Check to see if “clk_in” is connected to B8 and “out” is connected to M5.

• As shown above, the ISE did not correctly route the connections. This can be solved by resaving your UCF file and clicking the “Generate Programming File” option again.

We’re at the final part of the tutorial!

• Connect the Basys 2 to your computer and turn on it on.

• You can upload the bit file to the main FPGA or the board’s re-programmable flash memory. Since we want the board to remember the bit file whenever we turn on or off the board, we’ll program the bit file to the reprogrammable flash (PROM)
• Click browse button next to the PROM option
• Navigate to your project folder.  The bit file should be inside the folder.
• Hit “program” next to browse
• After the bit file is uploaded to the board, turn off then turn on your board. You should see  LD0 blink every 500ms.

How does it work?

First thing, we need to use the 50MHZ clock on the board to tell the FPGA when 500ms has occurred. But how? Well, frequency is really counts per second. Using unit conversion and an onboard counter , we can find how many counts it takes for 500ms to occur.

$\frac{50,000,000}{seconds}*500ms=25,000,000$

Now that we know the counts, how do we use it in our design? We can use a register, a variable inside verilog, to function as our counter.  During the positive edge of the clock, we tell the design to increment the counter by 1. When counts reaches 25 million, the design resets the counter to 0 then invert the output of the LED, which is initially set to off.