Date post: | 24-Dec-2015 |
Category: |
Documents |
Upload: | gagah-prakoso |
View: | 23 times |
Download: | 1 times |
1
ECE 3730 Principles of Embedded Systems:
Display Devices
Interfacing Display Devices to Embedded Microcontrollers
2
Single LED Interface
• Direct connection to a port pin
• Typical current required to switch LED on is about 1-5 mA.
• Typical maximum current, which must not be exceeded is about 90 mA.
• Note: R can control the brightness of the LED
R I LED VIR 025
kmA
VR 1
3
25
25 mA
Maximum
3
PIC16F877A Electrical Specifications
• Page 173 of PIC16F87XA Data Sheet:
25 mA
4
7 Segment Display Devices Example: LTD-4608JR (dual seven-segment display)
1 2 3 4 5
10 9 8 7 6
a
b
c
d
f
e
g
Most Significant Digit
(MSD)
Least Significant Digit
(LSD)
Common Cathode
5
EXAMPLE CONNECTION OF LTD-4608JR TO PIC16F877A
6
7-Segment Display Test Circuit Diagram
PIC16F877A
40 39 38 37 36 35 34 33 32 31 30 29 28 27 26 25 24 23 22 21
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
RJ-12
Programming Clock
Programming Data
Master Clear
VDD (5 V)
VSS (GND)
10 kΩ 3.3 kΩ 33 pF
VDD (5 V)
VSS (GND)
10 μF
1 2 3 4 5
10 9 8 7 6
1 kΩ
1 kΩ
RE0 RE1
RE2
RE0 RE2
RE1
RD0 RD1
RD3 RD2
RD2
RD5 RD4 RD6
RD3
RD4
RD5
RD6
7
Port D and Port E Configuration
• Port D configured as output to connect to the 7-Segment Display outputs A, B, C, D, E, F, G, and DP.
• Port E bit-0 (RE0) configured as output to connect to the 7-Segment Display Most Significant Digit (MSD) driver
• Port E bit 1 (RE1) configured as output to connect to the 7-Segment Display Least Significant Digit (LSD) driver
8
C Code for Configuring Port D and Port E
TRISD = 0b00000000; // Output for 7-segments
TRISE0 = 0; // Output for MSD Driver
TRISE1 = 0; // Output for LSD Driver
TRISE2 = 0; // Output for decimal point
• The names TRISD, TRISE1, etc are the standard names for the
PIC16F877A
• The name and type is declared in file pic16f877a.h
// Register: TRISD
volatile unsigned char TRISD @ 0x088;
9
7 Segment Decoder
# A B G F D E C
RD6 RD5 RD4 RD3 RD2 RD1 RD0
0 1 0 0 1 0 0 0 0
1 1 1 0 1 1 1 1 0
2 1 0 0 0 1 0 0 1
3 1 0 0 0 1 0 1 0
4 1 1 0 0 0 1 1 0
5 1 0 1 0 0 0 1 0
6 1 0 1 0 0 0 0 0
7 1 0 0 1 1 1 1 0
8 1 0 0 0 0 0 0 0
9 1 0 0 0 0 0 1 0 1 2 3 4 5
10 9 8 7 6
A
B
C
D
F
E
G
10
C Code for 7 Segment Decoder Array
// Declaration for 7 segment decoder array
unsigned char sevenSegmentLookUp[10];
sevenSegmentLookUp[0] = 0b10010000; // '0'.
sevenSegmentLookUp[1] = 0b11011110; // '1'.
sevenSegmentLookUp[2] = 0b10001001; // '2'.
sevenSegmentLookUp[3] = 0b10001010; // '3'.
sevenSegmentLookUp[4] = 0b11000110; // '4'.
sevenSegmentLookUp[5] = 0b10100010; // '5'.
sevenSegmentLookUp[6] = 0b10100000; // '6'.
sevenSegmentLookUp[7] = 0b10011110; // '7'.
sevenSegmentLookUp[8] = 0b10000000; // '8'.
sevenSegmentLookUp[9] = 0b10000010; // '9'.
# A B G F D E C
RD6 RD5 RD4 RD3 RD2 RD1 RD0
0 1 0 0 1 0 0 0 0
1 1 1 0 1 1 1 1 0
2 1 0 0 0 1 0 0 1
3 1 0 0 0 1 0 1 0
4 1 1 0 0 0 1 1 0
5 1 0 1 0 0 0 1 0
6 1 0 1 0 0 0 0 0
7 1 0 0 1 1 1 1 0
8 1 0 0 0 0 0 0 0
9 1 0 0 0 0 0 1 0
11
7-Segment Display Test Plan
• Send a counter value to the 7-segment display continuously
• Increment the counter as follows 0, 1, …, 99, 0, 1, …
• LEDs must be continuously driven for the light to show
• Human eye cannot detect short changes
• To display a 2-digit number: • MSD off LSD on
MSD on LSD off
MSD off LSD on , …
12
Main Loop Flow Chart
value = 0 get the LSD and MSD of value
Get sevenSegmentLookUp[LSD] and write to PORTD
MSD Driver off, LSD Driver on
Get sevenSegmentLookUp[MSD] and write to PORTD
MSD Driver on, LSD Driver off
value = value + 1 value
== 99
?
value = 0 N Y
00
01
01
…
09
10
11
…
98
99
00
01
…
MSD LSD
13
C Code for the Main loop value = 0;
while (1) { // 1 = true, means loop forever
for(i = 0; i < 1000; i++) {// Display "value" for about 1s
// Set the 7-segment lines on PORTD to match LSD of value:
PORTD = sevenSegmentLookUp[value%10];
RE0 = 0; // Turn off MSD
RE1 = 1; // Turn on LSD
// Set the 7-segment lines on PORTD to match MSD of value
PORTD = sevenSegmentLookUp[value/10];
RE0 = 1; // Turn on MSD
RE1 = 0; // Turn off LSD
}
if(value == 99){
value = 0;
}
else {
value++;
}
} //end of while (1)
} // end of main() function.
14
Modulo Operator n mod m (C syntax is: n % m)
• Given two positive numbers, n and m, n mod m is the remainder that results after the division of n by m.
• The division of n by m yields an integer part and a remainder part
• Example: 37%3 = 1, because 37÷3 = 12 with remainder 1
• Special case: when m is the base of the number system, then n % m will yield the value of the least significant digit
n % m = LSD(n), when m = base of number system
15
Integer Division Operator n / m
• Given two positive numbers, n and m, n / m is the integer that results after the division of n by m.
• The division of n by m yields an integer part and a remainder part
• Example: 37 / 3 = 12, because 37÷3 = 12 remainder 1
• Special case: when m is the base of the number system, then n / m will remove the least significant digit
16
Example: Integer Division and Modulus Operators
7
7 % 10 = 7
7 / 10 = 0
34
34 % 10 = 4
34 / 10 = 3
50
50 % 10 = 0
50 / 10 = 5
99
99 % 10 = 9
99 / 10 = 9
17
Complete MPLAB Project #include <xc.h> // Insert file xc.h here. This file contains PIC register definitions
#pragma config BOREN = OFF, CPD = OFF, DEBUG = ON, WRT = OFF, FOSC = EXTRC, WDTE = OFF, CP = OFF, LVP = OFF, PWRTE = OFF
void main(void)
{
unsigned char value;
unsigned char sevenSegmentLookUp[10]; // 7 segment decoder
unsigned int i;
PCFG3 = 0; // Configure all port pins as digital I/O.
PCFG2 = 1;
PCFG1 = 1;
TRISD = 0b00000000; // Configure PORTD as output for the A-F segments
TRISE2 = 0; // Configure PORTE2 as output for the decimal point (dp) segment
TRISE0 = 0; // Configure PORTE0 as output to drive the MSD
TRISE1 = 0; // Configure PORTE1 as output to drive the LSD
sevenSegmentLookUp[0] = 0b10010000; // 7 Segment code for '0'
sevenSegmentLookUp[1] = 0b11011110; // 7 Segment code for '1'
sevenSegmentLookUp[2] = 0b10001001; // 7 Segment code for '2'
sevenSegmentLookUp[3] = 0b10001010; // 7 Segment code for '3'
sevenSegmentLookUp[4] = 0b11000110; // 7 Segment code for '4'
sevenSegmentLookUp[5] = 0b10100010; // 7 Segment code for '5'
sevenSegmentLookUp[6] = 0b10100000; // 7 Segment code for '6'
sevenSegmentLookUp[7] = 0b10011110; // 7 Segment code for '7'
sevenSegmentLookUp[8] = 0b10000000; // 7 Segment code for '8'
sevenSegmentLookUp[9] = 0b10000010; // 7 Segment code for '9'
18
Complete MPLAB Project (Cont’d) RE2 = 1; // Switch decimal point off
value = 0;
while (1) { // Loop forever
for(i = 0; i < 1000; i++) {// Display "value" for about 1s
// Set the 7-segment lines on PORTD to match LSD of value
PORTD = sevenSegmentLookUp[value%10];
RE0 = 0; // Turn off MSD
RE1 = 1; // Turn on LSD
// Set the 7-segment lines on PORTD to match MSD of value
PORTD = sevenSegmentLookUp[value/10];
RE0 = 1; // Turn on MSD
RE1 = 0; // Turn off LSD
}
if(value == 99){
value = 0;
}
else {
value++;
}
} //end of while (1)
} // end of main
19
Project Modularization
• A project can be made more modular
• Easier to maintain
• Easier to read and debug
• Easier to manage
• Encapsulate similar items into their own file
• C files that do certain function and that function only
• Include files (*.h) files that contain definitions (or code)
20
Example of a Modular MPLAB Project
• Project split into 6 files:
• MainFunctionPrototypes.h
• ProcessorConfiguration.h
• SevenSegmentDefinitions.h
• Main.c
• PortModule.c
• SevenSegment.c
21
Main.c #include "ProcessorConfiguration.h"
#include "MainFunctionPrototypes.h" //Needed b/c it calls 3 functions.
void main(void) {
unsigned char value;
unsigned int i;
portInit();
sevenSegmentInit();
value = 0;
while (1) { // Loop forever.
for (i = 0; i < 1000; i++) {// Display "value" for about 1 s
sevenSegmentDisplay(value);
}
if (value == 99) {
value = 0;
}
else {
value++;
}
} //end of while (1)
} // end of main.
22
Main.c Notes
• At most one file in a project must contain the configuration bits settings:
#include "ProcessorConfiguration.h”
• Must include the signature of each function main() calls: portInit(),
sevenSegmentInit(), and sevenSegmentDisplay():
#include "MainFunctionPrototypes.h“
• Notice that main() does not interact with the port or the seven segment display device directly; it invokes functions within files whose responsibility it is to interface with the port or the segment device directly.
23
ProcessorConfiguration.h #pragma config BOREN = OFF, CPD = OFF, DEBUG = ON, WRT = OFF, FOSC =
EXTRC, WDTE = OFF, CP = OFF, LVP = OFF, PWRTE = OFF
24
MainFunctionPrototypes.h extern void sevenSegmentDisplay(unsigned char);
extern void portInit(void);
extern void sevenSegmentInit();
25
MainFunctionPrototypes.h Notes
• The file contains:
extern void sevenSegmentDisplay(unsigned char);
extern void portInit(void);
extern void sevenSegmentInit();
• These define the signature of each function that main() calls.
• For example, the signature of sevenSegmentInit() is that it returns nothing (void) and it has an unsigned char parameter.
• The extern keyword tells the compiler that the item is defined in an external file.
26
PortModule.c #include <xc.h>
void portInit(void) {
PCFG3 = 0; // Configure all Port pins for digital I/O.
PCFG2 = 1;
PCFG1 = 1;
TRISD = 0b00000000; // Output for seven segments
TRISE0 = 0; // MSD driver
TRISE1 = 0; // LSD driver
TRISE2 = 0; // Decimal point segment
}
27
PortModule.c Notes
• The file xc.h contains the definitions of the variables PortModule.cd uses: PCFG3, PCFG2, PCFG1, TRISD, TRISE0, TRISE1, and TRISE2.
#include <xc.h>
void portInit(void) {
PCFG3 = 0; // Configure all Port pins for digital I/O.
PCFG2 = 1;
PCFG1 = 1;
TRISD = 0b00000000; // Output for seven segments
TRISE0 = 0; // MSD driver
TRISE1 = 0; // LSD driver
TRISE2 = 0; // Decimal point segment
}
28
SevenSegment.c #include <xc.h>
#include "SevenSegmentDefinitions.h"
unsigned char sevenSegmentLookUp[10]; // 7 segment decoder
void sevenSegmentInit() {
sevenSegmentLookUp[0] = 0b10010000; // 7 Segment code for '0'
sevenSegmentLookUp[1] = 0b11011110; // 7 Segment code for '1'
sevenSegmentLookUp[2] = 0b10001001; // 7 Segment code for '2'
sevenSegmentLookUp[3] = 0b10001010; // 7 Segment code for '3'
sevenSegmentLookUp[4] = 0b11000110; // 7 Segment code for '4'
sevenSegmentLookUp[5] = 0b10100010; // 7 Segment code for '5'
sevenSegmentLookUp[6] = 0b10100000; // 7 Segment code for '6'
sevenSegmentLookUp[7] = 0b10011110; // 7 Segment code for '7'
sevenSegmentLookUp[8] = 0b10000000; // 7 Segment code for '8'
sevenSegmentLookUp[9] = 0b10000010; // 7 Segment code for '9'
sevenSegment = sevenSegmentLookUp[0]; // Set both digits to zero.
leftDigit = DIGIT_ON; // Turn on the MSD.
rightDigit = DIGIT_ON; // Turn on the LSD.
DP = DP_OFF; // Switch decimal point off
}
29
SevenSegment.c (Continued) void sevenSegmentDisplay(unsigned char value) {
sevenSegment = sevenSegmentLookUp[value%10]; //Display LSD.
leftDigit = DIGIT_OFF; // Turn off the MSD
rightDigit = DIGIT_ON; // Turn on the LSD
sevenSegment = sevenSegmentLookUp[value/10]; // Display MSD.
rightDigit = DIGIT_OFF; // Turn off the MSD
leftDigit = DIGIT_ON; // Turn on the LSD
}
30
SevenSegment.c Notes
• Note that although SevenSegment.c does not refer to the names of the PIC registers directly, it still needs to include the file xc.h, because the variables leftDigit, rightDigit, and sevenSegment, are defined as RE0, RE1, RE2, and PORTD in the SevenSegmentDefineitions.h file:
#define leftDigit RE0
#define rightDigit RE1
#define sevenSegment PORTD
#define DP RE2
31
SevenSegmentDefinitions.h #define DIGIT_ON 1
#define DIGIT_OFF 0
#define leftDigit RE0
#define rightDigit RE1
#define sevenSegment PORTD
#define DP RE2
#define DP_ON 0
#define DP_OFF 1
32
XC8 Integer Data types