The next example uses the output highQ and output_low() built-in functions in conjunction with the time delay function created in the previous example to toggle bit 0 of port B on and off.
The function dei() is called twice by main(). By wrriting the time delay as a function which can be called saves writing a delay statement twice in main().
////output_high(), output_low() demo
//dock oscillator internal, frequency //delay function
Next, vve will use the output_toggle() built-in function to accomplish the same thing as in the previous example.
A
I I I /output_toggle() demo
1111 uses time delay via function call
#include <16F818.h>
#use delay(internal=4mhz) del ()
{
delay_ms(500);
return;
main() {
output_b (0x00);
do {
output_toggle(PIN_B0);
del();
}
while (TRUE);
//clock oscillator internal, //delay function
//delay 500 milliseconds
//clear port B v
//toggle port B, bit 0 //call delay function
Cs8b
frequency
In the comparison example presented earlier, the if/else statement was used. In the following example, if will be used by itself.
if
or
if (condition)' statement;
if (condition) {
statementl;
statement2;
//single statement
//block of statements
statementn;
If the condition is true, statement(s) is executed.
If the condition is false, statement(s) is not executed.
In either case, execution continues with the line of code following statement(s).
Note that if(condition) and statement(s) are all part of the if statement.
The schematic for this experiment is:
+5VDC
An if statement is used by itself to check the position of a switch as the code is executed. If the switch is open, port A, pin 2 will be high and the condition for the if statement will evaluate to
"1" or TRUE. The statement following the if statement (really part of the if statement) will be executed and the LED at.port B, pin 2 will be on. If the switch is closed, the if statement will evaluate to "0" or FALSE. The statement following the if statement will not be executed and the LED at port B, pin 2 will be off.
////simple if demo
#include <16F818.h>
#fuses INTRC_IO main()
{ '•
output_b (0x00);
if (input(PIN_A2))
output b (ObOOOOO100 ) ; while (TRUE);
}
Cs9a
//clear port B //high?
//indicate switch open //circle, always
1) Power-up with switch closed on port A, pin 2 - observe LED.
2) Power-up with switch open on port A, pin 2 - observe LED.
3) or change switch position and reset.
The logical operators && (and), || (or), and ! (not) may be used as the basis of conditions in if and if/else conditional statements to direct program flow. The logical operators evaluate to TRUE or FALSE.
Each of them will be used in the following three examples.
The NOT logical operator negates the logic of the expression it operates on.
! expression will evaluate to FALSE if expression is TRUE.
////simple if demo /include <16F818.h>
#fuses INTRC_IO main()
{
output_b (0x00);
if (1 input(PIN_A2))
output_b (ObOOOOOlOO);
while (TRUE);
}
1) Power-up with switch open on port A, pin 2 - observe LED.
2) Power-up with switch closed on port A, pin 2 - observe LED.
3) or change switch position and reset.
The next two experiments require two switches.
//clear port B //low?
//indicate switch closed //circle, always
+5VDC
Cs9b
expression 1 && expression2 will evaluate to TRUE if both expression! and expression? are TRUE.
////simple && logical operator demo CslOa
#include <16F818.h>
#fuses INTRC_IO main()
{
output_b (0x00); //clear port B
if (input(PINAl) && input(PIN_A2)) .//both high?
< output_b (ObOOOOO100); //indicate both switches open
while (TRUE); //circle, always
}
1) Power-up with switches closed on port A, pin 1 and port A, pin 2.
2) Open switch on port A, pin 1 and reset. Observe LED.
3) Open switch on port A, pin 2 and reset. Observe LED:
Using the AND logical operator results in the following:
Using the OR logical operator results in the following:
expression 1 || expression2 will evaluate to TRUE if expression 1 or expression2 is TRUE.
////simple || logical operator demo Csl0b*~
#include <16F818.h>
#fuses INTRC_IO main()
{
output b (0x00); //clear port B
if (input(PINAl) || input(PIN_A2)) //high?
outputb (ObOOOOO100); //indicate one switch or other or both // open
while (TRUE); //circle, always
1) Power-up with switches closed on port A, pin 1 and port A, pin 2.
2) Open switch on port A, pin 1 and reset. Observe LED.
3) Open switch on port A, pin 2 and reset. Observe LED.
4) Reset and try other possibilities.
if/else statements may be cascaded to create a hierarchy for decision making.
if (conditionl) statement(s)1;
else if (condition2) statement(s)2;
else if (condition3) statement(s)3 ; else
statement(s)4 ;
//single statement or block
//single statement or block
//single statement or block
//single statement or block
For this sequence of if/else statements, only one will be executed and all that follow will be skipped over. The first if/else statement in the sequence that evaluates as TRUE will be execut
ed. If conditions 1, 2 and 3 all evaluate as FALSE, statement 4 will be executed.
To try this out, let's assume that we want to make one of three choices known to the microcon
troller by means of three switches. One, and only one switch may be open, indicating our choice. In response to a switch sensed as open (logic 1), a corresponding LED is turned on.
Looking at the schematic will make this clearer.
+5VDC
////simple if/else, else, else demo
#include <16F818.h>
#fuses INTRCIO main()
{
output_b (0x00);
if (input(PIN_A1))
output_b (ObOOOOOOlO) else if (input(PIN_A2))
output_b (ObOOOOOlOO) else if (input(PIN_A3))
output_b (ObOOOOlOOO) else
output_b (ObOOOlOOOO) while (TRUE);
Csll
//clear port B //high?
//indicate port A, pin 1 switch open //high?
//indicate port A, pin 2 switch open //high?
//indicate port A, pin 3 switch open
//indicate statement 4 //circle, always
1) Power-up with switches closed on port A, pins 1, 2, 3 - observe LEDs.
2) Change switch positions, reset - observe LEDs - test program operation.
Next we will try a program which uses bit manipulation and port bit-level built-in I/O functions.
The objective of the program is to look at an input port line and when it has a 1 on it, output a 1 on an output port line (if sense X, then turn on Y). Bit 3 of port A is arbitrarily chosen as the input line to be sensed and bit 2 of port B is arbitrarily chosen as the output line to be turned on.
The input line switch is closed before the program is run. The output port line is cleared to 0 at the beginning of the program so the LED will be off when the program is initiated.
+5VDC
////bit manipulation demo
whi^e (bit_test (porta, 3) ==0); is ah example of loop until something happens. When the switch is closed (initial condition), port A, pin 3 is connected to ground = logic 0. When the switch is opened, the pin is pulled up to +5 volts and the while condition changes causing pro
gram execution to move to the next statement. • , ..
1) Power-up with switch closed - observe port B, bit 2 LED.
2) Open switch - observe port B, bit 2 LED.
The next program makes port B, pin 2 the same as port A, bit 3 using a while loop. Notice the use of the input() function and the use of the output bit() function.
value = input (pin)
output_b (0x00); //clear port B, LEDs off
while (TRUE)
{output bit (PIN_B2, input(PIN_A3));} //make port B, pin 2 same as // port A, pin 3
//output bit (pin, value)
//value in this case is input(PIN_A3)
>
The next example program illustrates an application for bit manipulation in event counting using port bit-level built-in functions. Events represented by a series of switch closures can be
counted. The example program will count the number of times the bit 0 switch used in the pre
vious example is opened allowing the port A bit 0 input line to be pulled up to logic 1. The count is displayed in binary on LEDs connected to port B.
+5VDC
Start with switch closed, bit = 0.
Loop 'til bit = 1 which means a transition from 0 to 1 has occurred (leading edge of pulse detected).
Loop 'til bit = 0 which means a transition from 1 to 0 has occurred (trailing edge of pulse detected).
The pulse is counted when the trailing edge has been detected.
Leading Edge Trailing Edge
//declare counter, count in binary //clear port B
//display counter contents via LEDs }
while (TRUE);
/ Depending on the switch used, contact bounce may be experienced which will result in multiple pulses being generated and counted for one switch open/close cycle. Switch contacts sometimes bounce when the switch is actuated. This phenomenon is commonplace and can be compensat
ed for in software (not explored here). If you are getting too many counts per switch open/close cycle, contact bounce is the culprit.
A solution to this problem is to use the positive-going output of the pulser circuit described in Appendix A connected directly to pin RAO. It will output one clean pulse per push on the switch lever.