Documente Academic
Documente Profesional
Documente Cultură
Mid‐Range PIC18
Data width 8 bits 8 bits
PIC18 Instruction word 14 bits 16 bits = 2 addressed bytes
Instructions 35 83
and Instruction address width
Program memory
13 bits
256 – 8192 words
21 bits
2 Kwords – 64 Kwords
ROM Flash Flash
Embedded Data memory (bytes)
Interrupts
56 – 368
int / ext
256 – 4K
int / ext
Pins 6 – 64 18 – 100
C Programming I/O pins 4 – 54 16 – 70
Stack 8 levels 31 levels
Timers 2 – 3 2 – 5
Bulk price $0.35 – $2.50 $1.20 ‐ $8.50
Embedded Systems — Hadassah College — Spring 2011 PIC18 Dr. Martin Land 1 Embedded Systems — Hadassah College — Spring 2011 PIC18 Dr. Martin Land 2
Migration to PIC18 Migration to PIC18
Data memory / registers Special Function Registers (SFR) — all in bank 15 (Fh)
Data address space Address
FFFh
Name
TOSU
Address
FDFh
Name
INDF2
(1)
Address
FBFh
Name
CCPR1H
Address
F9Fh
Name
IPR1
(1)
Embedded Systems — Hadassah College — Spring 2011 PIC18 Dr. Martin Land 3 Embedded Systems — Hadassah College — Spring 2011 PIC18 Dr. Martin Land 4
Migration to PIC18 Migration to PIC18
Status Register Indirect addressing
7 6 5 4 3 2 1 0 Indirect addressing
Name N OV Z DC C Program writes to File Select Registers (FSRs)
Writable Unimplemented in PIC18 R/W R/W R/W R/W R/W Instructions can increment/decrement FSR values
Reset value 0 0 0 1 1 x x x INDF virtual registers track contents of FSR registers
Migration to PIC18 Migration to PIC18
Indirect addressing with automatic increment/decrement Program memory migration
Similar to INDFn Instruction width
[005] = 10h 16 bit instruction = 2 bytes
[006] = 0Ah PC points to byte (not instruction)
Load FSRn ← 005h ⇒ [FSRn] = [INDFn] = 10h PC ← PC + 2 on non-branch instruction
Embedded Systems — Hadassah College — Spring 2011 PIC18 Dr. Martin Land 7 Embedded Systems — Hadassah College — Spring 2011 PIC18 Dr. Martin Land 8
Migration to PIC18 Migration to PIC18
10 bit A/D converter on 13 inputs Register changes
13 inputs Mid‐Range PIC18
AN0 , ... , AN12 Register Bit Register Bit
OPTION_REG NOT_RBPU INTCON2 NOT_RBPU
Physical pin assignments device dependent OPTION_REG INTEDG INTCON2 INTEDG0
New interrupt register
Embedded Systems — Hadassah College — Spring 2011 PIC18 Dr. Martin Land 9 Embedded Systems — Hadassah College — Spring 2011 PIC18 Dr. Martin Land 10
Migration to PIC18 Migration to PIC18
Example code changes Differences in status bit operation
STATUS Bits
Mid‐Range Code PIC18 Code Instruction
Mid‐Range PIC18
bcf STATUS,RP0 clrf BSR ; first occurrence only ADDLW C, DC, Z C, DC, Z, OV, N
bcf STATUS,RP1 ; otherwise remove ADDWF C, DC, Z C, DC, Z, OV, N
movf INDF,w movf INDF0,w ANDLW Z Z, N
ANDWF Z Z, N
movf TMR0,w movf TMR0L,w
COMF Z Z, N
movf FSR,w movf FSR0L,w DECF Z C, DC, Z, OV, N
movf SSPCON,w movf SSPCON1,w INCF Z C, DC, Z, OV, N
movf ADRES,w movf ADRESH,w IORLW Z Z, N
IORWF Z Z, N
movf OPTION_REG,w movf T0CON,w ; TIMER0 operations
MOVF Z Z, N
movf PCON,w movf RCON,w RETFIE GIE GIE/GIEH, PEIE/GIEL
RLF C, DC, Z C, Z, N New
Interrupt vector RRF C, DC, Z C, Z, N New
Mid‐range address = 0x04 → PIC18 address 0x08 (byte addressing) SUBLW C, DC, Z C, DC, Z, OV, N
SUBWF C, DC, Z C, DC, Z, OV, N
XORLW Z Z, N
XORWF Z Z, N
Embedded Systems — Hadassah College — Spring 2011 PIC18 Dr. Martin Land 11 Embedded Systems — Hadassah College — Spring 2011 PIC18 Dr. Martin Land 12
Migration to PIC18 Migration to PIC18
New instructions — 1 New instructions — 2
ADDWFC f, d, a (access) Add WREG and Carry bit to f BZ n Branch if Zero
BTG f, d, a Bit Toggle f
CPFSEQ f, a Compare f with WREG, Skip =
BC n Branch if Carry
CPFSGT f, a Compare f with WREG, Skip > BN n Branch if Negative
CPFSLT f, a Compare f with WREG, Skip < BNC n Branch if Not Carry
DAW — Decimal Adjust WREG BNN n Branch if Not Negative
LFSR f, k Literal k to FSR(f)
BNOV n Branch if Not Overflow
MOVF f, d, a Move f
MOVFF fs, fd Move fs to fd BNZ n Branch if Not Zero
MOVLB k Move Literal to BSR<3:0> BOV n Branch if Overflow
MULLW k Multiply k with WREG → PRODH:PRODL BRA n Branch Unconditionally
MULWF f, a Multiply WREG with f → PRODH:PRODL DCFSNZ f, d, a Decrement f, Skip if Not 0
NEGF f, a Negate f
INFSNZ f, d, a Increment f, Skip if Not 0
POP — Pop (delete) Top of Return Stack (TOS)
PUSH — Push (PC+2) to Top of Return Stack (TOS) TSTFSZ Skip next on file == 0
Embedded Systems — Hadassah College — Spring 2011 PIC18 Dr. Martin Land 13 Embedded Systems — Hadassah College — Spring 2011 PIC18 Dr. Martin Land 14
High Level Language
Why not assembly language
Laborious and tedious
Difficult to manage complex programs
Program flow
Mathematical tasks
C Programming Debugging
Required for critical path
Very fast code
for PIC18 Exact timing — code timed in clock cycles
Why C
Standard and portable
Designed for simple processors (1970s machines)
"Close" to hardware
Straightforward compilation
Human-readable disassembly
Hands-on optimization
Embedded Systems — Hadassah College — Spring 2011 PIC18 Dr. Martin Land 15 Embedded Systems — Hadassah College — Spring 2011 PIC18 Dr. Martin Land 16
Adapting C to PIC Example 1
Standard compiler strategies #include <p18f242.h> // 18F242 header file
Similar for all Instruction Set Architectures // predefines TRISB, PORTB
unsigned char counter;
Recursive procedures
Variable allocation
void main (void)
Mathematical functions
{
TRISB = 0; // set PORTB = outputs
PIC-specific strategies counter = 1;
Module programming
Timers, A/D, comparators, ports, ... while (1)
Controlled with Special Function Registers (SFRs) {
Device header file PORTB = counter; // PORTB ← counter value
Define SFRs as reserved words /* compiled code copies value of variable counter to
Program reads / writes SFRs variable PORTB, stored at address of SFR PORTB */
I/O counter = counter + 1;
Read / write ports as SFRs }
Standard output → USART }
Embedded Systems — Hadassah College — Spring 2011 PIC18 Dr. Martin Land 17 Embedded Systems — Hadassah College — Spring 2011 PIC18 Dr. Martin Land 18
MPLAB C18 Compiler Start MPLAB IDE
C compiler for PIC18
Specific to PIC18 ISA
Commercial software
$150 from Microchip
Academic version
Learning tool
Time limited
Embedded Systems — Hadassah College — Spring 2011 PIC18 Dr. Martin Land 19 Embedded Systems — Hadassah College — Spring 2011 PIC18 Dr. Martin Land 20
Configure > Select Device Project > Project Wizard
Save Project by Pathname Add linker Template and C File
Embedded Systems — Hadassah College — Spring 2011 PIC18 Dr. Martin Land 21 Embedded Systems — Hadassah College — Spring 2011 PIC18 Dr. Martin Land 22
Build Project Testing Code with Simulator
Either Debugger > Select Tool > MPLAB SIM
Project > Build All Debug toolbar opens
Right click on project name in Project Window > Build All Debugger > Step Into → Debugger > Reset > Processor Reset
Click Build All icon on Project toolbar Assembly code editor opens (disassembly)
Output window shows result of build process Green arrow points to program start (main)
Should be no errors or warnings for default template file
Code
Add constants / variables / code / directives / macros Step Into
Rebuild Run program in trace mode (single step)
Embedded Systems — Hadassah College — Spring 2011 PIC18 Dr. Martin Land 23 Embedded Systems — Hadassah College — Spring 2011 PIC18 Dr. Martin Land 24
View > Watch Breakpoints
Choose + Add items to watch list Set breakpoint
SFRs Symbols Double-click on line of code
Right click > choose Set Breakpoint from menu
Run
Program stops before breakpoint
Embedded Systems — Hadassah College — Spring 2011 PIC18 Dr. Martin Land 25 Embedded Systems — Hadassah College — Spring 2011 PIC18 Dr. Martin Land 26
More Details Example 2
C code
Radix
TRISA = 0b'10000110'; // initialise PORTA #include <p18cxxx.h> // PIC18 header file
Example 2 Example 2
Disassembly — 3 Disassembly — 4
6: { 9: long k = 0xaabbccdd, z;
7: short i = 0xaa , x; 002E 0EDD MOVLW 0xdd
0030 6EF3 MOVWF PRODL, ACCESS ; DDh -> PRODL
0014 0EAA MOVLW 0xaa
0032 0E08 MOVLW 0x8
0016 6EDE MOVWF POSTINC2, ACCESS
0034 CFF3 MOVFF PRODL, PLUSW2 ; PRODL -> [FSR2L + 8] = k_0
; AAh -> [FSR2L] = i, FSR2L++ 0036 FFDB NOP
0018 6ADD CLRF POSTDEC2, ACCESS ; 0 -> FSR2L-- 0038 0ECC MOVLW 0xcc
8: int j = 0xaabb, y; 003A 6EF3 MOVWF PRODL, ACCESS ; CCh -> PRODL
001A 0EBB MOVLW 0xbb 003C 0E09 MOVLW 0x9
001C 6EF3 MOVWF PRODL, ACCESS ; BBh -> PRODL 003E CFF3 MOVFF PRODL, PLUSW2 ; PRODL -> [FSR2L + 9] = k_1
0040 FFDB NOP
001E 0E04 MOVLW 0x4
0042 0EBB MOVLW 0xbb
0020 CFF3 MOVFF PRODL, PLUSW2
0044 6EF3 MOVWF PRODL, ACCESS ; BBh -> PRODL
; PRODL = BBh -> [FSR2L + 4] = j_0 0046 0E0A MOVLW 0xa
0022 FFDB NOP 0048 CFF3 MOVFF PRODL, PLUSW2 ; PRODL -> [FSR2L + 10] = k_2
0024 0EAA MOVLW 0xaa 004A FFDB NOP
0026 6EF3 MOVWF PRODL, ACCESS ; AAh -> PRODL 004C 0EAA MOVLW 0xaa
0028 0E05 MOVLW 0x5 004E 6EF3 MOVWF PRODL, ACCESS ; AAh -> PRODL
0050 0E0B MOVLW 0xb
002A CFF3 MOVFF PRODL, PLUSW2
0052 CFF3 MOVFF PRODL, PLUSW2 ; PRODL -> [FSR2L + 11] = k_3
; PRODL = AAh -> [FSR2L + 5] = j_1 0054 FFDB NOP
002C FFDB NOP
Embedded Systems — Hadassah College — Spring 2011 PIC18 Dr. Martin Land 31 Embedded Systems — Hadassah College — Spring 2011 PIC18 Dr. Martin Land 32
Example 2 Example 2
Disassembly — 5 Disassembly — 6
10: x = 0x12 + i; 11: y = 0x1122 + j;
0056 CFDE MOVFF POSTINC2, 0 0072 0E04 MOVLW 0x4
; [FSR2] = i_0 -> [0] , FSR2++ 0074 CFDB MOVFF PLUSW2, 0 ; [FSR2 + 4] = j_0 -> [0]
0058 F000 NOP 0076 F000 NOP
005A CFDD MOVFF POSTDEC2, 0x1 0078 0E05 MOVLW 0x5
; [FSR2] = i_1 -> [1] , FSR2-- 007A CFDB MOVFF PLUSW2, 0x1 ; [FSR2 + 5] = j_1 -> [1]
005C F001 NOP 007C F001 NOP
005E 0E12 MOVLW 0x12 007E 0E22 MOVLW 0x22
0060 2600 ADDWF 0, F, ACCESS ; [0] + 0x12 -> [0] 0080 2600 ADDWF 0, F, ACCESS ; [0] + 0x22 -> [0]
0062 0E00 MOVLW 0 0082 0E11 MOVLW 0x11
0064 2201 ADDWFC 0x1, F, ACCESS 0084 2201 ADDWFC 0x1, F, ACCESS
; [1] + 0x00 + C -> [1] ; [1] + 0x11 + C -> [1]
0066 0E02 MOVLW 0x2 0086 0E06 MOVLW 0x6
0068 C000 MOVFF 0, PLUSW2 ; [0] -> [FSR2 + 2] = x_0 0088 C000 MOVFF 0, PLUSW2 ; [0] -> [FSR2 + 6] = y_0
006A FFDB NOP 008A FFDB NOP
006C 0E03 MOVLW 0x3 008C 0E07 MOVLW 0x7
006E C001 MOVFF 0x1, PLUSW2 ; [1] -> [FSR2 + 3] = x_1 008E C001 MOVFF 0x1, PLUSW2 ; [1] -> [FSR2 + 7] = y_1
0070 FFDB NOP 0090 FFDB NOP
Embedded Systems — Hadassah College — Spring 2011 PIC18 Dr. Martin Land 33 Embedded Systems — Hadassah College — Spring 2011 PIC18 Dr. Martin Land 34
Example 2 Example 3
Disassembly — 7 #include <stdio.h>
12: z = 0x33445566 + k;
0092
0094
0E08
CFDB
MOVLW 0x8
MOVFF PLUSW2, 0 [0] = k_0 -> [FSR2 + 8]
#pragma config WDT = OFF
0098
009A
0E09
CFDB
MOVLW 0x9
MOVFF PLUSW2, 0x1 [1] = k_1 -> [FSR2 + 9]
void main (void)
009E
00A0
0E0A
CFDB
MOVLW 0xa
MOVFF PLUSW2, 0x2 [2] = k_2 -> [FSR2 + 10]
{
00A4
00A6
0E0B
CFDB
MOVLW 0xb
MOVFF PLUSW2, 0x3 [3] = k_3 -> [FSR2 + 11]
printf ("Hello, world!\n");
00AA
00AC
0E66
2600
MOVLW 0x66
ADDWF 0, F, ACCESS [0] + 0x66 -> [0]
while (1)
00AE
00B0
0E55
2201
MOVLW 0x55
ADDWFC 0x1, F, ACCESS [1] + 0x55 + C -> [1]
;
00B2
00B4
0E44
2202
MOVLW 0x44
ADDWFC 0x2, F, ACCESS [2] + 0x44 + C -> [2]
}
00B6 0E33 MOVLW 0x33
00B8 2203 ADDWFC 0x3, F, ACCESS [3] + 0x33 + C -> [3]
00BA
00BC
0E0C
C000
MOVLW 0xc
MOVFF 0, PLUSW2 [0] -> [FSR2 + 12] = z_0
Library function printf
00C0 0E0D MOVLW 0xd Character output to
00C2 C001 MOVFF 0x1, PLUSW2 [1] -> [FSR2 + 13] = z_1
00C6 0E0E MOVLW 0xe Hardware USART
00C8
00CC
C002
0E0F
MOVFF 0x2, PLUSW2
MOVLW 0xf
[0] -> [FSR2 + 14] = z_0
User defined function
00CE C003 MOVFF 0x3, PLUSW2 [1] -> [FSR2 + 15] = z_1 SIM UART1
13:
14: while(1){ PLAB function for
00D2
15:
D7FF BRA 0xd2
;
output capture
16: }
Embedded Systems — Hadassah College — Spring 2011 PIC18 Dr. Martin Land 35 Embedded Systems — Hadassah College — Spring 2011 PIC18 Dr. Martin Land 36
Stimulus Stimulus Dialog
Simulating events
Level change or pulse to I/O port pin
Value in SFR or GFR data memory
Stimulus dialog
Table of events and triggers
Asynchronous
One time change to I/O pin or register
Triggered by user
"Fire" button on stimulus GUI within MPLAB IDE
Synchronous
Automatic triggering
Predefined signal / data changes to I/O, SFR or GPR
Embedded Systems — Hadassah College — Spring 2011 PIC18 Dr. Martin Land 37 Embedded Systems — Hadassah College — Spring 2011 PIC18 Dr. Martin Land 38
C18 Software Library Functions Example 4 — 1
ANSI 1989 standard C libraries #include <p18F242.h> Inputs (switches)
#include <delays.h> RB4:RB5 on portB
Character classification, data conversion, string / memory
void initialize (void); RB7 on portC
Character output library void diagnostic (void); Outputs (LED)
fprint, fprintf, putc, ... void main (void) RC6:RC0 on portC
Device software libraries {
initialize(); // initialize ports
UART-type I/O
diagnostic(); // turn on LEDs for 1 sec
ReadUART, WriteUART, getcUART, putcUART, ...
loop:
External device drivers if (PORTBbits.RB4 == 0) // copy switch state on RB4 to RC6
LCD, serial communications, ... PORTCbits.RC6 = 0;
Delay functions else PORTCbits.RC6 = 1;
Delay1TCY Delay one instruction cycle
Delay10TCYx Delay multiples of 10 instruction cycles if (PORTBbits.RB5 == 0) // copy switch state on RB5 to RC5
Delay100TCYx Delay multiples of 100 instruction cycles PORTCbits.RC5 = 0;
Delay1KTCYx Delay multiples of 1,000 instruction cycles else PORTCbits.RC5 = 1;
Delay10KTCYx Delay multiples of 10,000 instruction cycles
goto loop;
Reset
}
Report cause of previous reset
Embedded Systems — Hadassah College — Spring 2011 PIC18 Dr. Martin Land 39 Embedded Systems — Hadassah College — Spring 2011 PIC18 Dr. Martin Land 40
Example 4 — 2 C18 Hardware Library Functions
void initialize (void) Peripheral module libraries
{
TRISA = 0b00000000; // set portA as outputs I/O port B
TRISB = 0b00110000; // set RB5:RB4 as inputs Configure interrupts, pull-up resistors, on PORTB pins
// rest of portC as outputs A/D converter
TRISC = 0b10000000; // set RC7 as input
Configure, start + check + read conversion, close device
// rest of portC as outputs
PORTA = 0; // reset portA ... portC CPP module
PORTB = 0; Configure, start, read, stop input capture
PORTC = 0; Configure, start, stop PWM output
}
Timers
void diagnostic (void) Configure, start, read, write, stop timer
{ USART
PORTCbits.RC6 = 1; // turn on RC6
Configure, start, check, read, write, stop USART
PORTCbits.RC5 = 1; // turn on RC5
delay 100 × 10 × 1000 TCY = 106 TCY
Delay10KTCYx(100); //
Serial communications
PORTCbits.RC6 = 0; // turn off RC6
PORTCbits.RC5 = 0; // turn off RC5 Proprietary chip-to-chip data communication
Delay10KTCYx(100); // delay 106 TCY I2C, Microwire, SPI
}
Embedded Systems — Hadassah College — Spring 2011 PIC18 Dr. Martin Land 41 Embedded Systems — Hadassah College — Spring 2011 PIC18 Dr. Martin Land 42
TimerX, X = 0, 1, 2, 3, 4 Motor Control with One PWM
Connections
Timer library functions
unsigned int ReadTimerX( void ); Motor enable
Read unsigned integer from TimerX Output pin RA5
void WriteTimerX( unsigned int ); Motor speed control
PWM CCP1 output pin (device-dependent — usually RC2 on PIC18)
Write unsigned integer to TimerX
Control A = CCP1
void CloseTimer0( void );
Control B = NOT(CPP1)
Close TimerX
PWM duty cycle > 50% ⇒ Aaverage > Baverage ⇒ forward motion
void OpenTimerX( unsigned char ) PWM duty cycle < 50% ⇒ Aaverage < Baverage ⇒ reverse motion
Configure TimerX with unsigned character configuration bit mask E A B Motor
mask = binary value → SFRs TMRXH:TMRXH
Connections 5 V
1 0 0
Constructed from reserved words motor Brake
A 1 1 1
Example Full
Ground Ground 1 1 0
mask = TIMER_INT_OFF & T2_PS_1_4 & T2_POST_1_2 Forward
& T0_EDGE_RISE Full
B 1 0 1
Sets interrupts disabled, prescaler 1:4, postscaler 1:2, rising edge 10 V E
Reverse
trigger 0 x x Coast
Embedded Systems — Hadassah College — Spring 2011 PIC18 Dr. Martin Land 43 Embedded Systems — Hadassah College — Spring 2011 PIC18 Dr. Martin Land 44
Motor Control with One PWM Motor Control with One PWM
PWM parameters Code
Internal oscillator #include <timers.h>
#include <pwm.h>
fOSC = 4 MHz ⇒ TOSC = 0.25 μs void motor(unsigned short);
Require PWM frequency > human hearing threshold void main (void)
{
fPWM = 25 kHz ⇒ TPWM = 40 μs unsigned short speed = 0x50;
TPWM = 40 μs = 4 × (PR2 + 1) × P × 0.25 μs = (PR2 + 1) × P × 1 μs TRISA = 0b00000000; // portA = outputs, RA2 = motor enable
TRISC = 0b00000000; // portC = outputs, RC2 = CCP1 PWM
(PR2 + 1) × P = 40
PORTA = 0; // disable motor
Preset and PR2 PORTC = 0; // PWM output = 0
OpenTimer2(TIMER_INT_OFF & T2_PS_1_1 & T2_POST_1_1);
P = 1 ⇒ PR2 + 1 = 40 ⇒ PR2 = 39 = 0x27 // Enable Timer2, set P = 1
ΔTON = P × TOSC = 0.25 μs ⇒ ΔTON / TPWM = 0.25 μs / 40 μs = 0.625% OpenPWM1(0x27); // Enable PWM1, set PR2
/* program sets speed and calls motor(speed) */
Breaking duty cycle = 50% }
TON = 0.50 × 40 μs = 20 μs ⇒ DC = 20 μs / 0.25 μs = 80 = 0x50 void motor(unsigned int speed);
{
Maximum duty cycle SetDCPWMx(speed); // set duty cycle
Forward 80 < DC < 160
TON = 40 μs ⇒ DC = 40 μs / 0.25 μs = 160 PORTAbits.RA2 = 1; // enable motor
Reverse 0 < DC < 80 }
Embedded Systems — Hadassah College — Spring 2011 PIC18 Dr. Martin Land 45 Embedded Systems — Hadassah College — Spring 2011 PIC18 Dr. Martin Land 46
A/D Converter A/D Converter
Functions Configuration words
Embedded Systems — Hadassah College — Spring 2011 PIC18 Dr. Martin Land 47 Embedded Systems — Hadassah College — Spring 2011 PIC18 Dr. Martin Land 48
A/D Converter Inline Assembly
Example
Insert assembly code into C program
#include <p18F242.h>
_asm begins assembly section
#include <adc.h>
_endasm ends assembly section
void main (void)
{ Assembled by C18 compiler
int data; Uses
// Enable ADC — portA<3:0> = analog inputs, internal reference Processor-specific actions
// right justify result, channel 0, no interrupt SLEEP, CLRWDT, etc
OpenADC(ADC_FOSC_8 & ADC_RIGHT_JUST & ADC_3ANA_0REF ,
Critical path
ADC_CH0 & ADC_INT_OFF);
SetChanADC(ADC_CH0); // convert channel 0
Very fast / clock counting procedures
Delay10TCYx(2); // delay 20 us for acquisition Special requirements
ConvertADC(); No assembler directives — only PIC18 ISA
while (BusyADC()); // wait for conversion Comments in C or C++ format
data = ReadADC() // read data
Operands fully specified
SetChanADC(ADC_CH3); // switch channel
Default radix = decimal
Delay10KTCYx (2); // delay 20 us for acquisition
ConvertADC(); Literals specified in C notation
} Labels must end with colon
Embedded Systems — Hadassah College — Spring 2011 PIC18 Dr. Martin Land 49 Embedded Systems — Hadassah College — Spring 2011 PIC18 Dr. Martin Land 50
Inline Assembly Example Specifying Code Sections
void main (void) Code sections
{
Overrides usual C procedure assignments
while (1)
{ Provide assembly-type section declarations for relocatable code
check_function_1(); // some C-oriented work Pragmas
check_function_2(); #pragma code (section name) (=address)
_asm #pragma romdata (section name) (=address)
CLRWDT // reset watchdog timer #pragma udata (section name) (=address)
_endasm
#pragma idata (section name) (=address)
}
} Examples
#pragma code _entry_scn=0x00 // defines reset routine
void _entry (void) // at address 0
{
_asm goto _startup _endasm Default: start at user main()
}
#pragma code _startup_scn // defines startup routine
void _startup (void) // linker chooses address
{ ...
Embedded Systems — Hadassah College — Spring 2011 PIC18 Dr. Martin Land 51 Embedded Systems — Hadassah College — Spring 2011 PIC18 Dr. Martin Land 52
Configuration Bits Interrupts
Static hardware configuration Interrupts in C program
Device dependent Enable interrupt
Written to program memory during EEPROM programming Interrupt Service Routine (ISR)
Not program accessible at run time Located at fixed interrupt address
Written in C or inline assembly
Pragma Cannot pass parameters to / from ISR
#pragma config Access global variables / define local variables
Priority
Example High / low priority interrupts in PIC18
For typical PIC18 #pragma interrupt function_name (save = list)
#pragma config OSC = HS, OSCS = OFF Declares high priority ISR
// oscillator = HS, oscillator switch off Uses Fast Register Stack to save STATUS, WREG, BSR registers
#pragma config PWRT = ON, BOR = OFF Interrupt ends fast return (restores context)
// power-up timer on, brown-out detect off #pragma interruptlow function_name (save = list)
#pragma config WDT = OFF Declares low priority ISR
// watchdog timer is off Saves / restores STATUS, WREG, BSR using software stack
Embedded Systems — Hadassah College — Spring 2011 PIC18 Dr. Martin Land 53 Embedded Systems — Hadassah College — Spring 2011 PIC18 Dr. Martin Land 54
Interrupt Example
#include <p18F242.h> main starts timer0
#include <timers.h>
timer0 counts 28 ⇒ interrupt ⇒ counter++ → portB
unsigned char counter = 0;
#pragma code high_vector=0x08 // code section allocated to address 0x08h
void interrupt (void) // section written in C → inline assembly
{
_asm GOTO timer0_isr _endasm //jump to ISR
}
#pragma code
#pragma interrupt timer0_isr
void timer0_isr (void)
// default code section
// specify code as high-priority ISR Practical Example
{
}
PORTB = ++counter;
INTCONbits.TMR0IF = 0; // Clear TMR0 interrupt flag Elevator Controller
void main (void)
{
TRISB = 0b00000000; // portB = outputs
PORTB = 0; // outputs = 0
OpenTimer0(TIMER_INT_ON & T0_SOURCE_INT & T0_8BIT & T0_PS_1_4);
// enable interrupt, 8-bit count, internal clock, prescaler 1:4
INTCONbits.GIE = 1; // Enable global interrupt
while (1) // wait for interrupt
{
}
}
Embedded Systems — Hadassah College — Spring 2011 PIC18 Dr. Martin Land 55 Embedded Systems — Hadassah College — Spring 2011 PIC18 Dr. Martin Land 56
Embedded Elevator Controller Embedded Elevator Controller
General requirements State machine
Travel up + down Elevator States
Store + display current position (floor) Up car traveling up
Store current direction (up / down)
Down car traveling down
Store + classify floor requests
Door car stopped with door open
External — call to floor
Idle car not traveling + door closed + no pending requests
Internal — call from passenger
Direction — up / down from current position Passenger Call I/O Events
Grant floor requests in order of current direction Car internal passenger request — call for floor f_pass
Announce floor Example of floor request ordering Call external request — call from floor f_call to d_call (up/down)
Stop Car at floor 0
Block passenger in elevator doorway
Call to floor 4 → up
Clear request from memory Passenger at 4 requests floor 1 → down Internal state (memory)
Open door Down call to floor 3 → stop at 3
Up call to floor 2 → no stop at 2 Floor current elevator position
Delay Stop at floor 0
Pending bitmap of stored floor and direction requests
Check obstacle in door Up to floor 2
Passenger at 2 requests floor 5 → up Direction car executing up / down cycle
Close door
Embedded Systems — Hadassah College — Spring 2011 PIC18 Dr. Martin Land 57 Embedded Systems — Hadassah College — Spring 2011 PIC18 Dr. Martin Land 58
Embedded Elevator Controller Embedded Elevator Controller
State transition diagram Sequential model for pending state
No Pending Pending
Floor Direction
Requests No Pending Block = yes Floor 0 1 2 3 ... N
Requests Timer > 0 Pending Up Up Up Up Up Up Down
Pending Down Down Down Down Down
Idle Call (floor = F_Call) Door
Ca
ll (
flo or p Pending bitmaps
o Flo _u
r >
F_ r = ing
Floor_pending_down
o d pending_up / pending_down
ns e n
Call (floor < F_Call)
Ca
Pending Requests
Direction = down
ll) Se r_p
Sensor = Floor
F lo
if (f_car > floor) pending_up.f_car ← 1
if (f_car < floor) pending_down.f_car ← 1
sts
q ue p
e u
R = Call — external request from floor f_call to direction d_call
ng n o
n di ctio = n 0
Pe Dire lock r =
B ime I/O calls if (d_call ≠ floor){
Up Down On floor if (d_call = up) pending_up<f_ call> ← 1
T
Call up / down
Floor Pending Direction In car if (d_call = down) pending_down<f_ call> ← 1
Call floor }
Embedded Systems — Hadassah College — Spring 2011 PIC18 Dr. Martin Land 59 Embedded Systems — Hadassah College — Spring 2011 PIC18 Dr. Martin Land 60
Embedded Elevator Controller Embedded Elevator Controller
Direction + idle Call I/O
Embedded Elevator Controller Embedded Elevator Controller
Car position control Motor control
Open loop control motor Binary control motor
Embedded Elevator Controller Embedded Elevator Controller
Flow chart of main loop Code — 1
// header files
#include <p18F2420.h>
close door down routine up routine #include <delays.h>
#include <timers.h>
yes yes yes #include <pwm.h>
no no no no #include <portb.h>
start idle door down up
Embedded Systems — Hadassah College — Spring 2011 PIC18 Dr. Martin Land 67 Embedded Systems — Hadassah College — Spring 2011 PIC18 Dr. Martin Land 68
Embedded Elevator Controller Embedded Elevator Controller
Code — 2 Code — 3
// global variables // interrupt vector
#pragma code high_vector=0x08 // code section at address 0x08h
unsigned int floor; // car position void interrupt (void)
unsigned short state; // state bitmap {
// 0 = idle, 1 = door, 2 = down, 3 = up _asm GOTO limit_isr _endasm //jump to ISR
unsigned short cycle; // direction cycle (0 = down / 1 = up) }
unsigned long pending_dn; // bitmap: up call to floor i => bit i = 1 // interrupt service routine
unsigned long pending_up; // bitmap: down call
unsigned long mask; // index into bitmap #pragma code // place in default code section
unsigned int selector; // select floor to read buttons #pragma interrupt limit_isr // specify code as high-priority ISR
unsigned short safety; // copy of portB void limit_isr(void)
unsigned short prev_RB3; // previous reading of portB.bit3 (at floor) {
unsigned int DC; // PWM duty cycle short limit;
limit = PORTB; // read portB<7:6> => reset interrupt
// configuration bits if (limit & 128) {
stop_up();
#pragma config PWRT = ON // power-up timer on floor = FLOORS;
#pragma config WDT = ON // watchdog timer on }
#pragma config CCP2MX = PORTC // CCP2 on RC1 if (limit & 64) {
#pragma config PBADEN = OFF // PORTB<4:0> pins = digital I/O stop_dn();
#pragma config OSC = INTIO67 // oscillator = internal 8 MHz floor = 0;
// T_CY = 0.5 us = 500 ns }
Embedded Systems — Hadassah College — Spring 2011 PIC18 Dr. Martin Land 69 Embedded Systems — Hadassah College — Spring 2011 PIC18 Dr. Martin Land 70
Embedded Elevator Controller Embedded Elevator Controller
Code — 4 Code — 5
void main (void) //
{ // motor PWM configuration
// //
// Reset code
// TRISC = 0b11111111; // portC = outputs
TRISA = 0b11100000; // portA<7:5> -- inputs
// portA<7> -- up call button PORTC = 0; // portC<2> = CPP1 -- PWM output
// portA<6> -- down call button // portC<0> -- 1 = motor enabled
// portA<5> -- car call button
// portA<4:0> -- outputs PORTCbits.RC0 = 0; // disable motor
// portA<4:0> -- 5-bit floor selector
PORTA = 0; // reset portA // enable Timer2 with no interrupt and P = 2
OpenTimer2(TIMER_INT_OFF & T2_PS_1_1 & T2_POST_1_2);
TRISB = 0b11111110; // portB<7:1> -- inputs
// portB<7> -- car near top floor // enable PWM1 with 50% duty cycle
// portB<6> -- car near ground floor
// portB<5:4> -- pulled up to logic 1 OpenPWM1(39); // Enable PWM1, set PR2+1 = 40
// portB<3> -- car positioned at floor // T_PWM = 4*40*2*0.125 us = 40 us
// portB<2> -- door blocked
// portB<1> -- door open DC = 80; // DC = 80 => T_ON = 80*2*0.125 us = 20 us
// portB<0> -- output
SetDCPWM1(DC); // set PWM1 duty cycle DC
// portB<0> -- door motor (1 = open)
Embedded Systems — Hadassah College — Spring 2011 PIC18 Dr. Martin Land 71 Embedded Systems — Hadassah College — Spring 2011 PIC18 Dr. Martin Land 72
Embedded Elevator Controller Embedded Elevator Controller
Code — 6 Code — 7
// initialize car at ground floor // main loop
cycle = 0; // down cycle while(1){
// reset watchdog timer
pending_dn = 0; // clear pending calls _asm CLRWDT _endasm
pending_up = 0; // read call + passenger buttons
safety = PORTB; // read portB: interrupt on change in portB<7:6>
close_door();
mask = 1;
safety = PORTB; // read portB for (selector = 0 ; selector < 32 ; selector++){
if (!(safety & 64)) init_dn(); // go to ground floor // write to portA: read input pins followed by write of outputs
// output lines portA<4:0> select floor to read
// read fl_0 until reach ground floor PORTA = selector;
// T_CY = 0.125 us => delay 1.25 ms if (PORTA & 32){ // RA5 = car button
if (selector == floor) open_door(); // call here
while (!(PORTB & 64)) Delay10KTCYx(1); if (selector > floor) pending_up |= mask; // set bit
stop_dn(); // stop car if (selector < floor) pending_dn |= mask; // in bitmap
floor = 0; }
if (PORTA & 64){ // RA6 = down call
state = 1; // idle if (floor == selector) open_door(); // call to this floor
safety = PORTB; // read portB else pending_dn |= mask; // set bit in bitmap
}
prev_RB3 = PORTB & 8; // copy of RB3 if (PORTA & 128){ // portA<7> = up call
// enable interrupt on changes to portB<7:4> if (floor == selector) open_door(); // call to this floor
// enable pull-ups else pending_up |= mask; // set bit in bitmap
}
OpenPORTB( PORTB_CHANGE_INT_ON & PORTB_PULLUPS_ON); mask << 1; // next mask
}
Embedded Systems — Hadassah College — Spring 2011 PIC18 Dr. Martin Land 73 Embedded Systems — Hadassah College — Spring 2011 PIC18 Dr. Martin Land 74
Embedded Elevator Controller Embedded Elevator Controller
Code — 8 Code — 9
switch (state) { void open_door( void ){
case 1: // idle state
if (pending_up != 0) { while(!(PORTB & 2)) {
cycle = 1; // starting up cycle PORTBbits.RB0 = 1; // try to open door until open
init_up(); // travel up
break; Delay10KTCYx(10); // T_CY = 0. 5 us
} // delay 5 ms
if (pending_dn != 0) { }
cycle = 0; // starting down cycle
init_dn(); // travel down state = 2; // door open state
break;
} }
break;
case 2: // door open state
close_door(); // close door void close_door( void ){
break;
case 4: // traveling down state while( (PORTB & 2) && !(PORTB & 4) ) {
down(); // process down tasks PORTBbits.RB0 = 0; // close door unless blocked
break;
case 8: // traveling up state Delay10KTCYx(10); // T_CY = 0. 5 us
up(); // process up states // delay 5 ms
break; }
default:
break; }
}
Embedded Systems — Hadassah College — Spring 2011 PIC18 Dr. Martin Land 75 Embedded Systems — Hadassah College — Spring 2011 PIC18 Dr. Martin Land 76
Embedded Elevator Controller Embedded Elevator Controller
Code — 10 Code — 11
void init_up( void ){ void up( void ){
// accelerate motor from DC = 80 to 160 unsigned long floormask = 1; // bitmap index
// in 80 steps over 1 second
// (12.5 ms / step) // floor++ if car at floor for first time
int speed; if ( (PORTB & 8) && (prev_RB3 == 0) ) floor++;
state = 8; // traveling up state
PORTCbits.RC0 = 1; // enable motor prev_RB3 = PORTB & 8; // save last RB3
for (speed = 80 ; speed <= 160 ; speed++){ floormask << floor + 1; // update index
SetDCPWM1(speed); // PWM1 duty cycle // if next floor is pending begin to stop
Delay1KTCYx(25); // T_CY = 0.5 us
// delay 12.5 ms if (pending_up & floormask == 1) stop_up();
} }
}
void down( void ){
void init_dn( void ){
// accelerate motor from 80 to 0 unsigned long floormask = 1; // bitmap index
// in 80 steps over 1 second // floor-- if car at floor for first time
int speed;
state = 4; // traveling down state if ( (PORTB & 8) && (prev_RB3 == 0) ) floor--;
PORTCbits.RC0 = 1; // enable motor prev_RB3 = PORTB & 8; // save last RB3
for (speed = 80 ; speed >= 0 ; speed--){ floormask << floor - 1; // update index
SetDCPWM1(speed); // PWM1 duty cycle
Delay1KTCYx(25); // T_CY = 0.5 us // if next floor is pending begin to stop
// delay 12.5 ms if (pending_dn & floormask == 1) stop_dn();
}
} }
Embedded Systems — Hadassah College — Spring 2011 PIC18 Dr. Martin Land 77 Embedded Systems — Hadassah College — Spring 2011 PIC18 Dr. Martin Land 78
Embedded Elevator Controller Embedded Elevator Controller
Code — 12 Code — 13
void stop_up( void ){ void stop_dn( void ){
int speed; int speed;
for (speed = 160 ; speed >= 88 ; speed--){ for (speed = 0 ; speed <= 72 ; speed++){
// 80 + 10% * 80 = 88 // 80 - 10% * 80 = 72
SetDCPWM1(speed); // set PWM1 duty cycle speed SetDCPWM1(speed); // set PWM1 duty cycle speed
Delay1KTCYx(25); // T_CY = 0.5 us Delay1KTCYx(25); // T_CY = 0.5 us
// delay 12.5 ms // delay 12.5 ms
} }
while (!(PORTB & 8)) Delay10KTCYx(10); while (!(PORTB & 8)) Delay10KTCYx(10);
// wait for floor // wait for floor
SetDCPWM1(80); // stop SetDCPWM1(80); // stop
PORTCbits.RC0 = 0; // disable motor PORTCbits.RC0 = 0; // disable motor
open_door(); open_door();
Delay10KTCYx(3000); // delay = 15 sec Delay10KTCYx(3000); // delay = 15 sec
close_door(); close_door();
if (pending_up != 0) init_up(); if (pending_dn != 0) init_dn();
else if (pending_dn != 0) { else if (pending_up != 0) {
cycle = 0; // start down cycle cycle = 0; // start up cycle
init_dn(); init_up();
} }
else { else {
state = 1; // idle state state = 1; // idle state
cycle = 0; cycle = 0;
} }
} }
Embedded Systems — Hadassah College — Spring 2011 PIC18 Dr. Martin Land 79 Embedded Systems — Hadassah College — Spring 2011 PIC18 Dr. Martin Land 80