Professional Documents
Culture Documents
Tiva c Gpios
Tiva c Gpios
Tiva c Gpios
Never exceed input logic high voltage of any pin beyond VDD limit unless you are sure that
the source will not exceed the 5V limit and you aren’t using the any of the exceptional pins
(PB0, PB1, PD4 and PD5). It is better to leave these pins idle unless you have memorized
these pin numbers. Fortunately, PD4 and PD5 are inaccessible in the Tiva C Launchpad board.
Likewise, don’t use negative input voltages with any pin. Be sure of polarity.
Some GPIO pins are not accessible in Launchpad board while others are physically non-
existent, e.g. PF7 and so don’t try to program them. Leave them alone just like a don’t care
bit of a register.
When coding a new project, I recommend adding a delay of about 2 - 3 seconds at the start
of the code to avoid part lockout.
Don’t stress any GPIO pin beyond 10 - 15mA, although the max limit is 25mA. Use external
switching devices like opto-isolators, FETs and BJTs to drive high power loads.
Though most pins are 5V tolerant, it doesn’t necessarily mean that the logic level is based on
5V TTL logic level. The logic level voltage limits are still realized with respect to VDD, 3.3V.
Similarly, when using TIVA C micro’s ADC, the ADC pins can withstand voltages beyond VDD
voltage limit but can’t measure voltages beyond VDD or reference voltage level.
GPIO pins have alternate functions and so use Pinmux software to find required GPIO pins.
You can also checkout the alternate function pins in the help section of MikroC compiler
under the GPIO library. In the compiler, if you type _GPIO and hit CTRL + Space, you’ll see all
available options for GPIO.
Both the GPIOs and their registers are all 8-bit wide just like 8-bit micros but there are many registers
and options related to each port pin. We can code these registers on our own or use MikroC compiler’s
GPIO Library and get GPIOs working. Here I’m preferring the use of MikroC’s library functions because
this library allows us to set every option related to GPIOs much more easily and quickly than it would
have been otherwise. We will still have an overview of the registers. Please note that neither will you
find GPIO Library in the compiler’s Library Manager nor will it be needed to add this library in a project
like other built-in libraries. This is because GPIOs are the most common things we use in a micro and
so, by default, GPIO Library is added by the compiler whenever we start a new project. The compiler’s
help documentation on GPIO Library is as good as the datasheet itself. All we need is the pin map as
shown below. The pin names and numbers are also inscribed in the board.
One personal experience I would like to share here. I have been working with STM32 ARMs for quite
a long time and I love STM32 family a lot. One key advantage with STM32s is the 16-bit port width. In
some applications, this feature helps a lot as we can use the GPIOs to form 16-bit parallel ports
intended for 6800 and 8080 interfaces. For example, in popular TFT display like ILI9325, it is required
to send/receive instructions to and from the display as 16-bit chunks. With only one C instruction, we
can complete one 16-bit transfer sequence unlike what we have been doing previously in 8-bit
systems, i.e. breaking a 16-bit value into two 8-bit values and then transferring it sequentially one
after another. This save time and requires less coding. It also makes the displays perform faster than
otherwise. However, for Tiva C ARMs and other advanced MCUs like the Atmel ATXMega series, this
same task needs to be done twice due to 8-bit port width. This isn’t a design flaw or some kind of
serious issue with these MCUs. Having things in 8-bit format isn’t bad, in fact it is often a time-saver
in another way. We can easily manipulate 8-bit stuffs more quickly and easily than higher bit order
stuffs. It is something we have inherited from our previous 8-bit MCU experiences.
When comparing Tiva C ARMs with respect to the popular STM32F1 series flagship ARMs, we need to
look at two things also. STM32F1 series can operate at a max clock speed of 72MHz while Tiva C ARMs
are slightly faster and can operate at a max clock speed of 80MHz. STM32F10x series is based on
Cortex M3 architecture while Tiva C ARMs are based on Cortex M4 architecture. This gives Tiva C ARMs
an edge over the STM32F1s. However, STM32F4 and STM32F7 series, which are also based on Cortex
M4, are even better. The point here is not the comparison of MCU families and choice but to show
that each family have their own disadvantages and advantages that we only need to consider when
things demand so. Every MCU is good and it depends how we are going to use it. Fortunately, MikroC
for ARM allows us to try out different ARM families with minimum efforts and low cost.
Basic Architecture
In the block diagarm shown below we can see the internal architecture of a Tiva C GPIO pin. The first
thing that will strike our mind is the number of registers attached to a pin and thereby the several
options a GPIO pin possesses.
As you can see there are too many things to configure and this is still not the complete register map.
However, for most applications we’ll need GPIODATA and GPIODIR registers. Their names suggest
their purpose. GPIODIR register sets GPIO direction – input/output. Clearing its bits set corresponding
GPIO pins as inputs and setting them set pins as outputs. GPIODATA register is used to write to/read
from GPIO pins. The rest of the registers are for external interrupts, triggers for DMA and ADC, and
for advanced customization of GPIO pins.
When coding in raw level, we also need to take care of enabling/disabling the clocks of GPIOs. This is
one by using the registers of system control block. Check General-Purpose Input/Output Run Mode
Clock Gating Control (RCGCGPIO) register.
MikroC GPIO Library
The following are the built-in GPIO library functions:
GPIO_Clk_Enable
GPIO_Clk_Disable
GPIO_Unlock
GPIO_Lock
GPIO_Config
GPIO_Set_Pin_Mode
GPIO_Digital_Input
GPIO_Digital_Output
GPIO_Analog_Input
GPIO_Alternate_Function_Enable
__mE_Lib_GPIO
Of these 11 functions, we’ll need only the following six for most applications:
The rest, except the __mE_Lib_GPIO are basically extensions of GPIO_Config function and so we won’t
be needing them. GPIO_Config function is more than enough.
We will understand well how these functions work when we check out the code examples. For now,
have look at the Launchpad boards schematic. Notice the red highlighted areas. We’ll be using these.
LM Flash Programmer
For physically programming the Tiva C Launchpad board, we’ll need a programmer or bootloader. I’m
not interested in the latter as all Tiva C Launchpad boards came with on board programmer hardware.
Bootloaders are also sometimes unreliable. All we need to use the programmer is a software. LM Flash
programmer is that software. It has a simple GUI interface and is quite similar to other program-
uploading software. It can be freely downloaded from http://www.ti.com/tool/lmflashprogrammer.
The only different thing one may encounter is the file format that can be uploaded. So far most of us
know that hex files are the ones that are finally uploaded to micros. However, there are other file
formats that can be uploaded too. LM Flash programmer requires a binary file instead of a hex file.
Uploading a hex file won’t simply work. Thus, we have to instruct our compiler to generate binary (bin)
files along with hex files. In MikroC IDE, press F12. Compiler options window will popup. Just tick the
checkbox as shown below. Now MikroC compiler will also generate binary images.
LM Flash programmer GUI looks like as shown below.
It is a very easy to use software. All we need to do is to select the proper Launchpad board and show
it the path to the binary file we wish to upload.
Code Examples
The very first project that we always do when we try out a new MCU is a simple LED blinking. This is
also my first example. In this example, I lit the on-board RGB LED in a colour mixer pattern. Here’s the
code:
void setup_GPIOs();
void main()
{
setup_GPIOs();
while(1)
{
GPIO_PORTF_DATA1_bit = 1;
GPIO_PORTF_DATA2_bit = 0;
GPIO_PORTF_DATA3_bit = 0;
delay_ms(900);
GPIO_PORTF_DATA1_bit = 1;
GPIO_PORTF_DATA2_bit = 1;
GPIO_PORTF_DATA3_bit = 0;
delay_ms(900);
GPIO_PORTF_DATA1_bit = 0;
GPIO_PORTF_DATA2_bit = 1;
GPIO_PORTF_DATA3_bit = 0;
delay_ms(900);
GPIO_PORTF_DATA1_bit = 0;
GPIO_PORTF_DATA2_bit = 1;
GPIO_PORTF_DATA3_bit = 1;
delay_ms(900);
GPIO_PORTF_DATA1_bit = 0;
GPIO_PORTF_DATA2_bit = 0;
GPIO_PORTF_DATA3_bit = 1;
delay_ms(900);
GPIO_PORTF_DATA1_bit = 1;
GPIO_PORTF_DATA2_bit = 0;
GPIO_PORTF_DATA3_bit = 1;
delay_ms(900);
GPIO_PORTF_DATA1_bit = 1;
GPIO_PORTF_DATA2_bit = 1;
GPIO_PORTF_DATA3_bit = 1;
delay_ms(900);
}
}
void setup_GPIOs()
{
delay_ms(2000);
GPIO_Clk_Enable(&GPIO_PORTF);
GPIO_Config(&GPIO_PORTF,
(_GPIO_PINMASK_1 | _GPIO_PINMASK_2 | _GPIO_PINMASK_3),
_GPIO_DIR_OUTPUT,
(_GPIO_CFG_DIGITAL_ENABLE | _GPIO_CFG_DRIVE_8mA),
_GPIO_PINCODE_NONE);
}
As you can see the GPIO_PORTF_DATA registers are being used to light the LEDs. However, we need to
configure these pins before we can use them. In the setup_GPIOs() function, pins 1 through 3 of GPIO
PORTF are configured as outputs. Firstly, we need to enable the clock for the GPIO that we are wanting
to use. Library function GPIO_Clk_Enable() does that. This is followed by actual GPIO setup. We need
PF1, PF2 and PF3 – the RGB LED pins, to be outputs. This is done by GPIO_Config() library function.
This function has several argument parameters that define GPIO properties. The first argument states
which GPIO port we are concerned with. The second masks the required pins. The third selects GPIO
direction. Finally, the last parameters further select what features we want from these pins. More
details on what each argument parameter means is detailed in the compiler’s help documentation.
Just be sure that you selected the right ARM family. In case of Tiva C MCUs we should check out which
functions and options are valid for Stellaris family. Stellaris is the predecessor of Tiva C micros.
If you remember my previous post on Tiva C clock system, you’ll remember that I stated that we’ll
reverify our clock settings in this post. In the example, we saw that at every 900ms the state of the
GPIOs changed in a grey-code-like fashion. To verify clock settings, I hooked up an oscilloscope with
one GPIO pin. Here’s the result:
The scope has been set to one second per division. The smaller square waveforms are a bit shorter
than one complete division. As can be seen, the timing is perfect and so is our clock setting.
This example demonstrates how to read GPIO pins. Again, refer to the Launchpad board schematic.
There are two user buttons on board. In this example, we’ll use both to change the RGB LED’s colour.
Apart from configuring the GPIOs, an extra step will be needed.
There are certain special pins in the TM4C123GH6PMI MCU that, by default, can’t be used like other
GPIOs. They are attached to important hardware like JTAG, NMI, etc. In terms of hardware, these pins
are locked from ordinary uses. Thus, we’ll be needing to unlock them if we are to use them as ordinary
GPIOs. The SW2 button on the Tiva C Launchpad board is shared with NMI and we can’t use it unless
we unlock it. This is the extra step.
Both SW1 and SW2 – momentary pushbuttons are attached directly with the PF4 and PF0 respectively.
There are no pull-up or pull-down resistor attached with them. Thus, we will be needing to enable
internal pull-up resistors. Here’s the code example.
void setup_GPIOs();
void main()
{
signed char s = 0;
setup_GPIOs();
while(1)
{
if(user_button1 == 0)
{
while(user_button1 == 0);
s++;
}
if(s > 7)
{
s = 0;
}
if(user_button2 == 0)
{
while(user_button2 == 0);
s--;
}
if(s < 0)
{
s = 7;
}
switch(s)
{
case 1:
{
red_LED = 1;
green_LED = 0;
blue_LED = 0;
break;
}
case 2:
{
red_LED = 0;
green_LED = 1;
blue_LED = 0;
break;
}
case 3:
{
red_LED = 0;
green_LED = 0;
blue_LED = 1;
break;
}
case 4:
{
red_LED = 1;
green_LED = 1;
blue_LED = 0;
break;
}
case 5:
{
red_LED = 1;
green_LED = 0;
blue_LED = 1;
break;
}
case 6:
{
red_LED = 0;
green_LED = 1;
blue_LED = 1;
break;
}
case 7:
{
red_LED = 0;
green_LED = 0;
blue_LED = 0;
break;
}
default:
{
red_LED = 1;
green_LED = 1;
blue_LED = 1;
break;
}
}
}
}
void setup_GPIOs()
{
delay_ms(2000);
GPIO_Clk_Enable(&GPIO_PORTF);
GPIO_Unlock(_GPIO_COMMIT_PIN_F0);
GPIO_Config(&GPIO_PORTF,
(_GPIO_PINMASK_0 | _GPIO_PINMASK_4),
_GPIO_DIR_INPUT,
(_GPIO_CFG_PULL_UP | _GPIO_CFG_DIGITAL_ENABLE),
_GPIO_PINCODE_NONE);
GPIO_Config(&GPIO_PORTF,
(_GPIO_PINMASK_1 | _GPIO_PINMASK_2 | _GPIO_PINMASK_3),
_GPIO_DIR_OUTPUT,
(_GPIO_CFG_DIGITAL_ENABLE | _GPIO_CFG_DRIVE_8mA),
_GPIO_PINCODE_NONE);
}
Happy coding.
*Some images are taken from TI’s websites and datasheet. Some are taken from MikroC for ARM compiler.