Thanks to visit codestin.com
Credit goes to www.scribd.com

0% found this document useful (0 votes)
16 views9 pages

Chapitre 3

Chapter 3 covers C programming for the MSP430, focusing on constants, variables, arrays, conditional statements, loops, functions, and pointers. It emphasizes the differences between static and volatile variables, and illustrates how to use pointers for efficient memory management and function operations. The chapter includes practical examples demonstrating UART communication and the manipulation of data through functions and pointers.

Uploaded by

miniarkammoun705
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)
16 views9 pages

Chapitre 3

Chapter 3 covers C programming for the MSP430, focusing on constants, variables, arrays, conditional statements, loops, functions, and pointers. It emphasizes the differences between static and volatile variables, and illustrates how to use pointers for efficient memory management and function operations. The chapter includes practical examples demonstrating UART communication and the manipulation of data through functions and pointers.

Uploaded by

miniarkammoun705
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/ 9

Chapitre 3 : C programming for MSP430

Constants and variables


When defining constants to make more readable programs or to allow for easy
changes of constants used in multiple places use #define, rather than const . The
constant declaration forces the compiler to create a variable in RAM at runtime.
Define simply creates a code in the program memory this is much more efficient.
#define PIN3 3 //define PIN3 = 3

int pin3 = 3; // create a 16 bit variable in RAM and store 3 in it.

Variables change during runtime so are required to be stored in RAM.

Typical variable types:

unsigned char myvariable; // 8 bit unsigned integer (0,... 255)

char myvariable; // 8 bit unsigned integer (0,... 255)

signed char myvariable; // 8 bit signed integer (-128,... 127)

unsigned int myvariable; // 16 bit signed integer (0,... 65535)

signed int myvariable; // 16 bit signed integer (-32768,... 32767)

int // 16 bit signed integer (-32768,... 32767)

Static and Volatile variables are different. A static variable is simply a variable that
exists for the lifetime of the application. Static variables can be global: defined
outside of a function and accessible everywhere, or local: defined within a function
and only accessible from within that function. Local static variables are created on
the first invocation of the function and remain in memory for the function to use
when next called. The static keyword enforces the compiler to ensure that the RAM
for the variable is always reserved and not reused for other variables.
static int state = 0;

So if you need a variable that is only used within a function and only updated by
that function and you need the value of that variable to remain for the next time that
you call the function then you need to define it as a static variable.

char debounce(void)
{
static char count=0;
if (PINB & (1< 10) return 1;
else return 0;
}

where the value of count needs to be kept for the next time the function is called.

A volatile variable is one the can be changed without the compilers knowledge for
example by an interrupt. This means that whenever this variable is accessed by the
program it must be reread from the actual memory location in case it has changed,
rather than simply read from the cache or registers on the ALU if it has already
been used recently by the program.
volatile int state = 0;

A variable can be both static (always present) and volatile (changed from
anywhere).
static volatile int state = 0;

Arrays
Arrays allow for the storage and retrieval of multiple values using indexing.
int myArray[5]; // define an array of 5 integers
chars myArray2[5]; // define an array of 5 bytes

int myArray3[3] = { 1, 2, 3}; // define an array of 3 integers and


store (1, 2, 3)

int x = myArray3[2]; // copy the 3 third value from the


myArray3 into x

#define ARRAYSIZE 100 // define array size constant


int myArray4[ARRAYSIZE]; // initialise array
int i; // initialise indexing variable
for (i=0; i<ARRAYSIZE; i++){ // loop through all array indices
myArray4[i] = i; // store the current index value in the
array
}

Conditional statements: If, Switch


if (seconds == 59) {
minutes++;
seconds=0
} else seconds++;

switch(state) {
case 1:
{expression;}
break;
case 2:
{expression;}
break;
default:
{expression;}
break;
}

Loops: while, for


while ( condition ){
expression;
}

// Example of a while loop the iterates 1000 times


int x = 0;
int n = 1000;
while ( n-- ){ // Post decrement n
x = x+n;
}

int i;
for (i=0,i<10,i++) {
expression;
}

Functions
Functions allow you to reuse and encapsulate code. to use functions in c it is first
necessary to define the function prototype as the top of your code before the main
function. This necessary so that the compiler knows that the functions exist. The
function prototype is simply the function declaration terminated with a semicolon.
// Function protoypes
void myfunction(int number, char code);
int myotherfunction(int number, char code);

The function itself can then appear anywhere after your main function. The main
function should be the first function that appears in your code and does not require
a function prototype. Functions do not need to return any values or have any inputs.
the key word void is used. A function can only have one output with is returned
using the return keyword.
// A function with no inputs and no output.
void myfunction(void)
{
Expressions;
}

// A function with two inputs and no output.


void myfunction(int number, char code)
{
Expressions;
}
// A function with two inputs and one output.
int myotherfunction(int number, char code)
{
int result;
result=number*code;
return result;
}

If you wish to change more than one variable then you will need to use pointers.

Pointers and Arrays


Pointers are simply special variables that contain the address of a particular
memory location where you store data i.e. they point to that memory location.

To create a pointer variable (myPointer) that points to a particular variable


(myVariable) we could use the following code
int myVariable = 1000; // define variable myVariable assign it a value
of 1000

int *myPointer; // define a pointer variable


myPointer = &myVariable; //Create a pointer that contains the address of
myVariable

The ‘int’ type definition when defining a pointer specifies the size of the memory
location that the pointer points to in this case the size of myVariable. The size of
the pointer itself depends on the size of the address used by the computer or micro
controller and is taken care of by the compiler. The ‘*’ indicates that we are
defining a pointer variable. We then assign the memory location of the variable
myVariable to the pointer myPointer using the & operator.

We can now use the pointer to access the value stored at the memory location it
points to.
int x; // Define new variable x
x = *myPointer; //Copy the value stored in the location that the pointer
points to into x

Here the ‘*’ indicates that we want the contents stored at the memory location (in
this case 1000) not the value of the pointer itself which simply contains the
memory address.

These examples seem a little pointless as here we are only dealing with variables
that refer to a single memory location. In fact the variable myVariable is really
already a pointer to the memory location where the value is stored. However
pointers become really useful when you have arrays. Consider an array (myArray)
that is able to hold 5 integers.
int MyArray[5] = { 2, 5 , 3, 14, 300 }; // Define new array MyArray
int *myPointer; // Define pointer to integer type
myPointer = &MyArray[0]; // Create a pointer variable that
points to the first value in the array.

Now whilst the code above is correct in practice you will never see this because for
arrays you can drop the ‘&’ that is required to indicate you want the address of the
Variable not its value. Note for variables that are not arrays i.e. only single values
you must use the ‘&’ notation. For arrays the simplified code as shown below
int MyArray[5] = { 2, 5 , 3, 14, 300 }; // Define new array MyArray
int *myPointer; // Define pointer to integer type
myPointer = MyArray; // Create a pointer variable that
points to the first value in the array.

You can now use the pointer to index the array consider the example given in the
array section above
#define ARRAYSIZE 100 // define array size constant
int myArray[ARRAYSIZE]; // initialise array
int i; // initialise indexing variable
for (i=0; i<ARRAYSIZE; i++){ // loop through all array indices
myArray[i] = i; // store the current index value in the
array
}

Using pointers
#define ARRAYSIZE 100 // define array size constant
int myArray[ARRAYSIZE]; // initialise array
int *myPointer = myArray; // initialise array pointer to first
element of myArray
for (i=0; i<ARRAYSIZE; i++){ // loop through all array indices
*myPointer = i; // store the current index value in the
location pointed to by myPointer
myPointer++; // increment pointer
}

This can be further reduced to


#define ARRAYSIZE 100 // define array size constant
int myArray[ARRAYSIZE]; // initialise array
int *myPointer = myArray; // initialise array pointer to first
element of myArray
for (i=0; i<ARRAYSIZE; i++){ // loop through all array indices
*myPointer++ = i; // store the current index value in the
location pointed to by myPointer

Pointers really come into their own when you want to define functions that operate
on variables and arrays without requiring the function to first make a local copy of
the variable to use within the function. They also allow you to update multiple
variables from within a function and make these accessible after the function has
completed. You first need to define the variables that you wish to operate on as
volatile variables before the main function. You then define the inputs to the
function as pointers. In this way the function only creates a local copy of the
pointer within the function not the variable itself. You can see that if your function
operates on arrays this is going to be much more efficient as the pointer to the array
is a single address, whereas to create a local copy of a large array would require the
same amount of memory as the original array again. In this way when you pass the
variables to the function only the pointer to the variable is passed. Inside the
function no new variables are created and the function simply writes or changes the
variables in the location pointed to by the pointer. Thus when the function finishes
your original variables will have been changed.

As an example consider a function that takes in two char inputs and swaps them.
volatile char A;
volatile char B;

void SwapChars(char *a, char *b); // Function prototype

void main(void){
x1 = 'A';
x2 = 'B';
SwapChars(&x1, &x2); // Pass the pointers to variables x1 and x2 to
the function
}

void SwapChars(char *a, char *b){


char c = 0; // initialise temporary variable c
P1OUT |= BIT6; // Set P1.0
c = *a; // copy the value in memory location a in variable c
*a = *b; // copy the value stored in memory location b into memory
location a
*b = c; // copy the value temporarily stored in c into memory
location b
}

You can see that the function definition defines the inputs as pointers to chars.
Inside the function the value stored at the location pointed to by a is temporarily
stored in a variable c that is created within the function. The value stored at the
location pointed to by b is then copied into location pointed to by a and finally the
value of c is copied into the location pointed to by b. Note also when we call the
function from within main it is necessary to use the & notation to ensure we pass
the address to the variables not the variables themselves as these variables are not
arrays.

The UARTSendArray function below is an example of using pointers to pass an


array to a function.
char myString[5] = "Hello";
int data[2]={1023, 235};

void main(void){
UARTSendArray(myString, 5); // Send character string in myString
UARTSendArray("Bye", 3); // Send character string "Bye"
UARTSendArray(data, 4); // Send integer in array data as bytes
}

void UARTSendArray(char *TxArray, int ArrayLength){


while(ArrayLength--){ // Loop until StringLength == 0 and
post decrement
while(!(IFG2 & UCA0TXIFG)); // Wait for TX buffer to be ready for
new data
UCA0TXBUF = *TxArray++; //Write the character at the location
specified by the pointer and post increment
}
}

This example also highlights another nice feature of pointers because the UART is
only able to transmit 8 bit bytes the type that the TxArray pointer points to is
defined as a char. However we can use this function to send the contents of an
integer array one byte at a time. This works because when we call the
function UARTSendArray(data, 4); the pointer TxArray created by the function
simply points to the first address of data. Now when the value of the pointer
address pointer is incremented by TxArrray++ it is only incremented to the address
of the next byte as the data type that the pointer was defined as pointing to was
char, even thought the original data array was defined as an integer. In order to
transmit the entire data array as bytes it is therefore necessary to specify the array
length as twice that of the integer array.

Pointers code full example


/* Example code demonstrating the use of pointers.
* It uses the hardware UART on the MSP430G2553 to receive
* and transmit data back to a host computer over the USB connection on the
MSP430
* launchpad.
* Note: After programming using CCS it is necessary to stop debugging and
reset the uC before
* connecting the terminal program to transmit and receive characters.
* This demo will transmit the characters AB in response to a S been sent
each time S is sent the
* order of the characters is swaped. If agen any other character is sent
and unknown command response is sent.
*/

#include "msp430g2553.h"
void UARTSendArray(char *TxArray, int ArrayLength);
void UARTSendChar(char *TxChar);
void SwapChars(char *a, char *b);

volatile char data;


volatile char x1;
volatile char x2;

void main(void)

{
WDTCTL = WDTPW + WDTHOLD; // Stop WDT

P1DIR |= BIT0 + BIT6; // Set the LEDs on P1.0, P1.6 as outputs


P1OUT = BIT0; // Set P1.0
BCSCTL1 = CALBC1_1MHZ; // Set DCO to 1MHz
DCOCTL = CALDCO_1MHZ; // Set DCO to 1MHz

/* Configure hardware UART */


P1SEL = BIT1 + BIT2 ; // P1.1 = RXD, P1.2=TXD
P1SEL2 = BIT1 + BIT2 ; // P1.1 = RXD, P1.2=TXD
UCA0CTL1 |= UCSSEL_2; // Use SMCLK
UCA0BR0 = 104; // Set baud rate to 9600 with 1MHz clock (Data
Sheet 15.3.13)
UCA0BR1 = 0; // Set baud rate to 9600 with 1MHz clock
UCA0MCTL = UCBRS0; // Modulation UCBRSx = 1
UCA0CTL1 &= ~UCSWRST; // Initialize USCI state machine
IE2 |= UCA0RXIE; // Enable USCI_A0 RX interrupt

x1 = 'A';
x2 = 'B';

__bis_SR_register(LPM0_bits + GIE); // Enter LPM0, interrupts enabled


}

// Echo back RXed character, confirm TX buffer is ready first


#pragma vector=USCIAB0RX_VECTOR
__interrupt void USCI0RX_ISR(void)
{
data = UCA0RXBUF;
switch(data){
case 'S':
{
SwapChars(&x1, &x2); // Pass the pointers to variables x1 and x2
to the function

UARTSendChar(x1);
UARTSendChar(x2);
UARTSendArray("\n\r", 2);
P1OUT &= ~BIT6; // Set P1.0
}
break;
default:
{
UARTSendArray("Unknown Command: ", 17);
UARTSendChar(data);
UARTSendArray("\n\r", 2);
}
break;
}
}

void UARTSendArray(char *TxArray, int ArrayLength){


// Send number of bytes Specified in ArrayLength in the array at using
the hardware UART 0
// Example usage: UARTSendArray("Hello", 5);
// int data[2]={1023, 235};
// UARTSendArray(data, 4); // Note because the UART transmits bytes it
is necessary to send two bytes for each integer hence the data length is
twice the array length

while(ArrayLength--){ // Loop until StringLength == 0 and


post decrement
while(!(IFG2 & UCA0TXIFG)); // Wait for TX buffer to be ready for
new data
UCA0TXBUF = *TxArray++; //Write the character at the location
specified by the pointer and post increment
}
}

void UARTSendChar(char *TxChar){


// Send number of bytes Specified in ArrayLength in the array at using
the hardware UART 0
// Example usage: UARTSendArray('A');
while(!(IFG2 & UCA0TXIFG)); // Wait for TX buffer to be ready for
new data
UCA0TXBUF = TxChar; //Write the character at the location
specified py the pointer
}

void SwapChars(char *a, char *b){


char c = 0; // initialise temporary variable c
P1OUT |= BIT6; // Set P1.0
c = *a; // copy the value in memory location a in variable c
*a = *b; // copy the value stored in memory location b into memory
location a
*b = c; // copy the value temporarily stored in c into memory
location b
}

You might also like