Sunteți pe pagina 1din 30

Chapter 9 Introduction to PIC18 C

Programming

Why program the PIC18 in C?


C programming is easier and less time
consuming
C is easier to modify and update
Existing libraries available (e.g., delays)
C code is portable to other
microcontroller with little or no
modification
We will be using Microchip C18 compiler
2

Example Delay Program in Lab 1

Memory Usage Gauge

Same Program Coded in C

Memory Usage Gauge

Disadvantages of C
The code produced is less space-efficient
and runs more slowly than native assembly
code.
A compiler is much more expensive than an
assembler.
Image courtesy of S.
Katzen, The essential
PIC18 Microcontroller,
Springer

Data Types, Sizes and Ranges

Data Type
unsigned char
(signed) char
unsigned int
(signed) int

Size in Bits
8
8
16
16

Data Range
0 to 255
-128 to +127
0 to 65535
-32768 to 32767

Data Types, Sizes and Ranges


char
Because PIC18 is an 8-bit microcontroller,
char data type is most commonly used.
C compliers use the signed type as default
unless the qualifier unsigned is put in front.
int
int variables are stored in two 8-bit
registers.
Dont use int unless we have to. If one 8bit register is enough to store a variable, we
dont want to use 2 registers.
7

Data Memory Allocation in C18


Declared two variables: i, mynum.

Data Memory Allocation in C18


i = d10000 = 0x2710 (int: 2 bytes)
i located in data memory address 08A:08B.
08B and 08A store the high and low bytes
respectively.
The array mynum is stored in 08C:08F
Here, the complier controls where to put
the variables.

Data Memory allocation in C18


A programmer can control where to put
variables.
Use
#pragma idata <variable> = <RAM addr>

before the declaration.


e.g.,
#pragma idata i = 0x150
unsigned int i = 10000;
10

Data Memory allocation in C18

11

Program Memory Allocation in C18


To write fixed (constant) data to
program memory, the keyword rom is
used:
rom
rom

const
const

int i = 10000;
char mynum[] = 0123456789

12

Program Memory Allocation in C18

i
mynum

13

Putting Data in Specific data memory


Address
To place data in a specific program
memory address, use:
#pragma romdata mydata = 0x200
rom const char mydata[] = 0123456789

14

Putting Data in Specific data memory


Address

15

Writing code in a specific program memory


address
To place code in a specific program
memory address, use:
#pragma code Delay = 0x300
void Delay(int cnt)
{ ....
}
16

Writing code in a specific program memory


address

17

Well, why do I want to write code in a


specific program memory location?
Remember this?
We have used polling to create a square
wave of 50% duty cycle on PORTB<5>
bit.
In this example, we implement the same
thing using interrupt with interrupt
priorities disabled (IPEN = 0).

18

Interrupt Example Revisited

Main:

ORG 0x0000
goto Main
ORG 0x0008 // High priority interrupt starts at 0x08
goto T0_ISR
ORG 0x0100
bcf TRISB, 5
bcf PORTB, 5
movlw 0x08; Timer0, 16-bit, no prescale, internal ck
movwf T0CON
movlw 0xFF
movwf TMR0H
movlw 0xF2
movwf TMR0L; load FFF2 to TMR0
bcf
RCON, IPEN; Disable Interrupt Priorities
bcf
INTCON, TMR0IF; Clear interrupt flag bit
bsf
INTCON, TMR0IE; enable Timer0 interrupt
bsf
INTCON, GIE; enable global interrupt
bsf
T0CON, TMR0ON; start Timer0
19
bra
$

Interrupt Example Revisited


T0_ISR:

EXIT:

ORG 0X0200
btfss INTCON, TMR0IF
bra
EXIT
bcf
INTCON, TMR0IF
btg
PORTB, 5; toggle PortB.5 to create sq. wave
movlw 0xFF
movwf TMR0H
movlw 0xF2
movwf TMR0L; Reinitialize TMR0 to FFF2
retfie
END

20

We have to write ISR starting 0x08. How


did we do it in C?
#include <p18F4520.h>
#pragma config OSC = HS, WDT = OFF, LVP = OFF
void timer_isr_internal(void);
//----------------------------------------------------------------------------

#pragma code timer_isr = 0x08 // Store the below code at address 0x08
void timer_isr(void)
{
_asm GOTO timer_isr_internal _endasm
}
//---------------------------------------------------------------------------#pragma code
void main (void)
{
TRISBbits.RB5 = 0;
//set RB5 output
PORTBbits.RB5 = 0;

T0CON = 0x08;
TMR0H = 0xFF;
TMR0L = 0xF2;

// Timer0, 16-bit, no prescale, internal ck

RCONbits.IPEN = 0;
INTCONbits.TMR0IF = 0;
INTCONbits.TMR0IE = 1;
INTCONbits.GIE = 1;
T0CONbits.TMR0ON = 1;
while(1);

//disable priority levels

21

We have to write ISR starting 0x08.


How did we do it in C?
#pragma interrupt timer_isr_internal
void timer_isr_internal (void)
{
if (INTCONbits.TMR0IF)
{
INTCONbits.TMR0IF=0;
PORTBbits.RB5 = ~PORTBbits.RB5;//toggle
PortB.5 to create sq. wave
TMR0H = 0xFF;
TMR0L = 0xF2;
}
}
22

Use of C to generate time delay


Using assembly language, we can
control the exact instructions executed
in a time delay subroutine and thus be
able to control the exact time delay.
DelayLoop: decfsz
DELAY_L
bra DelayLoop
decfsz DELAY_H
bra DelayLoop
23

Use of C to generate time delay


C compliers convert C statements to assembly
instructions.
Different compliers produce assembly code of
different length.
The actual time delay generated by the following
function depends on the complier used.
void Delay
{
unsigned int i;
for(i=0; i<10000; i++);
return;
}

Need to measure the exact time delay using


MPLAB StopWatch tool.

24

I/O Programming in C
Recall: I/O Programming involves
PORTx and TRISx registers.
Byte I/O Programming: Change the
whole byte stored in PORTx or TRISx.
e.g., PORTB = 0x18
TRISB = 0X20

25

I/O Programming in C

26

I/O Programming in C
Bit-addressable I/O programming: Change
a single bit without disturbing the rest of
the PORTx or TRISx registers.
PORTBbits.RB7 = 7th bit of PORTB
TRISBbits.TRISB7 = 7th bit of TRISB
Same function as bcf or bsf in assembly
language
e.g., bcf PORTB, 5 is expressed as
PORTBbits.RB5 = 0 in C
e.g., bcf TRISB, 5 is expressed as
TRISBbits.TRISB5 = 0 in C
27

Logic Operations in C
Bit-wise operators:
1.AND (&)
Extract lower nibble: PORTB & 0x0F

2.OR (|)
e.g., SPI_VALUE = 0x30 | SPI_HI

3.Exclusive OR (^): 1^1 = 0


4.Inverter (~)
e.g., Toggle PORTB: PORTB = ~PORTB
28

Simplicity of C: An Example
Lab 2 Task 2
Task: Display your group number of the 4digit 7-segment LED.
Remember how much
work you have done to
make it work in
assembly?
Very simple coding in C.
29

Simplicity of C: An Example
void Delay(unsigned int cnt)
{
while(cnt != 0) {
cnt--;
}
}
void main(void)
{
unsigned char Segment[10] = {0x3f, 0x06, 0x5b, 0x4f, 0x66, 0x6d, 0x7d, 0x07,
0x7f, 0x6f};
unsigned char DispBuf[4] = {0, 1, 2, 3};
unsigned char i;
ADCON1 = 0x0f;
TRISB = 0x00000000;
TRISD = 0b00000000;

//Set All Port Digit I/O


//Set PortB Output
//Set PortD Output

while(1) {
for(i=0; i<=3; i++) {
PORTD = 0;
PORTB = i;
PORTD = Segment[DispBuf[i]];
Delay(400);
}
}
}

30

S-ar putea să vă placă și