Transcript Document

C and Embedded Systems
• A P-based system used in a device (i.e, a car engine)
performing control and monitoring functions is
referred to as an embedded system.
– The embedded system is invisible to the user
– The user only indirectly interacts with the embedded system
by using the device that contains the P
• Most programs for embedded systems are written in C
– Portable – code can be retargeted to different processors
– Clarity – C is easier to understand than assembly
– compilers produce code that is close to manually-tweaked
assembly language in both code size and performance
1
So Why Learn Assembly Language?
• The way that C is written can impact assembly language size
and performance
– i.e., if the uint32 data type is used where uint8 would suffice, both
performance and code size will suffer.
• Learning the assembly language, architecture of the target P
provides performance and code size clues for compiled C
– Does the uP have support for multiply/divide?
– Can it shift only one position each shift or multiple positions? (i.e,
does it have a barrel shifter?)
– How much internal RAM does the P have?
– Does the P have floating point support?
• Sometimes have to write assembly code for performance
reasons.
2
C Compilation
V 0.6
3
MPLAB PIC24 C Compiler
• Programs for hardware experiments are written in
C
• Will use the MPLAB PIC24 C Compiler from
Microchip
• Excellent compiler, based on GNU C, generates
very good code
• Use the MPLAB example projects from
reesemicro.com to get started
4
Referring to Special Function Registers
__attribute__ is not ANSI C,
but it is common in GCC
#include "pic24.h"
Must have this include statement at top of a C file to include the
all of the header files for the support libraries.
Special Function Registers can be accessed like variables:
extern volatile unsigned int
Defined in compiler header files
PORTB = 0xF000;
PORTB __attribute__((__sfr__));
Register
Name
Special
function
register
In C code, can refer to special register
using the register name
5
Referring to Bits within
Special Function Registers
The compiler include file also has definitions for individual
bits within special function registers. Can use these to access
individual bits and bit fields:
PORTBbits.RB5 = 1;
PORTBbits.RB2 = 0;
//set bit 5 of PORTB
//clear bit 2 of PORTB
if (PORTBbits.RB0) {
//execute if-body if LSB of PORTB is '1'
....
}
Uses bit fields in C structs
OSCCONbits.NOSC = 2;
//bit field in OSSCON register
6
Referring to Bits within
Special Function Registers
Using registername.bitname requires you to remember both
the register name and the bitname. For bitnames that are
UNIQUE, can use just _bitname.
_RB5 = 1;
_RB2 = 0;
//set bit 5 of PORTB
//clear bit 2 of PORTB
if (_RB0) {
//execute if-body if LSb of PORTB is '1'
....
}
_NOSC = 2;
//bit field in OSSCON register
7
Variable Qualifiers, Initialization
If a global variable does not have an initial value, by default
the runtime code initializes it to zero – this includes static
arrays. To prevent a variable from being initialized to zero,
use the _PERSISTENT macro in front of it: Initialization to zero is
uint16
uint8
u16_k;
u8_k = 4;
required in C only for global
variables
//initialized to 0
//initialized to 4
_PERSISTENT uint8 u8_resetCount;
//uninitialized, value
// is unknown
The C runtime code is run before main() entry, so run on
every power-up, every reset. Use _PERSISTENT variables to
track values across processor resets.
V 0.1
8
C Macros, Inline Functions
The support library and code examples makes extensive use of
C macros and Inline functions. The naming convention is all
uppercase:
#define DEFAULT_BAUDRATE
#define LED1
_RB15
57600
Macros are like an “inline” function
Macros, the left hand
label is replaced by the
right hand text
static inline void CONFIG_RB1_AS_DIG_INPUT(){
DISABLE_RB1_PULLUP();
Inline functions expand
_TRISB1 = 1;
without a subroutine
_PCFG3 = 1;
call.
}
V 0.1
9
PIC24HJ32GP202 µC
Hardware lab exercises
will use the
PIC24HJ32GP202 µC
(28-pin DIP)
Note that most pins
have multiple
functions.
Pin functions are
controlled via special
registers in the PIC.
Will download programs into the PIC24
µC via a serial bootloader that allows
the PIC24 µC to program itself.
Copyright Delmar Cengage Learning 2008. All Rights Reserved.
From: Reese/Bruce/Jones, “Microcontrollers: From Assembly to C with the PIC24 Family”.
10
There are
multiple
VDD/VSS pins
on your PIC24
µC; hook them
all up!!!
Initial Hookup
Any input voltage from 5 V to 15 V
will work.
Not included in
your board.
Copyright Delmar Cengage Learning 2008. All Rights Reserved.
From: Reese/Bruce/Jones, “Microcontrollers: From Assembly to C with the PIC24 Family”.
11
Powering the
PIC24 µC
The POWER LED provides a
visual indication that power is on.
A Wall transformer provides 15 to 6V DC unregulated
(unregulated means that voltage can vary significantly depending
on current being drawn). The particular wall Xfmr in the parts kit
provides 6V with a max current of 1000 mA.
The LM2937-3.3 voltage regulator provides a regulated +3.3V.
Voltage will stay stable up to maximum current rating of device.
With writing on device visible, input pin (+9 v) is
left side, middle is ground, right pin is +3.3V
regulated output voltage.
12
Aside: How does an LED work?
3.3V
Anode (long lead)
Power on
LED
470
ohm
Cathode (short lead)
current limiting resistor
A diode will conduct current (turn on) when the anode is at
approximately 0.7V higher than the cathode. A Light
Emitting Diode (LED) emits visible light when conducting
– the brightness is proportional to the current flow. The
voltage drop across LEDs used in the lab is about 2V.
Current = Voltage/Resistance ~ (3.3v – LED voltage drop)/470 
= (3.3v – 2.2V)/470 = 2.7 mA
13
Reset
10K ohm
+3.3V
0.1
+
PIC24 µC
VDD
MCLR#
VSS
10K resistor used to limit current
when reset button is pressed.
When reset button
is pressed, the
MCLR# pin is
brought to ground.
Reset This causes the PIC
Switch program counter to
be reset to 0, so
next instruction
fetched will be from
location 0. All Cs
have a reset line in
order to force the
C to a known
state.
14
The Clock
The PIC24 C has
many options for
generating a clock;
can use an external
crystal or internal
oscillator.
We will use the
internal clock.
Copyright Delmar Cengage Learning 2008. All Rights Reserved.
From: Reese/Bruce/Jones, “Microcontrollers: From Assembly to C with the PIC24 Family”.
V 0.1
15
Internal Fast RC Oscillator + PLL
RC Oscillators
discharge a
capacitor
through a
resistor
PLL
Phased Locked Loop
Our examples use
this! Internal FRC +
PLL configured for
80MHz.
V 0.1
16
Configuration Bits
Configuration bits are stored at special locations in program
memory to control various processor options. Configuration bits
are only read at power up.
Processor options controlled by configuration bits relate to
Oscillator options, Watchdog timer operation, RESET operation,
Interrupts, Code protection, etc.
The file pic24_config.c file included by the sample programs
used in lab specifies configuration bits used for all lab exercises.
We will discuss the meaning of the configuration bit options as
it is necessary.
17
The PC Serial Interface
We use a special USB-to-Serial cable to connect
our board to the PC. This serial interface outputs
3.3 V levels compatible with the PIC24 µC pins
(careful, most USB-to-Serial cables use +/- 9V
levels!!).
The serial interface will be used for ASCII input/output to
PIC24 µC, as well as for downloading new programs via the
Bully Serial Bootloader (winbootldr.exe).
V 0.1
18
ledflash.c
V 0.1
19
Testing your PIC24 System
After you have verified that your hookup provides 3.3 V and turns on the
power LED, the TA will program your PIC24 µC bootloader firmware.
Use to program your PIC24 with the hex file produced by the echo.c
program and verify that it works.
(a) Select correct COM
port, baud rate of
230400, open the COM
port.
(b) Browse to hex file
(c) To program, press the
‘MCLR# and Prgm’
while power is on.
20
After downloading ‘echo.c’
Type letters here and press ‘send’ to test, or type here.
Welcome message
printed by ‘echo.c’ on
reset or power-on.
If pin 6 on serial
connector tied to
MCLR#, then press this
to download a program.
Status messages from
bootloader
V 0.1
21
Reading the PIC24 Datasheets
• You MUST be able to read the PIC24 datasheets and find
information in them.
– The notes and book refer to bits and pieces of what you need to
know, but DO NOT duplicate everything that is contained in the
datasheet.
• The datasheet chapters are broken up into functionality
(I/O Ports, Timer0, USART)
– In each chapters are sections on different capabilities (I/O ports
have a section on each PORT).
• The PIC24 Family reference manual has difference
sections for each major subsystem.
• The component datasheet for the PIC24HJ32GP202 has
summary information, you will need to refer the family
reference manual most often.
22
PIC24 Reset
MCLR# -- external reset button
brings input low causes reset.
RESET# instruction causes
reset.
Power-on causes reset after
voltage stabilizes.
Copyright Delmar Cengage Learning 2008. All Rights Reserved.
From: Reese/Bruce/Jones, “Microcontrollers: From Assembly to C with the PIC24 Family”.
23
What RESET type occurred?
Bits in the RCON special function register tell us what type of reset
occurred.
Copyright Delmar Cengage Learning 2008. All Rights Reserved.
From: Reese/Bruce/Jones, “Microcontrollers: From Assembly to C with the PIC24 Family”.
24
Watchdog Timer
Copyright Delmar Cengage Learning 2008. All Rights Reserved.
From: Reese/Bruce/Jones, “Microcontrollers: From Assembly to C with the PIC24 Family”.
V 0.1
25
WDT Uses
Error Recovery: If the CPU starts a hardware operation to a
peripheral, and waits for a response, can break the CPU from an
infinite wait loop by reseting the CPU if a response does not come
back in a particular time period.
Wake From Sleep Mode: If the CPU has been put in a low power
mode (clock stopped), then can be used to wake the CPU after the
WDT timeout period has elapsed.
V 0.1
26
Power Saving Modes
Sleep: Main clock stopped to CPU and all peripherals. Can be
awoke by the WDT. Use the pwrsav #0 instruction.
Idle: Main clock stopped to CPU but not the peripherals (UART
can still receive data). Can be awoke by the WDT. Use the pwrsav
#1 instruction.
Doze: Main clock to CPU is divided by Doze Prescaler (/2, /4, …
up to /128). Peripheral clocks unaffected, so CPU runs slower, but
peripherals run at full speed – do not have to change baud rate of
the UART.
V 0.1
27
General-purpose I/O
The simplest type of I/O via the PIC24 µC external pins are
parallel I/O (PIO) ports.
A PIC24 µC can have multiple PIO ports named PORTA,
PORTB, PORTC, PORTD, etc. Each is 16-bits, and the number
of PIO pins depends on the particular PIC24 µC and package.
The PIC24HJ32GP202/28 pin package has:
PORTA – bits RA4 through RA0
PORTB – bits RB15 through RB0
These are generically referred to as PORTx.
Each pin on these ports can either be an input or output – the
data direction is controlled by the corresponding bit in the TRISx
registers (‘1’ = input, ‘0’ = output).
The LATx register holds the last value written to PORTx.
V 0.6
28
PORTB Example
Set the upper 8 bits of PORTB to outputs, lower 8 bits to be inputs:
TRISB = 0x00FF;
Drive RB15, RB13 high;
others low:
PORTB = 0xA000;
Test returns true while RB0=0
so loop exited when RB0=1
Wait until input RB0 is high:
while ((PORTB & 0x0001) == 0);
Test returns true while RB3=1
so loop exited when RB3=0
Wait until input RB3 is low:
while ((PORTB & 0x0008) == 1);
V 0.6
29
PORTB Example (cont.)
Individual PORT bits are named as _RB0, _RB1, .._RA0, etc.
so this can be used in C code.
Wait until input RB2 is high:
while (_RB2 == 0);
Wait until input RB3 is low:
while (_RB3 == 1) ;
Test returns true while RB2=0
so loop exited when RB2=1.
Can also be written as:
while (!_RB2);
Test returns true while RB3=1
so loop exited when RB3=0
Can also be written as:
while (_RB3);
V 0.6
30
Switch Input
Vdd
PIC24 µC
10K
RB3
PIC24 µC
RB3
External pullup
When switch is pressed
RB3 reads as ‘0’, else
reads as ‘1’.
don’t do
this!
V 0.6
If pullup not present, then
input would float when
switch is not pressed, and
input value may read as
‘0’ or ‘1’ because of
system noise.
31
PORTx Pin Diagram
External pin shared with
other on-chip modules
TRIS bit controls
tristate control on
output driver
Reading LATx reads last
value written; reading
PORTx reads the actual
pin
V 0.6
32
LATx versus PORTx
Writing LATx is the same as writing PORTx, both writes go to
the latch.
Reading LATx reads the latch output (last value written), while
reading PORTx reads the actual pin value.
PIC24 µC
RB3
Configure RB3 as an open-drain
output, then write a ‘1’ to it.
The physical pin is tied to ground, so
it can never go high.
Reading _RB3 returns a ‘0’, but
reading _LATB3 returns a ‘1’ (the
last value written).
V 0.6
33
LATx versus PORTx (cont)
_LATB0 = 1;
Compiler
bset LATB,#0
bset LATB,#1
_LATB1 = 1;
bitset/bitclr instructions are read/modify/write, in this case, read
LATB, modify contents, write LATB. This works as expected.
_RB0 = 1;
Compiler
bset PORTB,#0
bset PORTB,#1
_RB1 = 1;
bset/bclr instructions are read/modify/write – in this case, read
PORTB, modify its contents, then write PORTB. Because of
pin loading and fast internal clock speeds, the second bset may
not work correctly! (see datasheet explanation). For this reason,
our examples use LATx when writing to a pin.
V 0.6
34
Aside: Tri-State Buffer (TSB)
A tri-state buffer (TSB) has input, output, and outputenable (OE) pins. Output can either be ‘1’, ‘0’ or ‘Z’
(high impedance).
A
OE
Y
A
Y
OE
V 0.6
OE = 0, then switch closed
OE = 1, then switch open
35
Bi-directional, Half-duplex Communication
PIC24 µC
TRIS
driver
enabled
D Q
data bus
driver
disabled
0
1
PIC24 µC
Q D
data bus
D Q
Q D
Q D
D Q
rd_port
PIC24 µC
TRIS
TRIS
rd_port
driver
disabled
driver
enabled
D Q
Q D
0
1
data bus
PIC24 µC
data bus
D Q
Q D
Q D
D Q
rd_port
TRIS
rd_port
V 0.6
36
Schmitt Trigger Input Buffer
Each PIO input has a Schmitt trigger input buffer; this
transforms slowly rising/falling input transitions into sharp
rising/falling transitions internally.
V 0.6
37
PORTx Shared Pin Functions
External pins are shared with other on-chip modules. Just
setting _TRISx = 1 may be not be enough to configure a
PORTx pin as an input, depending on what other modules share
the pin:
RB15 shared with AN9, which is
_PCFG9 = 1;
an analog input to the on-chip
Analog-to-Digital Converter
(ADC). Must disable analog
functionality!
Disables analog function
_TRISB15 = 1;
Configure as input
_PCFG9 = 1;
Disables analog function
_TRISB15 = 0;
Configure as output
V 0.6
38
Analog/Digital Pin versus Digital-only Pin
Pins with shared analog/digital functions have a maximum input
voltage of Vdd + 0.3 V, so 3.6 V
Pins with no analog functions ( “digital-only” pins) are 5 V
tolerant, their maximum input voltage is 5.6 V.
This is handy for receiving digital inputs from 5V parts.
Most PIO pins can only source or sink a maximum 4 mA. You
may damage the output pin if you tie a load that tries to
sink/source more than this current.
V 0.6
39
Internal Weak Pullups
External pins with a CNy pin function have a weak internal
pullup that can be enabled or disabled.
Change notification input; to
enable pullup:
CN11PUE = 1;
To disable pullup:
CN11PUE = 0;
V 0.6
40
Open Drain Outputs
Each PIO pin can be configured as an open drain output, which
means the pullup transistor is disabled.
_ODCxy = 1 enables open drain, _ODCxy = 0 disables open drain
_ODCB15 = 1;
Enables open drain on RB15
V 0.6
41
Port Configuration Macros
For convenience, we supply macros/inline functions that hide pin
configuration details:
CONFIG_RB15_AS_DIG_OUTPUT();
CONFIG_RB15_AS_DIG_INPUT();
These macros are supplied for each port pin. Because these
functions change depending on the particular PIC24 µC, the
include/devices directory has a include file for each PIC24 µC,
and the correct file is included by the include/pic24_ports.h file.
V 0.6
42
LED/Switch IO:
Count number of
press/releases
43