Tutorial 2 : Using Switch to Blink LED
Overview
This tutorial is a basic tutorial through which I wish to teach you how to take in input using the Stellaris LaunchPad. For this tutorial, I will be using the one of the two on board switches named SW2 as the input. A switch is something basic and anyone, even someone without any prior knowledge about a micro controller and stuffs will surely understand. If you think so, it is time for you seriously consider what you have actually understood about a button switch. Actually, in real life, the switch is not ideal and is prone to many erroneous phenomena which is generally called as noise. Even though it is not proper to call it as a noise, lets for the time being term it as a noise.
Consider a button switch which is connected to your Stellaris LaunchPad. Now Lets say you have connected the other end of the button switch to VCC. Now, for sure, when you press the button a HIGH will be read as the input as it will short the path. What I am interested is actually what happens when I release the button. Will it go back to LOW?? Obviously yes huh? Where else is it supposed to go otherwise huh?
But the answer to the question is that the signal won't go back to LOW but it will be disturbed by "electromagnetic noise" and therefore it may switch between HIGH and LOW in a random fashion. Now Inorder to avoid this, in this case, we should use a pull down resistor. The Stellaris LaunchPad actually has it as an internal feature. I will talk about in detail later.
So i would strongly suggest that you go through some reference about the pull down resistors, pull up resistors, button debouncing etc. The other prerequisite for this tutorial is the Tutorial 1 about blinking an LED.
Consider a button switch which is connected to your Stellaris LaunchPad. Now Lets say you have connected the other end of the button switch to VCC. Now, for sure, when you press the button a HIGH will be read as the input as it will short the path. What I am interested is actually what happens when I release the button. Will it go back to LOW?? Obviously yes huh? Where else is it supposed to go otherwise huh?
But the answer to the question is that the signal won't go back to LOW but it will be disturbed by "electromagnetic noise" and therefore it may switch between HIGH and LOW in a random fashion. Now Inorder to avoid this, in this case, we should use a pull down resistor. The Stellaris LaunchPad actually has it as an internal feature. I will talk about in detail later.
So i would strongly suggest that you go through some reference about the pull down resistors, pull up resistors, button debouncing etc. The other prerequisite for this tutorial is the Tutorial 1 about blinking an LED.
/* * Stellaris LAUNCHPAD LM4F120H5QR * C++ code to use SW_1 button to turn on an RED LED(PORTF 1) */ #include <inc/hw_types.h> #include <inc/hw_memmap.h> #include <driverlib/gpio.h> #include <driverlib/sysctl.h> int main(void) { /* * The System clock is run using a 16 Mhz crystal connected to the main oscillator pins of the microcontroller * This generates a internal clock signal of 400 Mhz using the PLL * The signal is prescaled by the system by 2 * Now we are defining a prescale of 5 in addition to make the clock frequency 40MHz * The system clock frequency must be less than or equal to 80MHz */ SysCtlClockSet(SYSCTL_SYSDIV_5|SYSCTL_USE_PLL|SYSCTL_XTAL_16MHZ|SYSCTL_OSC_MAIN); /* * Peripherals are enabled with this function. * At power-up, all peripherals are disabled. * System Clock to the peripheral must be enabled in order to operate or respond to register reads/writes. */ SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOF); // Set PF4(SW_1) as input GPIOPinTypeGPIOInput(GPIO_PORTF_BASE, GPIO_PIN_4); /* * As it is a switch, we should use a pull up resistor. * Stellaris can be configured with various pull up/down resistors based on the drive strength(current) specified. * Refer to the Stellaris API page number 124 for more configurations * Link: www.ti.com/lit/ug/spmu019p/spmu019p.pdf */ GPIOPadConfigSet(GPIO_PORTF_BASE, GPIO_PIN_4, GPIO_STRENGTH_4MA, GPIO_PIN_TYPE_STD_WPU); //Set PF1(RED LED) as output GPIOPinTypeGPIOOutput(GPIO_PORTF_BASE, GPIO_PIN_1); //Turn of the LED GPIOPinWrite(GPIO_PORTF_BASE, GPIO_PIN_1, 0); while(1) { //Check whether the button is pressed. if(!GPIOPinRead(GPIO_PORTF_BASE, GPIO_PIN_4)) //Set PF1 as high. 2 ~ 0b00000010-->mask PF1 GPIOPinWrite(GPIO_PORTF_BASE, GPIO_PIN_1, 2); else GPIOPinWrite(GPIO_PORTF_BASE, GPIO_PIN_1, 0); } }
The code was provided before hand so that you will actually get a better understanding of the code. Otherwise it would be really boring and most of you will find it irresistible to wait for the final code.
Step 1 : Setup up clock and Enable Clock
SysCtlClockSet(SYSCTL_SYSDIV_5|SYSCTL_USE_PLL|SYSCTL_XTAL_16MHZ|SYSCTL_OSC_MAIN); SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOF);
The button switch SW2 on your Stellaris LaunchPad is actually connected to the PF4 of the LM4F120H5QR. So obviously, you will have too use the PORTF. As explained in the last tutorial, the SysCtlClockSet is used to set up the clock, whereas the SysCtlPeripheralEnable is used to enable the System Clock supply to the GPIOF which we would actually require to use our switch which is connected to PF4. I wont be explaining about the code snippets that we have already taught in the earlier tutorials again.
Step 2 : Setting Up Input
GPIOPinTypeGPIOInput(GPIO_PORTF_BASE, GPIO_PIN_4);
Once the system clock to the particular port has been enabled, the next thing that we have to do is to make the particular pin on the micro controller an input pin so that we can use it to interface our button. So this line of code will help us get it done elegantly. I believe that the function is self explanatory.
Step 3 : Enabling Pull Up Resistor
GPIOPadConfigSet(GPIO_PORTF_BASE, GPIO_PIN_4, GPIO_STRENGTH_4MA, GPIO_PIN_TYPE_STD_WPU);
The GPIOPadConfigSet function is actually used to the maximum current that is supposed to flow through the input pin and whether a pull up is required or not. You may wonder why i am using a pull up ressistor and not a pull down ressistor. Actually if you go through the schematic of the LaunchPad board, you will find that the Switch is actually connected to ground and not VCC. so therefore, when the button is released, i want to ensure that the state is HIGH and that is the reason why we go for a pull up resistor. More specifically standard weak pull up. There is another mode called opendrain pull up also available. The push-pull output actually uses two transistors. Each will be on to drive the output to the appropriate level: the top transistor will be on when the output has to be driven high and the bottom transistor will turn on when the output has to go low.
The open-drain output lacks the top transistor. When the output has to go high you simply turn off the bottom transistor, but the line is now pulled high only by the pullup resistor.Your micro allows you to select between the two types, which means that by setting some bits in some register you actually enable/ disable the top transistor and enable/disable the pullup (if internal, otherwise you just disable the top transistor and have to use an external pullup).
The advantage of the push-pull output is the higher speed, because the line is driven both ways. With the pullup the line can only rise as fast as the RC time constant allows. The R is the pullup, the C is the parasitic capacitance, including the pin capacitance and the board capacitance.The push-pull can typically source more current. With the open-drain the current is limited by the R and R cannot be made very small, because the lower transistor has to sink that current when the output is low; that means higher power consumption.However, the open-drain allows you to cshort several outputs together, with a common pullup. This is called an wired-OR connection. Now you can drive the output low with any of the IO pins. To drive it high all ouputs have to be high. This is advantageous in some situations, because it eliminates the external gates that would otherwise be required.
The open-drain output lacks the top transistor. When the output has to go high you simply turn off the bottom transistor, but the line is now pulled high only by the pullup resistor.Your micro allows you to select between the two types, which means that by setting some bits in some register you actually enable/ disable the top transistor and enable/disable the pullup (if internal, otherwise you just disable the top transistor and have to use an external pullup).
The advantage of the push-pull output is the higher speed, because the line is driven both ways. With the pullup the line can only rise as fast as the RC time constant allows. The R is the pullup, the C is the parasitic capacitance, including the pin capacitance and the board capacitance.The push-pull can typically source more current. With the open-drain the current is limited by the R and R cannot be made very small, because the lower transistor has to sink that current when the output is low; that means higher power consumption.However, the open-drain allows you to cshort several outputs together, with a common pullup. This is called an wired-OR connection. Now you can drive the output low with any of the IO pins. To drive it high all ouputs have to be high. This is advantageous in some situations, because it eliminates the external gates that would otherwise be required.
Step 4 : Reading From an Input Pin
if(!GPIOPinRead(GPIO_PORTF_BASE, GPIO_PIN_4))
This statement actually checks whether the Pin is pressed. I think that the function is self explanatory. Actually, we are checking whether it is low, because of the reason that the button is actually grounded at the other end and therefore, when pressed we are expecting a LOW signal.