Modifications: Before Modification After Modification Set - Tris - B (0x7F) Pin - b7
Modifications: Before Modification After Modification Set - Tris - B (0x7F) Pin - b7
1. If we want to use pin RC4 instead of RB7 then, write down lines before and after modifications.
Before modification (line or keyword) After modification
set_tris_b(0x7F) set_tris_c(0xEF)
pin_b7 pin_c4
2. Use another equivalent functions that included in PIC C to perform the same operation with one
second delay, write down lines before and after modification, suppose that the LED is
connected to pin RD2.
3. Example One : Suppose now that there are 8 LEDs connected to port D, LED0 on
RD0, and LED1 on RD1 and so on…, as shown below. Write down a code that performs a nibble
(4 bit) toggling, if LED0 to LED3 are ON then LED4 to LED7 are OFF and vice versa, with 300
mS delay, note that all pins of port D must be output, and you must deal with 8 bits(one Byte) at
a time.
//#include..,FUSES…,USE….
// Note:
// output_X(BYTE) is a function that deals with the whole port.
// X : A,B,C,D, or E
Void main()
{
set_tris_d(0x00); //PORT D is output
while(1)
{
output_d(0x0F); //LEDs 0,1,2 and 3 are ON
delay_ms(300);
output_d(0xF0); //LEDs 4,5,6 and 7 are ON, others are OFF.
delay_ms(300); //300 mS delay time.
}
} //end main.
1
2. using I/O functions
Note: I will explain the new lines of code only, any lines explained previously will not be handled.
In the previous example we show how to use digital output functions in bit mode only, also in the
modification part for the same example we highlight some of byte mode topics. The next example
explains how to use simple digital I/O functions either in bit mode, or in byte mode.
From previous description port D must be output and port B must be input. Schematic is shown below.
Instead of using 8 LEDs and 8 switches individually, I decided to introduce new peripherals. LED BAR
is working as an array of sequential LEDs it can be seen in many devices as a graphical guide to
demonstrates a level of some factor such as volume (Sound level) in stereos or recorders, velocity in cars,
temperature and so on….., also DIPS (Dual In Package Switch) is an array of switches and same as a
switch it must be pulled-up or pulled-down, it has many advantages such that simplicity of wiring and
small size.
Pulled-up means that the output of the switch is normally high and it goes to low whenever it pressed;
reset button must be pulled-up. In pulled-up switches the resistors must be connected to VCC from one
side and to the target pin and button from the other side; as shown above, in pulled-down, just, replace
VCC with GND and vice-versa.
2
Fr picking out these elements from proteus, type the keywords that shown below.
void main()
{
//Define variables
char x;
set_tris_B(0xFF); //PORTB is input.
set_tris_D(0x00); //PORTD is output.
MODIFICATIONS :
1. Rewrite down the while(1)'s body using one line with full optimization i.e. less variables,
calculations, instructions….
output_D( input_B() ); //No needs for variables.
2. As you note the above code deals with ports atomically (as a whole), either output or input in byte
mode, write down the equivalent code of while(1)'s body using bit mode only.
3
3. Interfacing 7-segment display
Before programmable LCDs (Liquid Crystal Display), the dominant display device for any embedded
system was 7-segment display, and till now you can see it in many systems such that prayer clocks in
mosques, customers counter in restaurants, Microwaves timers, fridges temperature viewer, any MPUs or
MCUs kit and many other devices. 7-segment can be manufactured in many ways but the most popular is
LED approach. Engineers and developers prefer LED 7-segment for many reasons as:
Low cost.
Low power consumption.
Illuminating device.
7-segment display is simply 7 LEDs arranged somehow to demonstrate any BCD or even Hexadecimal
number, some of them comes with dot operator called decimal point (DP), and some are manufactured for
a specific system as clock organization. Figure below shows the general layout for any 7-segment display,
from this figure each letter (from a to g) demonstrates a LED so there are 7 main LEDs or segments;
indeed if we ignore the decimal point.
a
a
b f
c b
d g
e
f e c
g
d GND Dr. Mohanad
7-segment display comes in two main parts; common cathode or common anode, common cathode as
shown in above figure means that all LEDs are common in GND so to illuminate any segment (LED) we
must feed it with 5 volt, in contrast of common anode, all segments common in VCC; so for illumination
any segment 0 volt must be fed to this segment.
Now suppose that we need to display number 0 on a common cathode 7-seg then we must feed segments
a, b, c, d, e and f with Vcc and segment g with GND. A second example, if we want to display number 2
then a, b, g, e and d must be in a high voltage, c and f must be in low voltage.
In general, the main task for 7-seg is to display any hexadecimal number, and as we know hexadecimal
digits is 4 bit long so we must find a method to convert 4 bit digit to 7-seg code. Actually, there are two
solutions for this problem, the first by using a dedicated IC or by building your own circuitry I prefer to
call this a hardware solution (BCD to 7-SEG) decoder. The second is by using a piece of code that
stored in the same PIC to dothis job i.e. Convert from 4 bit digit to 7-seg code, I called this method a
software solution (look-up table).
Also along with 7-segment display (output device); I will introduce an input device named thumbwheel.
Thumbwheel is a BCD, octal or hexadecimal input device, it is somewhat user friendly, so user can
scroll down or up a wheel until reach the target number and the number's code will be generated
automatically and latched into output pins. Thumbwheels are mainly found in PLCs (Programmable
Logic Array).
4
DESCRIPTION: Read a BCD thumbwheel value that connected on <RA0:RA3> and display it on 7-
segment connected on <RD4:RD7>.
void main()
{
//Initialize SFRs (Special Function Registers)
set_tris_A(0x0F);
set_tris_D(0x0F);
output_bit(pin_d4, input(pin_A0));
output_bit(pin_d5, input(pin_A1));
output_bit(pin_d6, input(pin_A2));
output_bit(pin_d7, input(pin_A3));
}
}
As you expect from example description <RA0:RA3> must be input and <RD4:RD7> must be output, so
because of partitioning ports to input and output i.e. <RD0:RD3>, RA4 and RA5 are input pins, we
shouldn't write to port D as a whole, and if we reads port A we must ignore excessive bits or read it in
using bit mode functions. I used bit mode function especially for port D because it is divided into input
and output so if I used byte mode function say output_D(BCDnum) maybe I will fall in a trouble with the
devices that connected to other pins in port D; if they are exist.
NOWDT is a new fuse introduced in the previous code, WDT is stand for WatchDog Timer, it is an
internal timer if enabled it begins running with PIC's program until reach some defined value then a
software RESET signal will be generated forcing PIC to reset. In other words the watchdog timer is
designed to automatically reset the MCU on program malfunctions, by stopping or getting stuck in loop.
For example suppose that the value of WDT time-out is 18m second (Typical period) and in the worst
case the program needs 10m second to complete one turn of execution then if the execution time takes
more than this value means that the program is getting stuck or freeze, and as we mention after 18ms
5
WDT time-outs and the MCU forced to reset. In fuses line NOWDT means it is disabled, but writing
WDT only will enable it (by default it's enabled). Finally, if WDT is enabled then it should be regularly
reset at the beginning of while(1) loop; in PIC C restart_wdt() must be called.
The above example stand on hardware solution so 74LS48 IC is used to convert BCD code to 7-segment,
you can simply build your own combinational circuitry using simple digital logic design. For more details
of 74LS48 IC refer to its datasheet.
DESCRIPTION: Read the state of RB7 pin, if it's high then begin counting up on a 7-segment that
connected directly to portD, else count down. Counts must be in hexadecimal.
Schematic is shown below.
As you expect from example description port D is output and pin RB7 is input. I think that the program is
straightforward.
Referring to figure in page 14 , if we imagine that each segment corresponds to one bit, so segment a is
the least significant bit and g is the most, then to display number 0; <a,b,c,d,e,f> must be one and <g>
must be 0 this means 0111111 in binary and if we suppose that the 8th bit is don't care (set to 0) then this
binary numbers corresponds to 0x3F in hexadecimal; in the code it is considered the first element in an
array. In the same manner we can find any digit or symbol and include it into the same array, then we can
consider this array as a lookup table and map our target digit to it, for example the code of number 0 is
stored in location 0, number 1 in location 1 and so on…….
Note that the variable i of the for() loops is signed integer, the reason behind that is the condition of the
first for() loop (i >= 0), this condition remains true until i becomes a negative number, if we use an
unsigned integer then this condition will remain true forever i.e. i is always positive between 0 and 255.
Code is shown in the next page.
6
//Code begins here:
#include <16F877A.h>
#FUSES XT, NOWDT
#USE DELAY (CLOCK = 4000000)
set_tris_d(0);
set_tris_b(0x80); //RB7 is input.