Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
0% found this document useful (0 votes)
84 views

ECE 521: Microprocessor System: CHAPTER 3: Microprocessor Programming in C

This document discusses microprocessor programming in C, including: 1) Data types, bitwise operations, logic operations, and simple I/O programming that will be covered. 2) Why C is useful for embedded programming due to its portability, readability, and independence from specific processors. 3) Details on C data types like int8_t, uint16_t and their ranges, as well as examples of data type usage.

Uploaded by

Amar Mursyid
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
84 views

ECE 521: Microprocessor System: CHAPTER 3: Microprocessor Programming in C

This document discusses microprocessor programming in C, including: 1) Data types, bitwise operations, logic operations, and simple I/O programming that will be covered. 2) Why C is useful for embedded programming due to its portability, readability, and independence from specific processors. 3) Details on C data types like int8_t, uint16_t and their ranges, as well as examples of data type usage.

Uploaded by

Amar Mursyid
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 42

ECE 521:

Microprocessor System
CHAPTER 3: Microprocessor Programming in C
What we will learn in this section:

❑ Data types
❑ Bit-wise Operations in C
❑ Logic operation
❑ Data conversion
❑ Simple I/O programming in C language
Why Use C for Embedded
Programming?
 Portability : code can be retargeted to different processors Portability of a
language is mainly important when an application program must be
moved to other operating systems. Code developed in C is more portable
and user can compile it on other platforms with least modifications.
 Readability : C code is efficient, easy to understand, maintain and debug.
A program can be written in one machine and can be run on other
machines.
 Processor independent : C language is not specific to any
microprocessor/micro-controller or any system. It can work on various
hardware configuration. C doesn’t require same set of hardware to run a
program.
Data Types Sizes
3 methods to find out the exact sizes of the data
types:
1. Read the compiler manual.
2. Use pseudo function sizeof().
3. Use C99 data types.
ISO C99 integer data types and their
ranges
Data type Size Range Min Range Max
int8_t 1 byte -128 127
uint8_t 1 byte 0 to 255
int16_t 2 bytes -32,768 32,767
uint16_t 2 bytes 0 65,535
int32_t 4 bytes -2,147,483,648 2,147,483,647
uint32_t 4 bytes 0 4,294,967,295
int64_t 8 bytes -9,223,372,036,854,775,808 9,223,372,036,854,775,807
uint64_t 8 bytes 0 18,446,744,073,709,551,615
Data type examples
• Read bits from GPIOA (16 bits, non-numeric)
uint16_t n; n = GPIOA->IDR; //or: unsigned short n;
• Write TIM2 prescale value (16-bit unsigned)
uint16_t t; TIM2->PSC = t; //or: unsigned short t;
• Read 32-bit value from ADC (unsigned)
uint32_t a; a = ADC; //or: unsigned int a;
• System control value range [-1000…+1000]
int32_t ctrl; ctrl = (x + y)*z; //or: int ctrl;
• Loop counter for 100 program loops (unsigned)
uint8_t cnt; //or: unsigned char cnt;
for (cnt = 0; cnt < 20; cnt++) {
Bit-wise logical operators in C

A B AND OR EX-OR Invert


(A & B) (A | B) (A^B) ~B
0 0 0 0 0 1
0 1 0 1 1 0
1 0 0 1 1 1
1 1 1 1 0 0
Bitwise logical operators
Bitwise logical operators produce n-bit results of the
corresponding logical operation:

& (AND) | (OR) ^ (XOR) ~ (Complement)

C = A & B; A 0 1 1 0 0 1 1 0
(AND) B 1 0 1 1 0 0 1 1
C 0 0 1 0 0 0 1 0

C = A | B; A 0 1 1 0 0 1 0 0
(OR) B 0 0 0 1 0 0 0 0
C 0 1 1 1 0 1 0 0

C = A ^ B; A 0 1 1 0 0 1 0 0
(XOR) B 1 0 1 1 0 0 1 1
C 1 1 0 1 0 1 1 1

B = ~A; A 0 1 1 0 0 1 0 0
(COMPLEMENT) B 1 0 0 1 1 0 1 1
Setting ,Clearing (masking) and Testing
bits with bit-wise operators in C
 Anything ORed with a “1“ results in a “1”; anything ORed with a “0” results
in no change.
 Anything ANDed with a “1”results in no change; anything ANDed with a “0”
results in a zero.
 Anything EX-ORed with a “1” results in the complement; anything EX-ORed
with a “0” results in no change.
 When it is necessary to test a given bit to see if it is high or low, the unused
bits are masked and then the remaining data is tested.
Bit set/reset/complement/test
• Use a “mask” to select bit(s) to be altered
C = A & 0xFE; A a b c d e f g h
0xFE 1 1 1 1 1 1 1 0 Clear selected bit of A
C a b c d e f g 0

C = A & 0x01; A a b c d e f g h
0x01 0 0 0 0 0 0 0 1 Clear all but the selected bit of A
C 0 0 0 0 0 0 0 h

C = A | 0x01; A a b c d e f g h
0x01 0 0 0 0 0 0 0 1 Set selected bit of A
C a b c d e f g 1

C = A ^ 0x01; A a b c d e f g h
0x01 0 0 0 0 0 0 0 1 Complement selected bit of A
C a b c d e f g h’
Bit-wise shift operation in C
Operation Symbol Format of Shift Operation
Shift Right >> data >> number of bit-positions to be shifted right
Shift Left << data << number of bit-positions to be shifted left

Shift operators:
x >> y (right shift operand x by y bit positions)
x << y (left shift operand x by y bit positions)
Vacated bits are filled with 0’s.

B = A << 3; A 1 0 1 0 1 1 0 1
(Left shift 3 bits) B 0 1 1 0 1 0 0 0` filled with 0

B = A >> 2; A 1 0 1 1 0 1 0 1
(Right shift 2 bits) B 0 0 1 0 1 1 0 1
filled with 0
Compound Operators

Instruction Its equivalent using compound


operators
a = a + 6; a += 6;
a = a – 23; a –= 23;
y = y * z; y *= z;
z = z / 25; z /= 25;
w = w | 0x20; w |= 0x20;
v = v & mask; v &= mask;
m = m ^ togBits; m ^= togBits;
Bit-wise operations using compound
operators
 The majority of hardware access level code involves
▪ setting a bit or bits in a register,
▪ clearing a bit or bits in a register,
▪ toggling a bit or bits in a register,
▪ monitoring the status bits.
Shift operator: to generate mask

 One way to ease the generation of the mask is to use the shift left operator.
▪ To generate a mask with bit n set to 1, use the expression: 1 << n
 If more bits are to be set in the mask, they can be “or” together.
▪ To generate a mask with bit n and bit m set to 1, use the expression:
(1 << n) | (1 << m)
▪ Example:
register |= (1 << 6) | (1 << 1);
Setting the value in a multi-bit field

Example:
 register |= 1 << 30;
register &= ~(1 << 29);
register |= 1 << 28;

 register &= ~(7 << 28);


register |= 5 << 28;

 register = register & ~(7 << 28) | (5 << 28);


Basic C program structure

#include "STM32fxx.h" /* I/O port/register names/addresses for the STM32fxx microcontrollers */

/* Global variables – accessible by all functions */


int count, bob; //global (static) variables – placed in RAM

/* Function definitions*/
int function1(char x) { //parameter x passed to the function, function returns an integer value
int i,j; //local (automatic) variables – allocated to stack or registers
-- instructions to implement the function
}

/* Main program */
void main(void) {
unsigned char sw1; //local (automatic) variable (stack or registers)
int k; //local (automatic) variable (stack or registers)
Declare local variables
/* Initialization section */
-- instructions to initialize variables, I/O ports, devices, function registers Initialize variables/devices
/* Endless loop */
while (1) { //Can also use: for(;;) {
-- instructions to be repeated Body of the program
} /* repeat forever */
}
Memory Map of STMF446RE
Microcontroller “header file”

• Keil MDK-ARM provides a derivative-specific “header


file” for each microcontroller, which defines memory
addresses and symbolic labels for CPU and peripheral
function register addresses.
#include "STM32Fxx.h“ /* target uC information */

// GPIOA configuration/data register addresses are defined in STM32Fxx.h


void main(void) {
uint16_t PAval; //16-bit unsigned variable
GPIOA->MODER &= ~(0x00000003); // Set GPIOA pin PA0 as input
PAval = GPIOA->IDR; // Set PAval to 16-bits from GPIOA
for(;;) {} /* execute forever */
}
Constant/ Literal values
Types Format Description
Decimal int m, n; 16 bit signed numbers
m= 45;
n=-23;
Hexadecimal m=0x67F2; Preface value with 0x
n=-0x1234;
Octal m=0345; Preface value with zero
n=-056; Don’t use leading zeros on “decimal” values. They
will be interpreted as octal.
Character m=‘a’; ASCII value 0x61
n=‘\14’ ASCII value 14 is the return character
String (array) of unsigned char k[7]
characters strcpy(m, “hello\n”); k[0]=‘h’, k[1]=‘e’, k[2]=‘l’, k[3]=‘l’, k[4]=‘o’,
k[5]=13 or’\n’ (ASCII new line char)
k[6]=0 or ‘\0’ (null char – end of string)
Relational Operators
• Test relationship between two variables/expressions
Test TRUE condition Notes
1. Compiler uses signed or
(m == b) m equal to b Double =
unsigned comparison, in
(m != b) m not equal to b
accordance with data types
(m < b) m less than b 1
(m <= b) m less than or equal to b 1
Example:
(m > b) m greater than b 1
unsigned char a,b; int j,k;
(m >= b) m greater than or equal to b 1
if (a < b) – unsigned if (j > k) -
(m) m non-zero
signed
(1) always TRUE
(0) always FALSE
Boolean operators

• Boolean operators && (AND) and || (OR) produce


TRUE/FALSE results when testing multiple TRUE/FALSE
conditions
if ((n > 1) && (n < 5)) //test for n between 1 and 5
if ((c = ‘q’) || (c = ‘Q’)) //test c = lower or upper case Q
• Note the difference between Boolean operators &&, ||
and bitwise logical operators &, |
if ( k && m) //test if k and m both TRUE (non-zero values)
if ( k & m) //compute bitwise AND between m and n,
//then test whether the result is non-zero (TRUE)
Common error

• Note that == is a relational operator,


whereas = is an assignment operator.

if ( m == n) //tests equality of values of variables m and n


if (m = n) //assigns value of n to variable m, and then
//tests whether that value is TRUE (non-zero)
C control structures

• Control order in which instructions are executed


(program flow)
• Conditional execution
– Execute a set of statements if some condition is met
– Select one set of statements to be executed from
several options, depending on one or more conditions
• Iterative execution
– Repeated execution of a set of statements
• A specified number of times, or
• Until some condition is met, or
• While some condition is true
If Statement

if (condition) statement


▪ If condition is met, the statement is executed, otherwise, it is omitted

if (work == 1)
{
statement s1;
statement s2;
}
IF-THEN-ELSE structure
if (condition) statement1;
else statement2 ;
▪If the condition is met (true), the statement1 is executed,
otherwise (false), statement2 is executed

if (a == 0)
{
statement s1;
statement s2; Yes No
S1; a == 0 S3;
} S2; ? S4;
else
{
statement s3;
statement s4:
}
Multiple ELSE-IF structure
• Multi-way decision, with expressions
evaluated in a specified order
if (n == 1)
statement1; //do if n == 1
else if (n == 2)
statement2; //do if n == 2
else if (n == 3)
statement3; //do if n == 3
else
statement4; //do if any other value of n (none of the above)

Any “statement” above can be replaced with a set of


statements: {s1; s2; s3; …}
SWITCH statement
• Compact alternative to ELSE-IF structure, for multi-
way decision that tests one variable or expression
for a number of constant values

/* example equivalent to that on preceding slide */


switch ( n) { //n is the variable to be tested
case 0: statement1; //do if n == 0
case 1: statement2; // do if n == 1
case 2: statement3; // do if n == 2
default: statement4; //if for any other n value
}
Any “statement” above can be replaced with a set of
statements: {s1; s2; s3; …}
Switch Statement
 Switch is only test for integer and character values
and not of type float/double.

switch (integer or character expression) /* evaluated to


become const1… */
{ case const1 : statement1;
break; /*optional*/
case const2 : statement2;
break; /*optional*/

default : statement; }
WHILE loop structure

• Repeat a set of statements (a “loop”) as long


as some condition is met

while (a < b)
{ S1;
statement s1; a<b S2;
? Yes …
statement s2;
No “loop” through these
…. statements while a < b
}

Something must eventually cause a >= b, to exit the loop


WHILE example

No Wait for a 1 to be applied


PORTA
bit0 0
operation to bit 0 of GPIOA
and then read GPIOB
1

Read
PORTB

while ( (GPIOA->IDR & 0x0001) == 0) // test bit 0 of GPIOA


{} // do nothing & repeat if bit is 0
c = GPIOB->IDR; // read GPIOB after above bit = 1
DO-WHILE loop structure
• Repeat a set of statements (one “loop”)until some condition is met
do { statements } while (condition);
▪The loop is always executed once since the condition is
tested at the end of the loop.

do “loop” through
S1;
{ S2; these statements
statement s1; … until a < b
statement s2;
….
Yes
} a<b
while (a < b); ?
No
FOR loop structure

• Repeat a set of statements (one “loop”) while


some condition is met
– often a given # of iterations
Condition for
Operation(s) at end
Initialization(s) execution
of each loop

for (m = 0; m < 200; m++)


a<b Statement s1;
{ ? Statement s2;
Yes
statement s1;
statement s2; No

}
FOR loop structure

• FOR loop is a more compact form of the


WHILE loop structure
/* execute loop 200 times */ /* equivalent WHILE loop */
for (m = 0; m < 200; m++) m = 0; //initial action(s)
{ while (m < 200) //condition test
statement s1; {
statement s2; statement s1;
} statement s2;
m = m + 1; //end of loop action
}
FOR structure example

 /* Read 100 16-bit values from GPIOB into array C */


 /* Bit 0 of GPIOA (PA0) is 1 if data is ready, and 0 otherwise */ uint16_t c[100];
 uint16_tk;

 for (k = 0; k < 200; k++) {


 while ((GPIOA->IDR & 0x01) == 0) //repeat until PA0 = 1

{} //do nothing if PA0 = 0


c[k] = GPIOB->IDR; //read data from PB[15:0]
}
FOR structure example

/* Nested FOR loops to create a time delay */

for (i = 0; i < 100; i++) { //do outer loop 100 times


for (j = 0; j < 1000; j++) { //do inner loop 1000 times
} //do “nothing” in inner loop
}
Switching ON LED

Eg. Write a program in C language that will turn on Green LED


(LD2) on the STM32F446RE board.
START

Enable Port A clock

Configure PA5 as
output

Turn on LED
Switching ON LED
START

Eg. Write a program in C language that will toggle the


green LED (LD2) on STM32F446RE Nucleo64 board at 16Hz Enable Port A clock

Configure PA5 as
output

Turn on LED

Delay 0.5s
User LED connection for STM32F446RE Nucleo board

Turn OFF LED

Delay 0.5s
TOOGLE OR BLINKING LED
Reading a Switch Condition

Eg. Write a program in C language that will turn on Green LED (LD2) on the
STM32F446RE board when the switch B1 is pressed (pull up register).

PA5
Reading a Switch Condition

Write a program in C language that will turn on Green LED (LD2) on


the STM32F446RE board when the switch B1 is pressed.

START

Read the status of


Enable Port A clock the switch

Turn off LED


Enable Port C clock
Is the N
switch
pressed
Configure PA5 as ?
output
Y

Turn on LED
Configure PC13 as
input
Reading a Switch Condition

You might also like