0% found this document useful (0 votes)
7 views

CH 4 Cprog

This document summarizes key differences between assembly language and C constructs, provides examples of pointer usage in C, and discusses basic C program structure. It contains 3 main sections: 1) A comparison of assembly language and equivalent C constructs for defining constants, allocating memory, flow control, and calling/returning from functions. 2) Examples and explanations of pointer usage in C, including dereferencing pointers, pointer arithmetic, and allocating arrays in memory. 3) An overview of basic C program structure for embedded systems, including use of header files, global/local variables, and function definitions.

Uploaded by

Chawki Wiki
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
7 views

CH 4 Cprog

This document summarizes key differences between assembly language and C constructs, provides examples of pointer usage in C, and discusses basic C program structure. It contains 3 main sections: 1) A comparison of assembly language and equivalent C constructs for defining constants, allocating memory, flow control, and calling/returning from functions. 2) Examples and explanations of pointer usage in C, including dereferencing pointers, pointer arithmetic, and allocating arrays in memory. 3) An overview of basic C program structure for embedded systems, including use of header files, global/local variables, and function definitions.

Uploaded by

Chawki Wiki
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 4

Chapter 4

C Programming

In C, the starting location of the program is defined when you compile the program, not in the program itself. C always uses
the stack and automatically loads the stack pointer. Assembly code can be included (embedded) within the C code using
the construct: asm(). Here’s a comparison of some Assembly language and C constructs:

Assembly C
; Define a constant COUNT
COUNT EQU 5 #define COUNT 5
; Start a program
org $2000 main(){
lds 0x2000 }
;Allocate two bytes for a signed number
org $1000
i ds.w 1 int i;
j dc.w $1A00 int j = 0x1A00;
;Allocate two bytes for an unsigned number
i ds.w 1 unsigned int i;
j dc.w $1A00 unsigned int j = 0x1A00;
;Allocate one byte for a signed number
i ds.b 1 signed char i;
j dc.b $1F signed char j = 0x1F;
;Get a value from an address, Put contents of
; address $E000 into variable i
i ds.b 1 unsigned char i;
ldaa $E000 i = *(unsigned char *) 0xE000;
staa i
/* Use a variable as a pointer (address) */
unsigned char *ptr, i;
ptr = (unsigned char *) 0xE000;
i = *ptr;
*ptr = 0x55;
;To call a subroutine /* To call a function */
ldaa i sqrt(i);
jsr sqrt
;To return from a subroutine /* To return from a function */
ldaa j return j;
rts
;Flow control
blo if (i < j)
blt if (i < j)
bhs if (i >= j)
bge if (i >= j)

Here is a simple program written in C and assembly. It simply divides 16 by 2. It does the division in a function.
41
42 Chapter 4 6812 C Programming
Assembly C
org $1000
i ds.b 1 signed char i;
signed char div(signed char j);
org $2000 main()
lds #$2000 {
ldaa #16 i = div(16);
jsr div }
staa i
swi

div asra signed char div(signed char j) {


rts return j >> 1; }

4.1 C Pointers

The construct *(number) treats number as an address, and to work with the contents of that address. The C runtime needs
to how many bytes we want and is it signed or unsigned as follow (*(type *) address).
i = *(unsigned char *) 0xE000; : take one byte from address 0xE000 (as unsigned) and store it in variable i.
j = *(int *) 0xE000; : take two bytes from address 0xE000, treat it as signed, and store that value in variable j.
*(char *) 0xE000 = 0xAA; : write the number 0xAA to a single byte at address 0xE000.
*(int *) 0xE000 = 0xAA; : write the number 0x00AA to two bytes starting at address 0xE000.

To access consecutive locations in memory, use a variable as a pointer:


unsigned char *ptr;
ptr = (unsigned char *)0x1000;
*ptr = 0xaa; /* Put 0xaa into address 0x1000 */
ptr = ptr+2; /* Point two further into table */
x = *ptr; /* Read from address 0x1002 */

To allocate ten locations


EEfor
308a table in memory: Spring 2010
unsigned char table[10];

Operators in C
The third element in the table can be accessed as table[2] or *(table+2)

Operator
To set up a table of constant data: | Action | example
-----------------------------|---------------------------------------
const unsigned char table[] |= {0x00, 0x01, 0x03,
| Bitwise OR |0x07,%00001010
0x0f; } | %01011111 = % 01011111
& | Bitwise AND | %00001010 & %01011111 = % 00001010
^ | Bitwise XOR | %00001010 ^ %01011111 = % 01010101
4.2 Setting and Clearing Bits ~ in C | Bitwise COMP | ~%00000101 = %11111010
% | Modulo | 10 % 8 = 2
| |
It is often needed to set or clear bits of a hardware register. A ”mask” is used to select bit(s) to be altered:
|| | Logical OR | %00000000 || %00100000 = 1
- The easiest way to set bits in C&&is to use the bitwise
| Logical ANDOR|(|) operator:
%11000000 && %00000011 = 1
DDRB = DDRB | 0x0F; /* Make 4 LSBs of Port B outputs, | %11000000 && %00000000
0x0F is the mask */ = 0
- The easiest way to clear bits in C is to use the bitwise AND (&) operator:
PORTA = PORTA & 0x1F; /* Clear 3 MSBs of Port Setting
A */ and Clearing Bits in C

assembly | C | action
----------------------|-------------------------------|---------------------
bset DDRB,$0F | DDRB = DDRB | 0x0f; | Set 4 LSB of DDRB
bclr DDRB,$F0 | DDRB = DDRB & ~0xf0; | Clear 4 MSB of DDRB
| |
l1: brset PTB,$01,l1 | while ((PTB & 0x01) == 0x01) | Wait until bit clear
| |
l2: brclr PTB,$02,l2 | while ((PTB & 0x02) == 0x00) | Wait until bit set

Pointers in C
Operators in C
Chapter 4 6812 C Programming 43

Operator | Action | example


-----------------------------|---------------------------------------
| | Bitwise OR | %00001010 | %01011111 = % 01011111
& | Bitwise AND | %00001010 & %01011111 = % 00001010
^ | Bitwise XOR | %00001010 ^ %01011111 = % 01010101
~ | Bitwise COMP | ~%00000101 = %11111010
% | Modulo | 10 % 8 = 2
| |
|| | Logical OR | %00000000 || %00100000 = 1
&& | Logical AND | %11000000 && %00000011 = 1
| %11000000 && %00000000 = 0

4.3 Setting
Basic C Program Structure for Embedded and Clearing Bits in C
Systems

# include < mc9s12dp512 .h > /* I / O port / register names / addresses for the MC9S12DP512 m i c r o c o n t r o l l e r s */
assembly | C | action
/* Global variables ----------------------|-------------------------------|---------------------
accessible by all functions */
int count , bob ; bset
// global DDRB,$0F
( static ) variables | p lDDRB
aced =
in DDRB
RAM | 0x0f; | Set 4 LSB of DDRB
bclr DDRB,$F0 | DDRB = DDRB & ~0xf0; | Clear 4 MSB of DDRB
/* Function definitions */
| |
int function1 ( char x ) { // parameter x passed to the function , function returns an integer value
int i , j ; l1: brset
// local PTB,$01,l1 | while ((PTB & 0x01) == 0x01) | Wait until bit clear
variables declaration
// -- instructions to implement function1 | |
}
l2: brclr PTB,$02,l2 | while ((PTB & 0x02) == 0x00) | Wait until bit set
/* Main program */
void main ( void ) {
unsigned char sw1 ;
Pointers in C
// local variable declaration
int k ; // local variable declaration
/* In itializ ation section */
To read
// -- instructions to a byte fromvariables
initialize memory, Ilocation 0xE000:
/ O ports , devices , function registers
/* Infinite loop */
while (1) { var// repeat forever
= *(char *), 0xE000;
can also use : for (;;) {
// -- instructions to be repeated to implement body of the program
}
} To write a 16-bit word to memory location 0xE002:

*(int *) 0xE002 = var;


4.4 Microcontroller header file

Freescale Codewarrior provides a derivative-specific ’header file’ (e.g. mc9s12dp512.h) for each microcontroller, which defines
memory addresses and symbolic labels for CPU and peripheral function register addresses.

4.5 Examples:

Software delay (in milliseconds)


void delay ( unsigned short num_ms ) {
volatile unsigned short i ; /* volatile so compiler does not optimize */
while ( num_ms > 0) {
16
i = 2000;
while ( i > 0){ /* Inner loop takes 12 cycles */
i = i - 1; /* Execute 2000 times to */
} /* delay for 1 ms */
num_ms = num_ms - 1;
}
}

A program to increment LEDs connected to PORTB, and delay for 50 ms between changes
main () {
DDRB = 0 xff ; /* Make PORTB output */
PORTB = 0; /* Start with all off */
while (1) {
PORTB = PORTB + 1;
delay (50);
}
}
44 Chapter 4 6812 C Programming
A Program to count the number of negative numbers in an array of bytes in memory from address 0xE000 to 0xEFFF.
# include < hidef .h > /* common defines and macros */
# include " derivative . h " /* derivative - specific definitions */

unsigned short num_neg ;

main () {
char * ptr ,* start ,* end ;
start = ( char *) 0 xE000 ; /* Address of first element */
end = ( char *) 0 xEFFF ; /* Address of last element */
num_neg = 0;
for ( ptr = start ; ptr <= end ; ptr = ptr +1) {
if (* ptr < 0) num_neg = num_neg + 1;
}
}

Variables can be printed out as follow:


# include < stdio .h >
# include < termio .h >
main () {
int i ;
for ( i =0; i <100; i ++) printf (" i = % d \ r \ n " , i );
}

You might also like