Download Simple Button Count

Survey
yes no Was this document useful for you?
   Thank you for your participation!

* Your assessment is very important for improving the workof artificial intelligence, which forms the content of this project

Document related concepts

Opto-isolator wikipedia , lookup

Rectiverter wikipedia , lookup

Immunity-aware programming wikipedia , lookup

Liquid-crystal display wikipedia , lookup

Transcript
Application Note
ANxxxx
Simple Button Count
By: Lynn Nguyen
Associated Project: Yes
Associated Part Family: CY8C24894
PSoC Designer Version: 4.4
Referenced Application Notes: None
Summary
This application note makes use of several onboard resources to display to the LCD the number of times a button is
pushed. It will explain the two types of drive modes that a pin can use, so that even if the developer does not have a
push button pin available, a mock pin may be created using wires and a breadboard.
Introduction
A very simple use and a common introduction project for microcontroller is to use the pushbuttons that are usually
provided on board and an LCD to display the number of times a button is pushed. This is simple because it requires
a minimal amount of hardware to implement and it familiarizes the user with the board. The board that we use for
this application note, CY3214 USBEval Board, comes with an LCD and 2 pushbuttons onboard. However, after
explaining the different drive modes that a pin may have, we will see how to implement a button using a breadboard
and wires.
Ports and Pins
What exactly is a pin? It’s been mentioned several
times already in this application note and if you are
new to embedded systems, this term is also new.
Basically, a pin is used to connect the microcontroller
to something else. This something else may be a
button, a switch, and LED… you get the picture. Pins
may be input or output pins but for the sake of
simplicity, we are only dealing with input pins in this
application note. An input pin is one in which an
outside resource is connected to the pin and the
microcontroller reads from that pin to get certain
information. A group of 8 pins is collectively called a
port. Recall also that a goup of 8 bits is called a byte.
Thus a port can read or write a byte at a time
depending on whether it is an input or an output port,
respectively.
On this PSoC microcontroller, you can see that we
have 6 ports, each with pins labeled 0-7. P0[1] is a
conventional short hand labeling of the pin, and you
can read this as, “Port 0, pin 1.” When reading a
value from a pin to know what the peripheral
attached to it is doing, we access the values through
the port registers PRT0DR, PRT1DR, PRT2DR,
PRT3DR, PRT4DR, or PRT5DR. You can think of
these registers as variables that store the value a
peripheral is sending. This value is sent as a voltage.
In code, when accessing the values from the port,
each port variable, PRTxDR (where x represents a
port number such as 0, 1, 2, 3, 4, or 5), is one byte.
One byte is 8 bits. Each bit in the byte corresponds to
a pin on a port. Just imagine the image in Figure 1 to
be a byte in memory, as laid out in Figure 2. So, if
you wanted to get the value of pin 3 on a port, you
would just mask the port variable to isolate the bit.
7
6
5
4
3
2
1
0
Figure 2 – Byte In Memory
Figure 1 – Port on Board
Page | 1
Pull-up and Pull-down
In PSoC Designer, there are 8 different ways to
connect to a pin. They are Strong, Strong Slow, High
Z, High Z Analog, Pull-up, Pull-down, Open Drain
High, and Open Drain Low. Each of these is used to
connect to different types of devices. In this project,
we are connecting buttons to the device and so we
will be using the Pull-up or Pull-down mode.
Technically these are considered pull-up or pulldown resistors. That is because, if you configure the
pin to pull-down, PSoC internally connects a resistor
from the pin to ground, or Vss. Externally, a
pushbutton is connected between the pin and a
positive supply voltage. This means, when the button
is not pushed, the pin will read 0 volts due to the
resistor. When the button is pushed, the voltage on
the pin will be at Vdd (positive supply voltage) and
you will read a 1 into the program. The opposite
applies to pull-up resistors. When the button is
pushed, the pin will read 0 and when the button is not
pushed, the pin will read 1. Basically, we will be able
to determine the state of the button (pushed/not
pushed) by reading from the pin.
Now we will set the User Module Paramters of the
LCD. This can be done on the left hand side in the
middle window. We want to set the value of the
LCDPort to Port_4.By connecting the LCD to the
port, we will be able to actually use this module in
our project. We will be using the LCD to display a
count of how many times a certain button is pushed.
An eccentricity of this board is that the LCD cannot
be connected to just any port. It must be connected to
Port_4 in order to display correctly.
Figure 5 – Configuring the LCD
Also, we will want to set the drive mode of the
button. We will first do pull-down mode. To do this,
we will set Port_3_7 or P3[7] to have Pull Down
mode. To do so, locate Port_3_7 in the window, and
go to the Drive column. There, click on the cell and a
drop down menu will appear. From the options,
choose Pull Down. Also, we’ll just rename it from
Port_3_7 to Button. This can be configured in the
window just under the window where we set the LCD
configuration.
Figure 3 – Pull-up and Pull-down Resistors
Set-up
Now we will begin creating the project. Open up
PSoC Designer and create a new project. We will be
using part CY8C24894-24LFXI and generating the
main file using C. Once that is done, we will be at the
user module selection screen of the Device Editor.
We will only be using one, the LCD. This can be
found under Misc Digital. Select this user module
and go to the Interconnect View.
Figure 6 – Setting P3[7]
This means that we will be connecting a pushbutton
to P3[7] and the program will read the value of the
button from that pin. Now, click the Generate
Application button and go on to the Application
Editor view of PSoC Designer.
Figure 4 – Selecting the LCD
Page | 2
Writing the Code
Open up main.c. This is where will we be writing the
source code necessary for the LCD to display the
count of a button push.

void main() {
1.
2.
unsigned char button_pushed;
int counter = 0;
3.
4.
5.
6.
7.
LCD_1_Start();
LCD_1_Position(0,0);
LCD_1_PrCString("Counter Program");
LCD_1_Position(1,11);
LCD_1_PrHexInt(counter);
8.
PRT3DR &= ~0x80;
9.
10.
while (1) {
int i, j;
11.
button_pushed = PRT3DR & 0x80;
12.
13.
14.
15.
if (button_pushed) {
++counter;
LCD_1_Position(1,11);
LCD_1_PrHexInt(counter);
16.
17.
for(i =0; i < 40; i++ ){
for(j =0; j < 250; j++ );
}




}
}
Figure 7 – Source Code
And that’s it! Of course, don’t worry, I’ll explain
what’s going on in the code. This is the main
function, and the only code that you will have to add
in order to get this program up and running.




Line-1 declares our button_pushed variable.
This variable will be used to read from P3[7]
and will be used to determine whether the
pin was pushed (if button_pushed == 1) or if
it was not pushed (if button_pushed == 0).
Line-2 declares our counter variable. This
variable will be used to keep track of how
many times the button connected to P3[7] is
pushed and the value of this variable will be
displayed on the LCD.
Line-3 is required because we need to
actually start the module before using any of
its APIs.
Line-4 and Line-6 tells us where we want
text on the LCD to be displayed. We can
think of the LCD as a grid of 2 rows where
(0,0) is the top left corner of the LCD. So,


the text that is first displayed on the screen
will begin on the top row.
Line-5 and Line-7 tell the LCD what to
print. Line-5 tells the LCD to print the string
“Counter Program” whereas Line-7 tells the
LCD to print the hex value of Counter.
Line-8 enables the pull-down resistor. You
may think we may have already enabled the
pull-down resistor when we set the drive
mode of P3[7] in the Device Editor, but
PSoC pins are different from other
microcontrollers in that they must also be
enabled in the code. The Device Editor only
sets the drive mode then when we have to
enable it in the code. To enable pull-down
resistor, we have to write 0 to the pin. This
is done using bitwise AND.
Line-9 tells the program to continuously poll
the pin for any changes in button state.
Line-10 is just variable declarations for a
nested loop used later on.
Line-11 is where we actually read a value
from the pin which will determine the button
state. We read the value by masking
PRT3DR to find the 7th bit. This 7th bit will
be 1 if the button is pushed and 0 if not
pushed because we are using a pull-down
resistor.
Line-12 to Line-15 tells the LCD to update
the button count on the screen if the button
was pushed. Also, the Counter variable
needs to be incremented because it is the
value of this variable that keeps track of the
button pushes.
Line-16 and Line-17 are used to create a
little delay when reading from the pin.
Unfortunately, in microcontrollers, when a
button is pushed, or when any metal surfaces
have contact with each other, a “bounce” is
created. It is when the metal contacts bounce
against each other before settling. So, the
program will consider these tiny extra
bounces as actual button pushes. To avoid
that, we set up a tiny delay in the loop so
that the program doesn’t take into account
these extra bounces.
Page | 3
Once you’ve added this code to the main method,
build the code (Build->Rebuild All) and program it
onto your board (Program->Program Part…)!
Remember to connect a wire from a button to P3[7].
Turn the microcontroller on and push away!
Figure 8 – Hardware Configuration
Some Modifications
Now that we know this works, let’s vary things a
little bit. Let’s pretend that none of the pushbuttons
on the board work (oh no!) but we still want to test
the code to be sure everything is okay. Well,
remember in the code that we saw that the button was
pushed if button_pushed == 1. We can replicate this
using the breadboard and power supply. If the button
read 1, that meant that the voltage was at V dd. So if
we set up the connections like in the following figure,
we can get the jumper wire to act like a button!
Figure 9 – Mock Pull Down Button
void main() {
1.
2.
unsigned char button_pushed;
int counter = 0;
3.
4.
5.
6.
7.
LCD_1_Start();
LCD_1_Position(0,0);
LCD_1_PrCString("Counter Program");
LCD_1_Position(1,11);
LCD_1_PrHexInt(counter);
8.
PRT3DR |= 0x80;
9.
10.
while (1) {
int i, j;
11.
button_pushed = PRT3DR ^ 0x80;
12.
13.
14.
15.
if (button_pushed) {
++counter;
LCD_1_Position(1,11);
LCD_1_PrHexInt(counter);
16.
17.
for(i =0; i < 40; i++ ){
for(j =0; j < 250; j++ );
}
}
}
Figure 10 – Pull Up Code
Notice that the only changes we made to the original
code were to Line-8 and Line-11.
 In Line-8, by doing the bitwise OR
operation, we are writing a 1 to the
register—thus enabling the pull up resistor
on Port_3_7. Previously, we had written a 0
to P3[7] to enable pull down.
 Line-11 is still reading from the pin. But
because we are using a pull up resistor, the
pin will now read 0 if the button is pushed.
To keep with the logic of “button_pushed
== 1” (where 1 is logically equivalent to
True) then we do a XOR to flip the bit. Thus
if we read 0 from the pin, that means that the
button is pushed, so by XOR’ing the bit, we
will now have a 1 for button_pushed.
Also, since we spent so much time learning about
pull-up and pull-down resistors, let’s configure the
project to read from the pin when it is using the pullup mode instead.
Using Pull-up Mode
Go to the Device Editor view of PSoC Designer and
configure P3[7] (which we had renamed to Button) to
use Pull Up mode. Click the Generate Application
button again and go back to the Application Editor
view. We will have to make some modifications to
the source code to enable the pin to read pull up.
Page | 4
Once that is done, rebuild it and program it onto
microcontroller. Unfortunately, if we use this
method, the program will not work if we connect the
pushbuttons provided onboard to P3[7]. I can only
assume that Cypress has the 2 buttons (S1 and S2)
automatically tied to Vdd. However, we can test this
code by using the mock buttons that we implemented
previously with jumper wires. This time, we want to
connect the wires to the negative supply source (on
J11) as shown below.
Figure 11 – Mock Pull Up Button
Challenge Yourself
Now try wiring in another button that will decrement
the button push count! Or try to implement code
where holding down the button for a long period of
time is equivalent to one button push instead of
multiple little ones.
Conclusion
There are many different ways in which you can use
the resources and settings provided on a PSoC
microcontroller. The easiest way to think about pull
up vs. pull down is to think that the resistor creates a
default value for a circuit. In this case, having a pull
up resistor meant that when the button was in its
default state (not pushed), then the program would
read a 1 (high). Moreover, a pull down resistor meant
that when the button was not pushed, the value read
from the register was 0 (low).
Page | 5