ECE 3567 Microcontrollers Lab Lecture 2 The Microcontroller
ECE 3567 Microcontrollers Lab Lecture #2 – The Microcontroller & Embedded C Programming Autumn 2019 Dr. Gregg Chapman 1
Numbering
The Hexadecimal Number System.
Hexadecimal Values of Bit Positions (Used to read or write register values) Bit 7 Bit 6 Bit 5 Bit 4 Bit 3 Bit 2 Bit 1 Bit 0 1 1 0 0 0 0 x. C 0 0 0 0 1 1 0 x 03 1 1 0 0 0 1 1 1 0 x. C 7 0 0 1 1 0 x 0 F 1 1 0 0 0 x. F 0 0 0 0 0 x 00 0 1 0 1 0 x 55 1 0 1 0 0 x. AA 1 1 1 1 0 x. FF
Registers – Bit numbering WE USE: 7 6 5 4 3 2 1 0
Hexadecimal Values of Bit Positions Don’t get Bit by Bit Numbering Bit 7 Bit 6 Bit 5 Bit 4 Bit 3 Bit 2 Bit 1 Bit 0 0 0 0 1 0 x 01 0 0 0 1 0 0 x 02 0 0 0 1 0 0 0 x 04 0 0 1 0 0 x 08 0 0 0 1 0 0 0 x 10 0 0 1 0 0 0 x 20 0 1 0 0 0 0 x 40 1 0 0 0 0 x 80
Register Terminology • Note that each 4 -bit nibble can be converted to a single Hexadecimal character. • Register contents are always expressed in hexadecimal values.
Registers 0000 0100 1110 0000 0 x 0 , or 0 h 0 x 4 , or 4 h 0 x. E , or Eh 0 x 0 , or 0 h • Example of 4 -bit binary values converted to a single Hexadecimal character. This 16 -bit register value would be shown as: 0 x 04 E 0
Data Types C Programming Language ! ! X X X
Data Types Processor Dependent!! MSP 430 Series Microcontrollers ! !
Variable Declaration Modifiers • • const – single value at runtime and cannot be altered volatile – value can be altered anywhere in code (global) extern – declaration is in another file, but can be used in current file static – value can be altered only within the current file Examples: volatile unsigned int delay; extern volatile unsigned char i, j, k; static int counter; const int x = 123;
Constant Declarations There are “constant” variables: const int x = 0 x 1234; Constant numbers are usually defined with the compiler directive: #define RED 0 x 11
C Operations (for reference)
C Operations
C Operations
C Operations MOST Important Operators in Embedded C Programming ! Used to CLEAR Bits Used to TOGGLE Bits Used to SET Bits Used to INVERT ALL Bits
HOW TO SET A BIT IN A REGISTER In C programming, the | character is a BITWISE OR NOTE THAT: 0|0=0 0|1=1 1|0=1 1|1=1 By BITWISE ORing a register with 1 s in the bits you want to SET, and 0 s in the bits that you want to preserve, YOU ONLY SET THE BITS AT LOCATIONS WHERE THERE A ONES IN THE BYTE USED TO OPERATE ON THE REGISTER
HOW TO SET A BIT IN A REGISTER EXAMPLE 1: RESIGTER is: REGISTER |= 0 x 10; 0000 SET Bit 4 0 x 10 = 0001 0000 (0000) | (0001 0000) = (0001 0000) You have SET Bit 4
HOW TO SET A BIT IN A REGISTER EXAMPLE 2: RESIGTER is: REGISTER |= 0 x 04; 1010 SET Bit 2 0 x 04 = 0000 0100 (1010) | (0000 0100) = (1010 1110) You have SET Bit 2
HOW TO SET A BIT IN A REGISTER EXAMPLE 3: RESIGTER is: REGISTER |= 0 x 80; ? ? ? ? SET Bit 7 0 x 80 = 1000 0000 (? ? ? ? ) | (1000 0000) = (1? ? ? ? ) You have insured that Bit 7 is SET regardless of the other bit values.
HOW TO SET A BIT IN A REGISTER EXAMPLE 4: RESIGTER is: REGISTER |= 0 x 03; 1111 0000 SET Bits 0 and 1 0 x 03 = 0000 0011 (1111 0000) | (0000 0011) = (1111 0011) You have SET bits 0 and 1.
HOW TO CLEAR A BIT IN A REGISTER In C programming, the & character is a BITWISE AND NOTE THAT: 0&1=0 1&1 =1 By BITWISE ANDing a register with 1 s in the bits you want to preserve, and 0 s in the bits that you want to clear, YOU ONLY CLEAR THE BITS AT LOCATIONS WHERE THERE A ZEROS IN THE BYTE USED TO OPERATE ON THE REGISTER
HOW TO CLEAR A BIT IN A REGISTER EXAMPLE 1: RESIGTER is: REGISTER &= 0 x. EF; 1111 Clear Bit 4 0 x. EF = 1110 1111 (1111) & (1110 1111) = (1110 1111) You have CLEARED Bit 4
HOW TO CLEAR A BIT IN A REGISTER EXAMPLE 2: RESIGTER is: REGISTER &= 0 x. F 7; 1010 Clear Bit 3 0 x. F 7 = 1111 0111 (1010) & (1111 0111) = (1010 0010) You have CLEARED Bit 3
HOW TO CLEAR A BIT IN A REGISTER EXAMPLE 3: RESIGTER is: REGISTER &= 0 x. FE; 0000 Clear Bit 0 0 x. FE = 1111 1110 (0000) & (1111 1110) = (0000) You have insured that Bit 0 is cleared
HOW TO CLEAR A BIT IN A REGISTER EXAMPLE 4: RESIGTER is: REGISTER &= 0 x 7 F; ? ? ? ? Clear Bit 7 0 x 7 F = 0111 1111 (? ? ? ? ) & (0111 1111) = (0? ? ? ? ) You have insured that bit 7 is cleared, regardless of the other bit values
HOW TO CLEAR A BIT IN A REGISTER EXAMPLE 5: RESIGTER is: REGISTER &= 0 x 9 F; 1111 0000 Clear Bits 6 and 5 0 x 9 F = 1001 1111 (1111 0000) & (1001 1111) = (1001 0000) You have cleared Bits 6 and 5
HOW TO CLEAR A BIT IN A REGISTER EXAMPLE 6: Alternate Notation: RESIGTER is: 1111 0000 REGISTER &= ~(BIT 6 & BIT 5); Clear Bits 6 and 5 (BIT 6 & BIT 5) = (0100 0000) & (0010 0000) = 0110 0000 ~(BIT 6 and BIT 5) = 1001 1111 (1111 0000) & (1001 1111) = (1001 0000) You have cleared bits 6 and 5
TI Method of Setting BIT Fields of Different Sizes DEFINES THE FIRST BIT OF THE FIELD TO BE USED 2*0 x 1000 u STEPS: 1. Convert this number to BINARY 2. Place the number in the register with the Least Significant Bit of the field defined by this value (See Table) EXAMPLES: 0010 0000 9*0 x 0020 u: 0000 0001 0010 0000 7*0 x 2000 u: 1110 0000 3*0 x 0040 u: 0000 1100 0000 #define BIT 1 #define BIT 2 #define BIT 3 #define BIT 4 #define BIT 5 #define BIT 6 #define BIT 7 #define BIT 8 #define BIT 9 #define BIT 10 #define BIT 11 #define BIT 12 #define BIT 13 #define BIT 14 #define BIT 15 (0 x 0001) (0 x 0002) (0 x 0004) (0 x 0008) (0 x 0010) (0 x 0020) (0 x 0040) (0 x 0080) (0 x 0100) (0 x 0200) (0 x 0400) (0 x 0800) (0 x 1000) (0 x 2000) (0 x 4000) (0 x 8000)
Other Ways to Express the Bit Patterns 0000 1000 = 0 x 08 = BIT 3 1111 0111 = 0 x. F 7 = ~0 x 08 = ~BIT 3 Because a #included header file msp 430 fr 6989. h contains: This is HEX not Binary #define BIT 0 (0 x 0001) #define BIT 1 (0 x 0002) #define BIT 2 (0 x 0004) #define BIT 3 (0 x 0008) #define BIT 4 (0 x 0010) #define BIT 5 (0 x 0020) #define BIT 6 (0 x 0040) #define BIT 7 (0 x 0080) #define BIT 8 (0 x 0100) #define BIT 9 (0 x 0200) #define BITA (0 x 0400) #define BITB (0 x 0800) #define BITC (0 x 1000) #define BITD (0 x 2000) #define BITE (0 x 4000) #define BITF (0 x 8000) NOTE: msp 430 fr 6989. h is #included in driverlib. h
Toggling Bits Compliment Bit 0 of register P 1 OUT ^= BIT 0; // P 1 OUT XOR 0 x 0001 inverts BIT 0 only a 0 0 1 1 b 0 1 XOR 0 1 1 0 (NOTE: This is the Bitwise Exclusive OR operator: A ZERO retains the bit value of all the positions that are zero. A ONE INVERTS the positions that are 1. Since BIT 0 is #defined as 0 x 0001 it is the only bit complimented. Pretty Cool (not to mention useful). 31
Programming
Compiler Directives (from Lecture #1) • • • #include – append contents of the external file #define – text substitution for a constant, can assign a numeric value #pragma – directs compiler to ignore multiple declarations of the same entity #ifdef – begin conditional compilation, paired with #endif #ifndef – define only if it hasn’t already been defined #typedef – defines an alias name or new type
Function Prototypes void funct 1(); void funct 1(void); void funct 2(unsigned int); unsigned int funct 3(void); unsigned int funct 4(char); unsigned int funct 5(char, unsigned int); NOTE: I put all function prototypes in a separate header file called 3567. h
Functions Called by Value
Functions Called by Reference 2
Local Variables • Declared inside functions • Are not preserved when the execution returns form the function unless returned. void delay_cycles(unsigned int x) { unsigned int a; a = x; while (a >= 0) { a--; } return; }
Function with Local Variables NOTE: You can return a local variable if the function prototype has a returned parameter
Loops in Embedded C Use while loops if possible FOR LOOP WHILE LOOP Also a do-while which tests at end. Not used much.
if-else or switch ?
if-else or switch ? • Use switch statements, for more than 3 conditions AND the values are constants. The cross-compiler will make a jump table (which is way more efficient than multiple tests). • Use if-else if the cases are Boolean or logical expressions. • In general, most cross-compilers are more efficient with switch. • switch is much more readable (easy to understand), IMHO • For a low number of cases, the difference is negligible.
How to handle external delays of unknown duration NEVER just wait: (assumes no Watchdog Timer) TAOCTL 0 |+= CCIE; // Enable process while(CCIF == 0); // CODE HANGS HERE if no event Value = TAOR; // Read Result
How to handle external delays of unknown duration Method 1: Rely on a Watchdog Timeout TAOCTL 0 |+= CCIE; // Enable process WDTCTL = WDTPW+WDTCNTCL; //Refresh the Watchdog timer while(CCIF == 0); // Watchdog timer could timeout if enabled Value = TAOR; // Read Result
How to handle external delays of unknown duration Method 2: Use a down-counter to prevent hanging: timeout = 0 x 100; while (timeout > 0) { timeout--; if (flag == 1) //external event occurred break; }
How to handle external delays of unknown duration Method 3 a: MEASURE the worst-case latency and add as delay count (slow process) // enable process TAOCTL 0 |+= CCIE; delay(2000); if (CCIF == 1) // flag checking { Value = TAOR; } Method 3 b: MEASURE the worst-case latency and add NOPs (short, fast process) // enable process TAOCTL 0 |+= CCIE; __no_operation(); __no_operation(); Value = TAOR; // // // TI TI TI NOP NOP NOP macro macro
Every Cross-Compiler has “Gotchas” Example from Code Composer Studio: void delay(unsigned long delay_count) { while(delay_count > 1) { delay_count--; } __no_operation(); // TI NOP macro return; } Never put a return directly after a loop. The above code is “optimized” out. } The NOP fixes the problem
The Microcontroller
The MSP 430 FR 6989 Microcontroller - Overview
Registers
Registers • Control Registers (xxx. CTLx)– Module level. Use to configure functions. • Count Registers (xxx. R) – Up or down counter • Capture/Compare Registers (xxx. CCR) – Work in conjunction with Counters to take action at a certain count. • Capture/Compare Control Registers (xxx. CCTLx)– Used to configure what happens when the CCR matches R (counter). • I/O Registers (Ports) – Input/Output ports can have 1 of 4 functions.
Control Registers • Every MODULE in a Microcontroller has one or more CONTROL REGISTERS to configure the functions of the module. • Each CONTROL REGISTER is divided into FIELDS • Each FIELD sets one PARAMETER of the MODULE to a specific function • The number of options for the PARAMETER determines the number of BITS in the FIELD • Each BIT has a Power-up DEFAULT value, usually 0.
Control Registers
Microcontroller Registers Count Registers
Microcontroller Registers Capture / Compare Registers
Capture / Compare Control Registers
Timer A Example: OUT 1
I/O Ports
Registers Associated with each I/O Port • Input Registers (Px. IN) - Read from this one • Output Registers (Px. OUT) – Write to this one • Direction Registers (Px. DIR) – Control direction of individual bits. • Pullup or Pulldown Resistor Enable Registers (Px. REN) – Also bit by bit • Function Select Registers (Px. SEL 0, Px. SEL 1) • Interrupt Settings (Px. IFG, Px. IES, Px. IE) NOTE: x – substitute the number of the PORT • 1 -10 and J, (8 bit) • A, B, C, D, and E (16 bit)
I/O Ports - Summary
I/O Ports – Multi-purpose Pins I/O Primary Secondary Tertiary
I/O Ports Port Number and Bit Number TI Conventions This is the number of the PORT This is the number of the BIT in the PORT P 3. 6 - Bit 6 of Port 3
I/O Ports
I/O Ports
I/O Ports
I/O Ports
I/O Ports
I/O Ports (and possibly P 3 and P 4)
MSP 430 FR 6989 HARDWARE Quick Start Guide 69
I/O Ports – Putting It All Together Suppose that you wanted to configure BIT 2 of PORT 2 as a Timer B 0. 4 output for a PWM application Bit 7 Bit 6 Bit 5 Bit 4 Bit 3 Bit 2 Bit 1 Bit 0 P 2 OUT X X X OUT X X P 2 DIR X X X 1 X X P 2 SEL 1 X X X 1 X X P 2 SEL 0 X X X 0 X X P 2 REN X X X X
- Slides: 70