This is an old revision of the document!


Crash course

Translation needed

Program structure

As a principle, program written in C-language can be in any form, even in one line, because the compiler assumes only the following of syntax rules. However, it is advisable to take care of program coding style for clearness and simplicity. Typical structure of a C-language program:

/* Include header files */
#include <avr/io.h>
#include <stdio.h>
 
/* Makro declarations */
#define PI 3.141
 
/* Data type definitions */
typedef struct
{
	int a, b;
}
element;
 
/* Global variables */
element e;
 
/* Functions */
int main(void)
{	
	// Local variables
	int x;
 
	// Program code
	printf("Tere maailm!\n");
}

Comments

Programmer can write random text into program code for notes and explanations that is no compiled. Comments can also be used for temporally excluding some parts of code from compiling. Examples of two commenting methods:

// Line comment is on one line.
// Text after two slash signs is considered as comment.
 
/*
  Block comment can be used to include more than one line.
  The beginning and the end of a comment is assigned with slash and asterisk signs.
*/

 

Data

Data types

C-language basic data types:

Type Minimum Maximum Bits Bytes
(signed) char -128 127 8 1
unsigned char 0 255 8 1
(signed) short -32768 32767 16 2
unsigned short 0 65535 16 2
(signed) long -2147483648 2147483647 32 4
unsigned long 0 4294967295 32 4
float -3.438 3.438 32 4
double -1.7308 1.7308 64 8

The word “signed” in brackets is not necessary to use because data types are bipolar by default.

AVR microcontroller has int = short
PC has int = long

There is no special string data type in C-language. Instead char type arrays (will be covered later) and ASCII alphabet is used where every char has its own queue number.

Variables

Program can use defined type of memory slots - variables. Variable names can include latin aplhabet characters, numbers and underdashes. Beginning with a number is not allowed. When declarations to variables are being made, data type is written in front of it. Value is given to variable by using equal sign (=). Example about using variables:

// char type variable c declaration
char c;
 
// Value is given to variable c.
c = 65;
c = 'A'; // A has in ASCII character map also value 65
 
// int type variable i20 declaration and initialization
int i20 = 55;
 
// Declaration of several unsigned short type variables
unsigned short x, y, test_variable;

Constants

Constants are declarated in the same way as variables, exept const keyword is added in front of data type. Constants are not changeable during program work. Example about using them:

// int type constant declaration
const int x_factor = 100;

Structures

Basic data types can be arranged into structures by using struct keyword. Structure is a combined data type. Type is declarated with typedef keyword. Example about structures by creating and using data type:

// Declaration of a new data type "point"
typedef struct
{
	// x and y coordinates and color code
	int x, y;
	char color;
}
point;
 
// declaration of a variable as data type of point
point p;
 
// Assigning values for point variable
p.x = 3;
p.y = 14;

Arrays

Data types can be arranged into arrays. Array can have more than one dimensions (table, cube etc). Example about using one- and two-dimensional arrays:

// Declaration of one- and two-dimensional arrays
char text[3];
int table[10][10];
 
// Creating a string from char array
text[0] = 'H';  // Char
text[1] = 'i';  // Char
text[2] = 0;    // Text terminator (0 B)
 
// Assigning new value for one element.
table[4][3] = 1;

 

Operations

Variables, constants and value returning functions can be used for composing operations. The result of and operation can be assigned to a variable, it can be used as a function parameter and in different control structures.

Arithmetic operators

C-language supported artithmetic operations are addition (+), subtraction (-), multiplication (*), division (/) and modulo (%). Some examples about using operators:

int x, y;
 
// Modulo, multiplication and assigning value
// x gets value of 9
x = (13 % 5) * 3;
 
// Adding-assigning operator
// x gets value of 14
x += 5;
 
// Quick style method for subtracting 1
// x gets value of 13
x--;

Logical operators

Logical operators are negation NOT (!), logic multiplication AND (&&) and logic addition OR (||). Example about using them:

bool a, b, c;
 
// Initialization
a = true;
b = false;
 
// Negation
// c will get a value of false because a is true
c = !a;
 
// Logic multiplication
// c will get a value of false because one of the operators is false
c = a && b;
 
// Logic addition
// c will get a value of true because one of the operators is true
c = a || b;

NB! bool data type in C-language is actually missing and instead integers are used where 0 marks false and every other value marks true. For example, in HomeLab library bool is defined as unsigned char. Constant true marks a value of 1 and false a value of 0.

Relational and equality operators

Logical values are a result of comparison of variable values. Equality operators are equal to (==), not equal to (!=), greater than (>), greater than or equal to (>=), less than (<) and less than or equal to (⇐). Exaple about using them:

int x = 10, y = 1;
 
// greater than operation which is true
// brackets around the operation are only for clarity
bool b = (5 > 4);
 
// Not equal to operation
// The result is false
b = (4 != 4);
 
// Arithmetic, equality and logic operations alltogether
// b is false because the first operator of logic multiplication is false
b = (x + 4 > 15) && (y < 4);

Bit operations

Bit operations are for data manipulation in binary numeral system. These can be applied only to integer type data. Bit operations are quite similar to logic operations but differ from them because operation is carried out with every single bit not the whole number. Bit operations in C-language are inversion (~), conjunction (&), disjunction (|), antivalency (^), left shift («) and right shift (»).

// Declaration of unsigned 8 bit char type variable
// Variable value is 5 in decimal system, 101 in binary system
unsigned char c = 5;
 
// Disjunction of c with a digit 2 (010 in binary)
// c value will become 7 (111 in binary)
c = c | 2;
 
// Bit left shift by 2
// c value will become 28 (11100 in binary)
c = c << 2;

Bit operations are essential when using the registers of microcontroller. These are described in AVR register chapter.

 

Functions

Functions are part of a program that can be called by its name. Function can include parameters as input and can return one output. If the function is not returning a parameter, it has type void. If the function has no parameters as its input, in older C-language compilers void must also be written besides parameter declaration. Example about addition function and a function without return:

// Declaration of 2 int type parameter function
// The function returns int type value
int sum(int a, int b)
{
	// Addition of 2 variables and returning of their sum
	return a + b;
}
 
// Function without parameters and no return output
void power_off(void)
{
}

To use a function, it must be called. It is required that a function is declared before call. Example about calling addition function:

int x;
int y = 3;
 
// Calling an addition function
// Parameetriteks on muutuja ja konstandi väärtus
// The parameters are variable and constant
x = sum(y, 5);
 
// The call of a power off function
// No parameters
power_off();

The execution of a C-language program is started from main function which makes it compulsory function.

 

Statements

If/Else statement

Conditional statements enable to execute or skip program code based on based on logic and relational operations. Conditional statement uses a keyword if. Example about using it:

// Statement is true and operation x = 5 will be executed
// because 2 + 1 is higher than 2
if ((2 + 1) > 2) x = 5;
 
// If x equals 5 and y equals 3 then the following code will be executed
if ((x == 5) && (y == 3))
{
	// Random action
	y = 4;
	my_function();
}

If statement can be longer and include code which will be executed in case the statement is false. For this, after if statement, else statement can be used. Example:

// Is x equal with 5 ?
if (x == 5)
{
	// Random action
	z = 3;
}
// If this is false then x might be equal with 6
else if (x == 6)
{
	// Random action
	q = 3;
}
// If x was not 5 nor 6 ...
else
{
	// Random action
	y = 0;
}

 

Switch statement

When required to compare operations and variables with many different values, it is reasonable to use comparison statement with switch keyword. Example about using this:

int y;
 
// Switch statement for comparing y
switch (y)
{
	// is y equal to 1 ?
	case 1:
		// Random action
		function1();
		break;
 
	// is y equal to 2 ?
	case 2:
		// Random action
		function2();
		break;
 
	// All other cases
	default:
		// Random action
		functionX();
		// break operation not needed because the comparisonbreak lauset pole vaja,
		// kuna võrdlemine lõppeb nagunii
}

Tsüklid

Tsüklitega saab programmilõiku täita mitmeid kordi.

while

while võtmesõnaga tähistatud programmilõiku täidetakse seni, kuni sulgudes olev avaldis on tõene.

int x = 0;
 
// Tsükkel kestab seni, kuni x on väiksem kui 5
while (x < 5)
{
	// x suurendamine ühe võrra
	x++;
}

 

for

for võtmesõnaga tsükkel sarnaneb while tsüklile, kuid lisaks on sulgudes ära määratud enne tsüklit täidetav lause ja iga tsükli ajal täidetav lause.

Näide:

int i, x = 0;
 
// Algul määratakse i nulliks. Tsüklit täidetaks seni, kuni
// i on vähem kui 5. Iga tsükli lõpus suurendatakse i ühe võrra
for (i = 0; i < 5; i++)
{
	// x suurendamine 2 võrra
	x += 2;
}
 
// Siinkohal tuleb x väärtuseks 10

Tsüklis liikumine

while ja for tsüklitest saab erandkorras väljuda break võtmesõnaga. continue võtmesõnaga saab alustada järgmist tsüklit ilma järgnevat koodi täitmata.

int x = 0, y = 0;
 
// Lõputu tsükkel, kuna 1 on loogiline tõesus
while (1)
{    
	// Tsüklist väljutakse, kui x on saavutanud väärtuse 100
	if (x >= 100) break;
 
	// x suurendamine, et tsükkel kunagi lõppeks ka
	x++;
 
	// Kui x on 10 või vähem, siis alustatakse järgmist tsüklit
	if (x <= 10) continue;
 
	// y suurendamine
	y++;
}
 
// Siinkohal on y väärtus 90

Tekstitöötlus

Tekstitöötlusfunktsioone on mikrokontrolleri puhul vaja eelkõige teksti kuvamiseks LCD ekraanile.

sprintf

sprintf funktsioon toimib sarnaselt C-keeles üldlevinud printf funktsiooniga. Erinevuseks on funktsiooni tulemuse väljastamine puhvrisse (muutujasse), mitte standard väljundisse.

tagastus = sprintf(muutuja, parameetritega_tekst, parameetrid);

Näide:

int r = sprintf(buffer, "%d pluss %d on %d", a, b, a+b);

Väärtustab muutuja vormindatud tekstiga, mis on antud funktsiooni teisest kuni n parameetrini. Sprintf funktsioon lihtsustab keerulisemate fraaside või lausete koostamist. Mugavam on kasutada tekstis muutujaid, mis asendatakse väärtustega. Funktsioon tagastab muutujasse salvestatud teksti pikkuse. Vea korral tagastatakse negatiivne arv.

Näide:

  sprintf(x, "%d. on esimene", 1);
  // sama tulemuse saaksime ka nii:
  x = "1. on esimene";
 
  sprintf(x, "%s on %d aastat vana", "Juku", 10);
  // sama tulemuse saaksime ka nii:
  x = "Juku on 10 aastat vana";

%s ja %d on antud juhul parameetrid, mis asendatakse vastavalt muutjate väärtustega, mis on funktsiooni viimasteks parameetriteks. Niipalju, kui on parameetreid, peab olema ka muutujaid. Esimese näite puhul oli meil parameetriks %d, mis asendati muutuja väärtusega 1. Teise näite puhul olid parameetriteks %s ja %d, mis asendati vastavalt muutuja väärtustega “Juku” ja 10. Just nimelt sellises järjekorras, sest %s ootab väärtust teksti kujul ja %d numbrilist väärtust. Erinevate andmetüüpide jaoks on olemas vastavad muutujate kirjeldused:

Parameeter Kirjeldus Näide
%c Tähemärk a
%i või %d Täisarv 123
%f Murdarv 3,14
%s Tekst näide
%X Heksadetsimaalarv 3F
#include <stdio.h>
 
int main ()
{
  char buffer [50];
  int n, a=5, b=3;
  n=sprintf (buffer, "%d pluss %d on %d", a, b, a+b);
  printf ("\"%s\" on %d markki pikk\n",buffer,n);
  return 0;
}

Üldised utiliidid

Teegi standard library (stdlib.h) funktsioonide erinevate operatsioonide ja konverteerimiste lihtsustamiseks

random

Juhuarvude genereerimine ei olegi AVR kontrolleril väga lihtne.

Esmalt tuleb juhunumbrigeneraator seemendada arvuga, mille järgi genereeritakse suvaliste numbrite jada. Sama numbri järgi genereeritakse alati sama jada. Suvalisema tulemuse saamiseks võib seemendamiseks kasutada näiteks tühjast ADC-st loetud ujuvaid väärtusi.

Näide:

srand(100);
rand();

Näide, juhuarvu genereerimiseks vahemikus 16

#include <stdlib.h>
 
int x;
x=rand() % 16;

Põhjalikuma inglisekeelse kirjelduse C keele funktsioonide kohta leiad aadressilt:

http://www.cplusplus.com/reference/clibrary/

~~DISCUSSION~~

en/programming/c/crashcourse.1338889102.txt.gz · Last modified: 2020/07/20 09:00 (external edit)
CC Attribution-Share Alike 4.0 International
www.chimeric.de Valid CSS Driven by DokuWiki do yourself a favour and use a real browser - get firefox!! Recent changes RSS feed Valid XHTML 1.0