Beruflich Dokumente
Kultur Dokumente
19-Aug 2010
Paranz
PART 1
C Function
Day 1 Afternoon Session
19-Aug 2010
Paranz
C FUNCTION: Basics
#include <pic.h> void delay(void) { unsigned int i; for(i=0;i<60000;i++); return; } void main() { TRISB0 = 0; RB0 = 0; while(1) { RB0 = 1; delay(); RB0 = 0; delay(); } } 19-Aug 2010 //count from 0 to 59999
Ex am ple
#1
A function
Paranz
C FUNCTIONS: Basics
return type
for(i=0;i<60000;i++); return; }
19-Aug 2010 Paranz
function body
function definition
C FUNCTIONS: Basics
C function
a named independent, self-containing block of C code that perform a specific task code in the function body is executed when the function is called/invoke
Why use?
program size is reduced structured programming
19-Aug 2010 Paranz 6
//do nothing
//LED on //call delay function, and pass value 60000 //LED off //call delay function, and pass value 20000
C FUNCTIONS: Parameters
void delay(unsigned int delay_val) { unsigned int i; delay_val = 60000
parameter variable
for(i=0;i<delay_val;i++); }
Parameter list
void main() { ... delay(60000); }
19-Aug 2010
argument
Paranz 8
C FUNCTIONS: Parameters
// a function with several parameters void myfunc1(unsigned int var1, char var2) { .. .. //use var1 and var2 somewhere here .. .. }
19-Aug 2010
Paranz
19-Aug 2010
Paranz
10
Ex am ple
unknown! Compiler does not know what delay() is
#3
19-Aug 2010
Paranz
11
Ex am ple
a function declaration a function definition
#3
19-Aug 2010
Paranz
12
- return type - function name - parameter list - variable data type only void myfunc1(unsigned int var1, char var2) { .. .. .. .. }
19-Aug 2010 Paranz 14
C FUNCTIONS: An Example
Exercise:
create new project in MPLAB
button_led_toggle
Ex am ple
#4
19-Aug 2010
Paranz
15
C FUNCTIONS: An Example
void main() { //Initializations
Ex am ple
#4
while(1) { if( /* Test if button is pressed */ ) { /* Wait until user releases the button. */ /* Do task. */ } } A skeleton code! }
19-Aug 2010
Paranz
16
C FUNCTIONS: An Example
void main() { //Initializations
Ex am ple
#4
while(1) { if( /* Test if button is pressed */ ) { /* Wait until user releases the button. */ LED ^= 1; //Toggle LED1 } } }
19-Aug 2010
Paranz
17
C FUNCTIONS: An Example
void main() { //Initializations non-zero (button is pressed) zero (button not pressed)
Ex am ple
#4
while(1) { if( IsButtonPressed() ) { /* Wait until user releases the button. */ LED ^= 1; } } }
19-Aug 2010
Paranz
18
C FUNCTIONS: An Example
void main() { //Initializations while(1) { if( IsButtonPressed() ) {
Ex am ple
#4
Wait4ButtonRelease();
LED ^= 1; } } }
19-Aug 2010
Paranz
19
C FUNCTIONS: An Example
void main() { //Initializations while(1) { if( IsButtonPressed() ) { Wait4ButtonRelease() ; LED ^= TOGGLE; } } } unsigned char IsButtonPressed(void) { } void Wait4ButtonRelease(void) { }
19-Aug 2010
Paranz
20
C FUNCTIONS: An Example
#include <pic.h> #define LED RB0 unsigned char IsButtonPressed(void); void Wait4ButtonRelease(void); void main() { //Initializations while(1) { if( IsButtonPressed() ){ Wait4ButtonRelease() ; LED ^= 1; } } } unsigned char IsButtonPressed(void) { return 1; } void Wait4ButtonRelease(void) { return; }
19-Aug 2010
Paranz
21
C FUNCTIONS: An Example
unsigned char IsButtonPressed(void) { if(/* Poll if input pin is Logic 0 */) return TRUE; else return FALSE; }
19-Aug 2010
Paranz
22
C FUNCTIONS: An Example
Switch bounce
non-ideal behavior MCU will interpret as
multiple presses by the user
td
Poll if Logic 0
C FUNCTIONS: An Example
unsigned char IsButtonPressed(void) { if(/* Poll if input pin is Logic 0 */) return TRUE; else return FALSE; }
C FUNCTIONS: An Example
unsigned char IsButtonPressed(void) { if(/* Poll if input pin is Logic 0 */) { /* time delay as simple debounce */ if(/* Poll again if input pin is still Logic 0 */) return TRUE; else return FALSE } else return FALSE; }
19-Aug 2010 Paranz 25
C FUNCTIONS: An Example
unsigned char IsButtonPressed(void) { if(BUTTON1==PRESSED) //Poll if button is pressed. { Delay(5000); //Short time delay to debounce. if(BUTTON1==PRESSED)//Poll again if still pressed, // therefore press is valid. return TRUE; //Return 1, meaning true. else return FALSE; //Return 0, meaning false. } else return FALSE; }
19-Aug 2010
Paranz
26
C FUNCTIONS: An Example
#include <pic.h> #define #define #define #define #define LED BUTTON PRESSED TRUE FALSE RB0 RB2 0 1 0
void Delay(unsigned int delay_val); unsigned char IsButtonPressed(void); void Wait4ButtonRelease(void); void main() { //Initializations while(1) { if( IsButtonPressed() ){ Wait4ButtonRelease() ; LED ^= 1; } } } unsigned char IsButtonPressed(void) { if(BUTTON1==PRESSED) //check if button is pressed { Delay(5000); //short time delay to debounce .....
19-Aug 2010
Paranz
27
C FUNCTIONS: An Example
void Wait4ButtonRelease(void) { while(BUTTON1==PRESSED) { //Do nothing. Just loop around. } return; }
C FUNCTIONS: An Example
Exercise:
Toggle an LED when button is pressed Demonstrate structured programming
- Top-Down Approach - Initial design requirements
- Implementation
19-Aug 2010
Paranz
29
C FUNCTIONS: Summary
C FUNCTION
function definition
function header return type, function name, parameter function body
C application program
essentially a collection of functions
main() user-defined functions
19-Aug 2010 Paranz 30
10
PART 2
Modular Programming
19-Aug 2010
Paranz
31
MODULAR PROG.
Modular programming
Divide an application into modules
C module - source (.c) & header (.h) files
Benefits:
Large, complicated C application projects are easy to manage code reuse
19-Aug 2010
Paranz
32
Ex am ple
#2
//LED on //call delay function, and pass value 60000 //LED off //call delay function, and pass value 20000
11
Ex am ple
#5
19-Aug 2010
Paranz
34
locate file in the same directory as the calling file (main.c)
< >
- locate file in default include directory of the compiler
\Program Files\HI-TECH Software\PICC\9.70\include
19-Aug 2010
Paranz
36
12
19-Aug 2010
Paranz
37
modular programming
should be #include delay.h
19-Aug 2010
Paranz
38
Ex am ple
#6
//do nothing
19-Aug 2010
Paranz
39
13
Ex am ple
__CONFIG(HS & WDTDIS & PWRTDIS & UNPROTECT & LVPDIS); void main() { TRISB0 = 0; RB0 = 0; while(1) { RB0 = 1; Delay(60000); RB0 = 0; Delay(30000); } }
19-Aug 2010 Paranz
#6
40
19-Aug 2010
Paranz
41
preprocessor (cpp.exe) parser (p1.exe) code generator (cgpic.exe) assembler (aspic.exe) linker (hlink.exe) objtohex (objtohex.exe)
Paranz 42
14
delay.c
cpp.exe
p1.exe
cgpic.exe
main.as delay.as blinker.obj
delay.h
main.obj delay.obj
blinker project
aspic.exe
hlink.exe
objtohex.exe
blinker.hex
19-Aug 2010 Paranz 43
preprocessor
main.obj
delay.obj
linker
Linker will reconcile addresses of code objects between modules
blinker.obj
19-Aug 2010 Paranz 45
15
code reuse
reuse .c and .h files in next project, saves time and effort use .c and .h files created by other individuals
19-Aug 2010 Paranz 46
e#7
Use delay.c and delay.h that comes with the HI-TECH compiler Create new project
copy delay.h & delay.c from the directory:
\Program Files\HI-TECH Software\PICC\9.70\samples\LCDemo
19-Aug 2010
Paranz
47
Ex am ple
#7
48
16
Ex am ple
#7
#define DelayUs(x) { unsigned char _dcnt; \ _dcnt = (x)*((XTAL_FREQ)/(12MHZ)); \ ... modify to match application ... ...
19-Aug 2010
Paranz
49
le# 8
Use delay.c and delay.h that comes with the HI-TECH compiler Toggle LED1 and LED2 alternately every second
RB0, RB1
Use #defines to improve readability Use bitwise operators, mask values, etc
19-Aug 2010
Paranz
50
e#9
19-Aug 2010
Paranz
51
17
Ex am ple
#10
52
Character LCD
2x16, 1x16, 4x20 character LCDs uses the HD44780 controller (Hitachi) 14 pin no LED backlight 16 pin with LED backlight
19-Aug 2010
Paranz
53
16
19-Aug 2010
Paranz
54
18
19-Aug 2010
Paranz
55
19-Aug 2010
Paranz
56
Ex am ple
#11
19-Aug 2010
Paranz
57
19
//Initialize the LCD. //Clear the LCD display. //Display text on first line. //Place cursor in this position //Display text on 2nd line.
19-Aug 2010
Paranz
58
4x3 Keypad
input device
19-Aug 2010
Paranz
59
4x3 Keypad
consists of 12 buttons arranged in a matrix
saves 5 I/O pins
4 rows 3 columns
19-Aug 2010
Paranz
60
20
4x3 Keypad
PIC16F877A + 4x3 Keypad
19-Aug 2010
Paranz
61
4x3 Keypad
Requires 7 I/0 pins
4 output pins ROW<3:0> 3 input pins COLUMN<2:0>
require 3 pull-up resistors
19-Aug 2010
Paranz
62
4x3 Keypad
Scanning Routine
1 0 1 1 1
19-Aug 2010 Paranz 63
21
4x3 Keypad
Scanning Routine
1 1 0 1 1
19-Aug 2010 Paranz 64
4x3 Keypad
Scanning Routine
1 1 1 0 1
19-Aug 2010 Paranz 65
4x3 Keypad
Scanning Routine
1 1 1 1 0
19-Aug 2010 Paranz 66
22
4x3 Keypad
Scanning Routine
1 0 0 0 0
19-Aug 2010 Paranz 67
1 0
pressed!
4x3 Keypad
Scanning Routine
1 0 1 1 1
19-Aug 2010 Paranz 68
pressed!
4x3 Keypad
Scanning Routine
1 1 0 1 1
19-Aug 2010 Paranz 69
pressed!
23
4x3 Keypad
Scanning Routine
101 1 1 1 0 ROW2 1
19-Aug 2010 Paranz 70
1 0
pressed!
4x3 Keypad
EXERCISE
PORTD
PORTD<3:0> PORTD<6:4> ROW<3:0> COLUMN<2:0>
Ex am ple
#11
4 LEDS
display numbers when a corresponding key is pressed (PORTB<3:0>)
4x3 Keypad
void main() { //Initializations
Ex am ple
while(1) { if ( /*Check if any column is Logic 0, a keypress!*/ ) { /* Start keypad scanning to determine row# and column bit patterns */ /* Convert row# & column bit pattern to equivalent key */ /* Then do stuffs, according to determined keypress. */ } } 19-Aug 2010 Paranz
#12
72
24
4x3 Keypad
void main() { KeypadInit();
Ex am ple
while(1) { if ( KeypadIsKeyPress() ) { /* Start keypad scanning to determine row# and column bit patterns */ /* Convert row# & column bit pattern to equivalent key */ /* Then do stuffs, according to determined keypress. */ } } 19-Aug 2010 Paranz
#12
73
4x3 Keypad
//Place in keypad.c void KeypadInit(void) { TRISD = 0b01110000; PORTD = 0b00001111; return; }
Ex am ple
#12
19-Aug 2010
Paranz
74
4x3 Keypad
//Place in keypad.c
Ex am ple
unsigned char KeypadIsKeyPress(void) { PORTD &= 0b11110000; //All rows are Logic 0 if((PORTD & 0b01110000)!=0b01110000) return TRUE; //A key was pressed. else return FALSE; //No key press detected }
#12
19-Aug 2010
Paranz
75
25
4x3 Keypad
//Place in keypad.h //#defines #define TRUE #define FALSE 1 0
Ex am ple
#12
19-Aug 2010
Paranz
76
4x3 Keypad
//keypad.c #include keypad.h void KeypadInit(void) { TRISD = 0b01110000; PORTD = 0b00001111; return; }
Ex am ple
#12
unsigned char KeypadIsKeyPress(void) { PORTD &= 0b11110000; //All rows are Logic 0 if((PORTD & 0b01110000)!=0b01110000) return TRUE; //A key was pressed. else return FALSE; }
19-Aug 2010 Paranz 77
4x3 Keypad
void main() { KeypadInit();
Ex am ple
while(1) { if ( KeypadIsKeyPress() ) { /* Start keypad scanning to determine row# and column bit patterns */ /* Convert row# & column bit pattern to equivalent key */ /* Then do stuffs, according to determined keypress. */ } } 19-Aug 2010 Paranz
#12
78
26
4x3 Keypad
void main() { unsigned char keypad_bit_pattern = 0x00; KeypadInit();
Ex am ple
#12
while(1) { if ( KeypadIsKeyPress() ) { keypad_bit_pattern = KeypadRead(); /* Convert row# & column bit pattern to equivalent key */ /* Then do stuffs, according to determined keypress. */ } }
19-Aug 2010
Paranz
79
4x3 Keypad
row variable
0,1,2,3
Ke
column bits
y 7
w as p
res sed !
0
Paranz
0
80
4x3 Keypad
R0W0 keys Key 1 Key 2 Key 3 ROW1 keys Key 4 Key 5 Key 6 ROW2 keys Key 7 Key 8 Key 9 ROW3 keys Key * Key 0 Key # 19-Aug 2010
01100000 01010000 00110000 01100001 01010001 00110001 01100010 01010010 00110010 01100011 01010011 00110011
(0x60) (0x50) (0x30) (0x61) (0x51) (0x31) (0x62) (0x52) (0x32) (0x63) (0x53) (0x33)
Paranz 81
27
4x3 Keypad
void main() { unsigned char keypad_bit_pattern = 0x00; KeypadInit();
Ex am ple
#12
key_ascii = 1,2,.6,*,0,#
while(1) { if ( KeypadIsKeyPress() ) { keypad_bit_pattern = KeypadRead(); key_ascii = KeypadGetKeyAscii(keypad_bit_pattern); /* Then do stuffs, according to determined keypress. */ } } }
19-Aug 2010 Paranz 82
4x3 Keypad
void main() { unsigned char key_bit_pattern = 0x00; unsigned char key_ascii = 0x00; TRISB &= ~0x0F; PORTB &= ~0x0F; KeypadInit();
Ex am ple
#12
while(1) { if ( KeypadIsKeyPress() ) { key_bit_pattern = KeypadRead(); key_ascii = KeypadGetKeyAscii(keypad_bit_pattern); if(key_ascii == '1') PORTB = 0b00000001; else if (key_ascii == '2') PORTB = 0b00000010; } 19-Aug 2010 Paranz 83 }
4x3 Keypad
unsigned char KeypadGetKeyAscii(unsigned char key_bit_pattern) { switch(key_bit_pattern) { case KEY1: return '1'; case KEY2: return '2'; case KEY3: return '3'; case KEY4: return '4'; case KEY5: return '5'; case KEY6: return '6'; case KEY7: return '7'; case KEY8: return '8'; case KEY9: return '9'; case KEYSTAR: return '*'; case KEY0: return '0'; case KEYHASH: return '#'; } return NULL; }
Ex am ple
#12
19-Aug 2010
Paranz
84
28
4x3 Keypad
#define #define #define #define #define #define #define #define #define #define #define #define #define #define TRUE 1 FALSE 0 KEY1 0x60 KEY2 0x50 KEY3 0x30 KEY4 0x61 KEY5 0x51 KEY6 0x31 KEY7 0x62 KEY8 0x52 KEY9 0x32 KEYSTAR KEY0 0x53 KEYHASH
Ex am ple
keypad.h
#12
0x63 0x33
void KeypadInit(void); unsigned char KeypadRead(void); unsigned char KeypadGetKeyAscii(unsigned char key_bit_pattern); unsigned char KeypadIsKeyPress(void);
19-Aug 2010 Paranz 85
4x3 Keypad
unsigned char KeypadRead(void) { if ( key1 = KeypadScan() ) { DelayMs(10); key2 = KeypadScan(); while(KeypadScan()); if (key1==key2) return key1; else return NULL; } else return NULL; } //If no key, return 0
Ex am ple
#12
//Time delay for key debounce. //Read again. //Wait until button is released. //If both readings are equal, a valid //keypress was detected, return key. //Else, not a valid key, return 0.
19-Aug 2010
Paranz
86
4x3 Keypad
static unsigned char KeypadScan(void) { unsigned char column_bits = 0x00; unsigned char current_row;
Ex am ple
#12
for(current_row=0;current_row < 4;current_row++) { PORTD = ~(1 << current_row); //Current row pin is low, // other rows are high. DelayUs(50); //Short time delay to // make signal stable. //Read column bit pattern, PORTx<6:4> column_bits = PORTD & 0b01110000; if (column_bits != 0b01110000) { return (column_bits | current_row); } } return NULL; } 19-Aug 2010 Paranz 87 //No key detected.
29
Keypad.c functions
void KeypadInit(void) unsigned char KeypadRead(void) unsigned char KeypadGetKeyAscii(unsigned char key_bit_pattern) unsigned char KeypadIsKeyPress(void) static unsigned char KeypadScan(void)
19-Aug 2010
Paranz
88
30