chapter 5 - pic programming in c
DESCRIPTION
PIC programming in embeddedTRANSCRIPT
Chapter 5
PIC PROGRAMMING IN C
Chapter Objective
• Understand C programming for embedded
system
• Understand input output (I/O) programming in C
• Understand programming timer
Why program the PIC18 in C
• Compilers produce hex file downloaded into the
ROM of the microcontroller
• The size of the hex file is the concern because
of:
• limited size of on-chip ROM
• limited code space for PIC18 (2Mbyte)
C Vs. Assembly
C Language Assembly Language
Easy to write the program Harder to write the program
Less time consuming Time consuming
Easier to modified and update Tedious to modified
Code available in function library Must know /write every instruction
Code is portable to other
microcontroller ( less modification)Not portable to other microcontroller
Bigger HEX file Smaller HEX file
The structure of C program for PIC18
Functions
• void main (void):
It represents that "main" function does not return any
value as well as does not accept any
parameter/arguments.
In old compilers it was mandate to specify void in
parenthesis in case main is not going to accept any
parameters. but these days you may need to use like
below only:
void main()
• its just simply means that a main function
has no any return value or any passed
variable
• if we write only main in our program then
the compiler has show some error
because it could not find any return type of
the main function
C data types for the PIC18
Data Type Bit Size Data Range
unsigned char 8-bit 0 to 255
char 8-bit -128 to +127
unsigned int 16-bit 0 to 65535
int 16-bit -32768 to
+32767
*PIC18 has a limited
number of registers and
data RAM locations
Example 1 (unsigned numbers)
#include<htc.h>
void main()
{
unsigned int z;
TRISB = 0;
for (z=0; z<=50000; z++)
{
PORTB = 0x55;
PORTB = 0xAA;
}
while(1);
}
Toogle all bits at
PortB for 50,000
times
Example 2
#include<htc.h>
void main()
{
unsigned short long z;
unsigned int x;
TRISB = 0;
for (z=0; z<=100000; z++)
{
PORTB = 0x55;
PORTB = 0xAA;
}
while(1); //stay here forever
}
Toogle all bits at
PortB for 100,000
times
Time delay
• Two way of creating a time delay in PIC18;
i. using a simple loop program
ii.using PIC18 timer function (discuss later)
Time delay using loop program
• Two factor that effect the delay accuracy:
– Crystal frequency
– The compiler used.
# Assembly lang. can control exact instruction
in delay subroutine.
# In C programs, different compilers produces
different-size HEX code.
• instructions are implemented in one
instruction cycle(except branching, they
are implemented in two instruction cycle).
• We can calculate instruction cycle by
dividing oscillator frequency by 4.
Example
• Let's say we have 4MHz oscillator
connected to our microcontroller. Then,
one instruction cycle will take
4/4Mhz = 1us(micro second).
• Write a C18 program to toggle all bits of
Port B ports continuously with a 250 ms
delay. Assume that the system is
PIC184550 with XTAL=10MHz
Example
Answer#include<htc.h>
__CONFIG(0x3F3A);
void delay(unsigned int);
void main(void)
{
TRISB=0;
PORTB=0;
while(1)
{
PORTB = 0X55;
delay(250);
PORTB = 0xAA;
delay(250);
}
}
void delay(unsigned int tempoh)
{
unsigned int i; unsigned char j;
for (i=0;i<tempoh;i++)
for(j=0;j<165;j++);
}
Exercise
• Assume that a system is PIC18F4550 with
XTAL=20MHz.
• The I/O port preserve be access using 2 method:
a. byte addressable , or
b. bit addressable
Ports PORTA-PORTD are byte accessible
Input and Output (I/O)
Programming in C
Write a C program to get a byte of data
from PORTB, wait 0.5 second, and then
send it to PORTC. Assume XTAL = 4MHz.
Example ( BYTE ADDRESSABLE )
#include<htc.h>
int a;
void main()
{
TRISB = 0xFF;
PORTB = 0x00;
TRISC=0x00;
while(1)
{
a = PORTB;
PORTC = a;
}
}
Answer
Write a C program to get a byte from
PORTC. If it is less than 100, send it to
PORTB; otherwise, send it to PORTD
Example ( BYTE ADDRESSABLE )
#include<htc.h>
void main(void)
{
unsigned char z;
TRISC = 0xFF;
TRISB = 0x00;
TRISD = 0x00;;
while(1)
{
z = PORTC;
if (z < 100)
PORTB = z;
else
PORTD = z;
}
}
Answer
Bit-addressable I/O
programming
• The l/O ports of PIC 18 are bit-addressable. We can
access a single bit without disturbing the rest of the port.
We use PORTxbits. Rxy to access a single bit of Portx,
where x is the port A, B, C, or D, and y is the bit (0-7)
of that port.
• For example, PORTBbits.RB7 indicates PORTB.7. We
access the TRISx registers in the same way where
TRISBbits.TRISB7 indicates the D7 of the TRISB.
Example ( BiT ADDRESSABLE )
Logic Operation and data
conversion in C
• One of the most important and powerful features of the C
language is its ability to perform bit manipulation.
• While every C programmer is familiar with the logical
operators AND (&&), OR (II), and NOT (!), many C
programmers are less familiar with the bitwise operators
AND (&), OR (I), EX-OR (^), inverter (~), shift right
(>>), and shift left(<<)).
Logic Operation and data conversion in C
• These bit-wise operators are widely used
in software engineering for embedded
systems and control; consequently, their
understanding and mastery are critical in
microprocessor-based system design and
interfacing.
Operation Symbol Example
Equal to == if(a == 0) b=b+5;
Not equal to != if(a != 1) b=b+4;
Greater than > if(a > 2) b=b+3;
Less than < if(a < 3) b=b+2;
Greater than or equal to >= if(a >= 4) b=b+1;
Less than or equal to <= if(a <= 5) b=b+0;
Logic Operation and data conversion in C
OPERATION OPERATOR DESCRIPTION SOURCE CODE EXAMPLE RESULT
Increment ++ Add one to integer result = num1++; 0000 0000 0000 00001
Decrement -- Subtract one from integer result = num1--; 1111 1111 1111 1110
Complement ~ Invert all bits of integer result = ~num1; 0000 0000 1111 1111
Arithmetic Operation
Add + Integer or Float result = num1 + num2; 0000 1010
+ 0000 0011
0000 1101
Subtract - Integer or Float result = num1 - num2; 0000 1010
- 0000 0011
0000 0111
Multiply * Integer or Float result = num1 * num2; 0000 1010
*0000 0011
0001 1110
Divide / Integer or Float result = num1 / num2; 0000 1100
/ 0000 0011
0000 0100
Logical Operation
Logical AND & Integer Bitwise result = num1 & num2; 1001 0011
& 0111 0001 0001 0001
Logical OR | Integer Bitwise result = num1 | num2; 1001 0011
|0111 0001
1111 0011
Logical OR ^ Integer Bitwise result = num1 ^ num2; 1001 0011
^ 0111 0001
1110 0010
Data conversion in C
• Recall that BCD numbers were discussed earlier. As
stated there, many newer microcontrollers have a real-
time clock (RTC) where the time and date are kept even
when the power is off.
• Very often the RTC provides the time and date in packed
BCD. To display them, however, it must convert them to
ASCII. In this section we show the application of logic
and rotate instructions in the conversion of BCD and
ASCII.
ASCII numbers
On ASCII keyboards, when the key "0" is activated, "0 II
0000" (30H) is provided to the computer. Similarly, 31H
(0110001) is provided for the key "1", and so on.
• The PICI8 has two to five timers depending on the family
member. They are referred to as Timers 0, I, 2, 3, and 4.
They can be used either as timers to generate a time
delay or as counters to count events happening outside
the microcontroller.
Programming Timer
• Every timer needs a clock pulse to tick. The clock source
can be internal or external. If we use the internal clock
source, then 1/4th of the frequency of the crystal
oscillator on the OSCI and OSC2 pins (Fosc/4) is fed
into the timer.
• Therefore, it is used for time delay generation and for
that reason is called a timer. By choosing the external
clock option, we feed pulses through one of the PICI8‘s
pins: this is called a counter.
Programming Timer
• PIC18 has two to five timers
– Depending on the family number
• These timers can be used as
– Timers to generate a time delay
– Counters to count events happening outside
the uC
Programming timers 0 and 1
• Every timer needs a clock pulse to tick
• Clock source can be
– Internal 1/4th of the frequency of the crystal oscillator
on OSC1 and OSC2 pins (Fosc/4) is fed into timer
– External: pulses are fed through one of the PIC18’s pins
Counter
• Timers are 16-bit wide
– Can be accessed as two separate reg. (TMRxL & TMRxH)
– Each timer has TCON (timer Control) reg.
T0CON (Timer0 control) register
• Each timer has a control register, called TCON, to set
the various timer operation modes. T0CON is an 8-bit
register used for control of Timer0.
Example
TMR0IF flag bit
• Notice that the TMR0IF bit (Timer0 interrupt flag) is part
of the INTCON (interrupt control) register.
• when the timer reaches its maximum value of FFFFH, it
rolls over to 0000, and TMR0IF is set to I.
16-bit timer programming
The following are the characteristics and operations of 16-bit
mode:
1. It is a 16-bit timer; therefore, it allows values of 0000 to
FFFFH to be loaded into the registers TMR0H and TMR0L.
2. After TMR0H and TMR0L are loaded with a 16-bit initial value,
the timer must be started. This is done by "BSF T0CON,
TMR0ON" for Timer0.
3. After the timer is started, it starts to count up. It counts up until
it reaches its limit of FFFFH. When it rolls over from FFFFH to
0000, it sets HIGH a flag bit called TMR0IF (timer interrupt
flag, which is part of the INTCON register). This timer flag
can be monitored. When this timer flag is raised, one option
would be to stop the timer.
4. After the timer reaches its limit and rolls over, in order to
repeat the process, the registers TMR0H and TMR0L
must be reloaded with the original value, and the
TMR0IF flag must be reset to 0 for the next round.
Steps to program Timer0 in 16-bit mode
To generate a time delay using the Timer0 mode 16, the
following steps are taken:
1. Load the value into the T0CON register indicating which mode
(8-bit or 16- bit) is to be used and the selected prescaler
option.
2. Load register TMR0H followed by register TMR0L with initial
count values.
3. Start the timer with the instruction "BSF T0CON, TMR0ON".
4. Keep monitoring the timer flag (TMR0IF) to see if it is raised.
Get out of the loop when TMR0IF becomes high.
5. Stop the timer with the instruction "BCF T0CON, TMR0ON".
6. Clear the TMR0IF flag for the next round.
7. Go back to Step 2 to load TMR0H and TMR0L again.
COUNTER PROGRAMMING
• We used the timers of the PICI8 to generate time delays.
These timers can also be used as counters to count
events happening outside the PIC 18.
• When it is used as a counter, however, it is a pulse
outside the PIC 18 that increments the TH, TL registers.
In counter mode, notice that registers such as T0CON,
TMR0H, and TMR0L are the same as for the timer
discussed in the last section; they even have the same
names.
T0CS bit in T0CON register
• Recall from the last section that the T0CS bit (Timer0 clock
source) in the T0CON register decides the source of the clock
for the timer. If T0CS = 0, the timer gets pulses from the
crystal oscillator connected to the OSC I and OSC2 pins
(Fosc/4).
• In contrast, when T0CS = I, the timer is used as a counter and
gets its pulses from outside the PIC 18. Therefore, when
T0CS = I, the counter counts up as pulses are fed from pin
RA4 (PORTA.4). The pin is called T0CKI (Timer0 clock input).
Notice that the pin belongs to Port A.
• In the case of Timer0, when T0CS = I, pin RA4 (PORTA.4)
provides the clock pulse and the counter counts up for each
clock pulse coming from that pin. Similarly, for Timer I, when
TMRI CS = I, each clock pulse coming in from pin RC0
(PORTC.0) makes the counter count up.