using avr …. introduction to microcontroller programming 1 muhammed yazar y btech, cse national...

Post on 24-Dec-2015

223 Views

Category:

Documents

0 Downloads

Preview:

Click to see full reader

TRANSCRIPT

1

Using AVR ….

Introduction To Microcontroller Programming

Muhammed Yazar YBtech, CSE

National Institute of Technology, Calicut2012

yazar.y@gmail.com

2

MicrocontrollerA microcontroller (sometimes

abbreviated µC, uC or MCU) is a small computer on a single integrated circuit containing a processor core, memory, and programmable input/output

peripherals.

3

Here in this workshop we will be dealing with ATMEL’s AVR microcontrollers, more specifically ATMEGA-16. For further reference about any further details about this MCU, you could refer to the manual for this MCU. We will be using WinAVR as our programming platform and avrdude as the programming application.

4

Let’s Revise C Programming

C programming Language was introduced in the year of 1972 by Dennis Ritchie of AT&T Bell Laboratories.

Let’s start our first program, the traditional Hello World!.. Program /*Program to Print Hello World*/#include<stdio.h> void main( ){

printf(“Hello World!..”); }

5

• Here the things given inside /* */ are called comments which will be ignored by the compiler during compilation time

• When we write the pre-processor directive #include<stdio.h> our pre-processor will also include the header file stdio.h which contains the defenitions for standard input output functions. So if we include stdio.h in our program, we will be able to use those standard functions in our program. Similary there are also many standard and user defined header files and if we include them in our program we will be able to use the functions defined int that in our program.

• Every C program starts its execution from main( ) function and we do call other userdefined or standard library functions inside our main( ) function. We do write all our programs also inside the main( )

• Every C Statements terminates with a semicolon ‘ ; ‘• printf( ) is the standard library function we use to print something

into the console.

6

Declaring Variable

• Variables are the programming elements which we refer to store some data in the Main Memory.

• The basic syntax for declaring and initializing variable is:

<data type> variable_name [= <value>];

Eg: int myVar = 5;char character;character = ‘A’;float x = 11.234;

7

Basic Data Types

• int is used to define integer numbers.• Eg :int x =6;• float is used to define floating point numbers.• Eg: float y = 3.231;• double is used to define BIG floating point numbers. It reserves twice

the storage for the number. On PCs this is likely to be 8 bytes.• Eg: double z = 234.2376546;• char defines characters and they are usually enclosed in a single quotes

and they could hold onle a single character values.• Eg: char newChar = ‘A’;• For storing strings, we use array of characters and they are being

terminated by null character ‘\0’.• Eg: char name = {‘R’, ‘a’, ‘m’, ‘\0’};

8

/*Program to Add two numbers*/#include<stdio.h> void main( ){

int x, y, sum;printf(“Enter two numbers : ”);

scanf(“%d %d”, &x, &y);sum = x + y;printf(“Sum is %d”, sum);

}

9

Basic Operators in C:

Operator Description Example

+ Adds two operands A + B will give 30- Subtracts second operand from the first A - B will give -10* Multiply both operands A * B will give 200/ Divide numerator by denumerator B / A will give 2% Modulus Operator and remainder of after

an integer divisionB % A will give 0

++ Increment operator, increases integer value by one

A++ will give 11

-- Decrement operator, decreases integer value by one

A-- will give 9

•Arithmetic Operators

10

Operator Description Example

== Checks if the value of two operands is equal or not, if yes then condition becomes true.

(A == B) is not true.

!= Checks if the value of two operands is equal or not, if values are not equal then condition becomes true.

(A != B) is true.

> Checks if the value of left operand is greater than the value of right operand, if yes then condition becomes true.

(A > B) is not true.

< Checks if the value of left operand is less than the value of right operand, if yes then condition becomes true.

(A < B) is true.

>= Checks if the value of left operand is greater than or equal to the value of right operand, if yes then condition becomes true.

(A >= B) is not true.

<= Checks if the value of left operand is less than or equal to the value of right operand, if yes then condition becomes true.

(A <= B) is true.

&& Called Logical AND operator. If both the operands are non-zero then then condition becomes true.

(A && B) is true.

|| Called Logical OR Operator. If any of the two operands is non-zero then then condition becomes true.

(A || B) is true.

! Called Logical NOT Operator. Use to reverses the logical state of its operand. If a condition is true then Logical NOT operator will make false.

!(A && B) is false.

•Logical / Relational Operators:

11

• Logical Operators• A logical operator operated between two

relational or logical expressions and returns a logical value.

• • && - Logical AND• || - Logical OR• ! - Logical Negation / NOT

12

• Bitwise Operators• Bitwise operator works on bits and performs bit by bit operation.• Assume if A = 60; and B = 13; Now in binary format they will be as follows:• A = 0011 1100• B = 0000 1101• -----------------• A&B = 0000 1100 – Bitwise ANDing• A|B = 0011 1101 – Bitwise ORing• A^B = 0011 0001 – Bitwise XORing• ~A = 1100 0011 – Bitwise Negation operator• << - Left shift operator• >> - Right Shift Operator• NB: Please make yourself very clear about bitwise operators as we use

them much frequently while programming the microcontrollers.• sizeof( ) – operator is used to get the size (in bytes) which a variable or a

data type takes in memory.

13

Control Structures:

14

• Sequential Control Structure• Eg: Usual programs in which we execute

statements one after the other.

• Selection Control Structure• If statements in which a condition is being

checked and if it is true certain set of statements will get executed.

15

Simple if statement:if(condition){

--Statements--}

16

• If –Else Statementsif(condition){

--Statements--}else{

--Statements--}

17

• If-Else-If Ladderif(condition1){

--Statements--}else if(condition2){

--Statements--}else{

--Statements--}

18

• Switch Statementsswitch(expression){

case const1: --Statements— break;

case const2: --Statements— break;

case const3: --Statements— break;

default: --Statements—

break; }

19

Iteration / Looping

• For Loop for(initialisation; condition ; updation){

--Loop Body--}Eg:for(int i = i; i<=10 ; i++){ /*Printing Multiplication Table of 5 */

printf(“%d x 5 = %d”, i, i*5);}

20

• While Loop – Loop Body will get executed till the condition goes false

while(condition){

--Loop Body --}

21

• Do-While Loop : It is an exit controlled loop, ie. The loop body is executed at least once even if the condition is always being false.do{

--Loop Body --} while (condition);

22

• Break statement:If we place a break statement inside a loop after

checking a condition and if it goes right, the control will come out of the loop.Eg:for(int i = i; i<=10 ; i++){ /*Printing Multiplication Table of 5 */

printf(“%d x 5 = %d”, i, i*5);if(i == 5) break;

}/*Here the loop will print only till 25 and later on i becomes 5 and it breaks the loop*/

23

• Continue Statement:If we place a continue statement inside a loop after checking a condition and if it goes right, the control leave rest of the loop body, update the loop variable and then continue the loop

for(int i = i; i<=10 ; i++){ /*Printing Multiplication Table of 5 */

printf(“%d x 5 = %d”, i, i*5);if(i == 5) break;

}/*Here the loop will not print 5*5 */

24

Functions• Functions are one of the most commonly used features in

the C Programming language. It helps users to separate blocks of codes which could be reused again and again.

A program using functions may look something like this:#include<stdio.h>int myFunction(int , int);void main( ){

------------------

} int myFunction(int x, int y){

int z;z = (x+y)*x;return z;

}

25

• Here the line int myFunction(int , int); is called function prototyping or declaration where we do tells the compiler that a function with a name myFunction exists and it takes two integer arguments. We need to add this if we define the function just after the main( )

• After the main we have defined the function myFunction and we have given the function body.

• The general syntax of defining a function is:<return-type> <function-name>(<parameter-list>){--Function Body--}

• Return-type is the data type of value returned by a function to the called program.

• If a function does not return a value, we do give its return type as void.

26

int factorial(int x){

if(x == 1 || x ==0)return 1;

elsereturn (x * factorial(x -1) );

}

• This is an example of a recursive function which does call itself. This is a powerful programming technique but it is least preferred in the embedded programming as it takes a lot of space in the system stack and memory is a main constraint in the Embedded Systems.

27

Arrays

• Arrays are continuous storage locations in memory which could be refered under a common name and could be used to store a collection of data of same data types.

• The syntax for declaration of array is:<data-type> <array-name>[<number-of elements>];

• Eg: int nos[20];• char name[30]; • The indexing of array starts from 0, so if we want to access the

first element, we give array[0];• There is no basic data type in C for storing strings, so we use

array of characters for storing string. The end of the string should have a null character .ie ‘\0’.

28

Structures

• Structures are user defined data types which could be used to group different data-types under a common name.

• Eg: struct student{

int roll_no;char name[20];char place[20];int age;

};• We create the elements of an array as follows:• struct student s;• We use dot( . ) operator to access each element in a structure.• Eg: s.age = 15;• n = s.roll_no;• We could also create array of structures : struct student s[40];

29

Pointers• Pointers are special variables which do hold the address of another

variable.• Eg:

int num = 25;int * ptr ; /* Declaring a pointer variable ptr */

ptr = &num; /* Assigning the address of variable num to ptr */print(“%d”, *ptr); /* Printing the value at the address in ptr through dereferencing*/

• Here we have created an integer num and a pointer variable ptr which could hold an address of a integer variable.

• We have assigned the address of num to ptr using the address of operator( & ).

• Using the dereferencing or value at operator ( * ) we have printed the value contained at the in ptr, which is equivalent as the value of num as ptr now has the address of variable num.

30

31

Beginning AVR µC Programming • AVR is a RISC µC ie. Reduced Instruction Set Computing. So the

number of instruction in the assembly for the µC will be much lesser as compared to CISC µCs. So it will take only lesser decoding time for instructions and will be comparatively faster for Embedded Systems.

• In this tutorial we will be using ATMEGA 16 and WinAVR

Programming environment with avrdude as programming tool. We will be using USBasp as the AVR Programmer.

• If you are using any other AVR µC then just refer to the manual and see if there are some differences.

• ATMEGA 16 has got 16 kB flash memory for storing the program. It has got four x eight bit ports which they do label as PA, PB, PC, PD

32

• Before going to the first example, let us get familiarized with the three types of basic port operating registers for AVR:

• DDRx (x = A / B / C / D ): It is called Data Direction Register. It is used to set whether a particular bit in a port is being used for input or output. If we give a high value for a bit then that bit will be used for out putting something in the later programs.

• Eg: DDRA = 0b00001111;• Here the first four bits (ie. bit 0 to bit 3) of port A is being

used for outputting something and the last four(bit 4 to bit7) is being used for inputting something.

• We could also write similarly in hexadecimal as: • DDRB = 0xf6;

33

• PORTx (x = A / B / C / D ): It is the Register which we use to output something into a port. As an example if we have set DDRA to have the bit 0 as output and if we want to set that to high we write as:

• PORTB = 0x01;

34

PINx (x = A / B / C / D ): It is used to read value from a register. as an example if we want to check the input in the most significant four bits of port C, we do write the program with the use of bitwise operator as follows:

if( (PINC & 0b11110000) = = 0b101010000 ){

-- do something --}

• The above usage of bitwise operator to mask the four lower

bits which we are not concerned about is called bit masking. If we AND a bit with 0, it will become 0 and if we OR a bit with 1, it will become one. In the later on programming examples we will encounter the usage of bitwise operators a lot many times.

35

36

Example 1: Lighting an LED with µC

• Circiut:

• Program:• #include <avr/io.h>• • void main()• {• DDRB = 0b00000001;//Setting Bit 0 for Out put• while(1)• {• PORTB = 0b00000001;//Setting Port B0 to High• }• }

37

• Program:#include <avr/io.h> void main(){DDRB = 0b00000001;//Setting Bit 0 for Out putwhile(1){PORTB = 0b00000001;//Setting Port B0 to High}}

• In the circuit given above, we have used a 8 MHz external crystal to clock the µC. There is an internal clock in a µC but its frequency is low limited (about 1MHz) and it is not precise. So we add an external crystal to the µC to make it run faster.

• The output coming from the µC is 5V and the LED needs just a 2 to 3 V voltage. So we use a 330Ohm resistor to reduce the voltage.

• Using the command PORT PORTB = 0b00000001; we do assign a high voltage to the 0 th bit of PORTB and so the LED keeps on lighting.

• Here you can see unlike the usual C-Program which goes sequentially and terminated after certain number of steps, the programs for a µC are generally written inside an infinite while loop so that it gets executed infinitely.

• Now we will change the code slightly with the same hardware to make the LED blink.

38

• Program:#include <avr/io.h>#include <util/delay.h>

void main(){ DDRB = 0b00000001; while(1) { PORTB = 0b00000001; _delay_ms(100); PORTB = 0b00000000; _delay_ms(100); }}

• Here we are using a _delay_ms( ) function which makes the µC do nothing for some milliseconds. So for using that function, we do include the header file delay.h

• When we program this, we could see the LED blinking.

39

Now we will try to add an external switch to our circuit and do something…

40

• In the above circuit, we have connected a switch to the PINB1. If the switch is not being pressed, then a high voltage will be dropped across the resistor and the PINB1 will be having a logical high voltage.

• If we press the switch then a logical 0 voltage will come to the PIN1 and we have added a capacitor across the switch to avoid de-bouncing.

Program:#include <avr/io.h>#include <util/delay.h> void main(){

DDRB = 0b00000001; //Here we are setting PB0 for outputwhile(1){ if( (PINB & 0b00000010) == 0b00000000) //Checking whether switch is pressed

{PORTB = 0b00000001;_delay_ms(20);PORTB = 0b00000000;_delay_ms(20);}else{PORTB = 0b00000001;_delay_ms(100);PORTB = 0b00000000;_delay_ms(100);}

}}

41

• We could make a slight modification in the program and we can give an internal pull up to avoid the external 10K pull up resistor.

#include <avr/io.h>#include <util/delay.h>void main(){ DDRB = 0b00000001; // setting PB0 for output

PORTB = 0b00000010; //Setting the PINB1 with a high voltage while(1) { PORTB |= 0b00000010; if( (PINB & 0b00000010) == 0b00000000) //Checking whether switch is pressed { PORTB = 0b00000001; _delay_ms(20); PORTB = 0b00000000; _delay_ms(20); } else { PORTB = 0b00000001; _delay_ms(100); PORTB = 0b00000000; _delay_ms(100); } }}· In the above program if we press the switch, then the LED will blink faster.

42

Interrupts…

43

• In a microcontroller or in any microprocessor, we could check the status of a device or input from a pin in two different ways:

• Polling• Interrupt Method

• In polling the µC periodically check for the input or status flags from the external peripheral to get the status of its working. In the case of interrupt method when the external (or even internal) peripheral needs the attention of the processor, it will trigger an interrupt and the processor will stop execution of the current statements and store the present program address in system stack, execute a set of codes called ISR (Interrupt Service Routine) associated with the particular interrupt and restores the lastly executed program from stack and continue its work.

44

In the following slides we will be demonstrating how we can make an external interrupt to trigger our ATMEGA16 µC. We will be connecting an external switch to the external interrupt 0 (INT0) of our µC and toggling the led connected to the circuit.

In order to trigger enable the external interrupt we must do three things mainly:1. Unmask the needed external interrupt in the GICR (General Interrupt Control Register).

Unmask the INT0 bit for enabling INT0 Unmask the INT1 bit for enabling INT1 Unmask the INT2 bit for enabling INT2

45

2. Set the interrupt sense bits in the MCUCR (MCU Control Register), ie. to enable interrupt when there is a change in voltage level / when there is a rising edge / falling edge etc.

3. Set the global interrupt enable bit in the SREG which is being done by calling the function sei( );

46

Toggling LED on External Interrupt INT0

47

Program:#include <avr/io.h>#include <util/delay.h>#include<avr/interrupt.h> void main(){

DDRB = 0b00000001;PORTB = 0b00000001;

GICR = 0b01000000; //Enabling external interrupt 0MCUCR = 0b00000011; //INT0 triggered on rising edgesei( );while(1){}

} ISR(INT0_vect) //Interrupt Service Routine for external Interrupt{

PORTB ^= 0b00000001;}

48

• Here we have included the interrupt.h header file which do contains the vector number and other interrupt related definitions for using external interrupts.

• In the circuit we have connected a switch to the INT0th pin with a 10K pull up resistor so that is we press switch it will become logical low and else it will be logical high.

• In GICR we have enabled just the external interrupt 0 ie. INT0.• We have set the MCUCR to trigger the INT0 on external

interrupt 0 on rising edge.• We have called the sei( ) interrupt enabler function.• We have used ISR(INT0_vect) to write the statements

associated with the INT0 interrupt. INT0_vect is the alias for interrupt vector number whose definition comes in the interrupt.h header file.

49

Interfacing LCD

• For interfacing LCD we will be using the header file lcd.h from http://www.jump.to/fleury and we will be calling the functions defined in that header file.

50

LCD Pin Connection

Vee is the Pin in the LCD used to set the contrast of the LCD. So use a resistance nearly 1 K with that to connect to Vcc.

51

Make sure to set your Clock speed properly in the lcd.h header file.

52

Sample Program:

#include <avr/io.h>#include <util/delay.h>#include "lcd.h“

int main(void){lcd_init(LCD_DISP_ON_CURSOR); /* initialize lcd, display on, cursor on for more options lcd_init(), view lcd.h file */ while(1) /* run continuously */ { lcd_clrscr(); /* clear screen of lcd */ lcd_home(); /* bring cursor to 0,0 */ lcd_puts("hello"); /* type something random */ lcd_gotoxy(0,1); /* go to 2nd row 1st col */ lcd_puts("maxEmbedded"); /* type something random */ _delay_ms(50); /* wait 50ms */ }}

53

• Outputing Integers:char buffer[10]; int n = 12345; itoa(n, buffer, 10);lcd_puts(buffer);

• Outputting Floats:

char buffer[10]; float f = 3.1415926; sprintf(buffer, "%f", f);lcd_puts(buffer);

54

Timers & Counters

55

Timers & Counters

• Timers and Counters are the one of the most commonly used complex peripheral in a microcontroller.

• They are used for getting time periods, generating pulse signals and also for measuring time period of pulses.

• There are two main TIMER/COUNTER in ATMEGA32 : TIMER0(8-Bit) and TIMER1(16-Bit)

• Timer0 will roll over after 255 and Timer1 will rollover after 65,535. So be careful about this roll over when using Timers in a µC.

• TCNT0 is the counter for TIMER0 ie. It is like a variable which counts with the oscillation of system clock and rolls over back to 0.

• Similarly TCNT1 is the counter for TIMER1.

56

Timer0:• Using timer 0 includes setting the appropriate values in the

Timer Counter Control Register ( TCCR0 ) mainly for setting the speed / frequency at which TCNT0 is counting.

57

Circuit

58

• void main()• {• DDRB = 0b00000011;• PORTB = 0b00000000; • TCCR0 = (1<<CS02) | (0<<CS01) | (0<<CS00); // 8MHz / 256 as prescaler• TCNT0 = 0; • int ctr1 = 0;• int sec_ctr = 0; • while(1)• { if(TCNT0 == 200)• { PORTB = 0b00000000;• TCNT0 = 0;• ctr1++;• if(ctr1 == 20)• { ctr1 = 0 ;• PORTB = 0b00000001;• sec_ctr++;• if(sec_ctr >= 60) //checking for elapsing of one minute• {• PORTB |= 0b00000010;• sec_ctr = 0;• _delay_ms(10);• }• }• }• }}

59

• An interrupt is also being generated when the overflow of Timer occurs.• We need to unmask the TIMER0 overflow interrupt in the TIMSK registers

and should use suitable ISRs.

60

#include <avr/io.h>#include <util/delay.h>#include<avr/interrupt.h>

int ctr1 = 0;int sec_ctr = 0;

void main(){ DDRB = 0b00000011; PORTB = 0b00000001; TCCR0 = (1<<CS02) | (0<<CS01) | (0<<CS00); TIMSK = 0x01; //Enabling TIM0 ovf interrupt sei(); int ctr1 = 0; int sec_ctr = 0; while(1) { //Do nothing… }}

ISR(TIMER0_OVF_vect){ TCNT0 = 0; PORTB = 0b00000000; ctr1++; if(ctr1 == 15) { ctr1 = 0 ; PORTB = 0b00000001; sec_ctr++; if(sec_ctr >= 60) //checking for

elapsing of one minute { PORTB |= 0b00000010; sec_ctr = 0; _delay_ms(10); } }

61

Timer 1• Use TCNT1 as timer variable and it will roll back after 65,535.• Make proper settings in TCCR1A & TCCR1B

62

Analogue to Digital Conversion(ADC)

63

ADC

• The world around us is analogue in nature and the microcontroller usually understands only digitial information .ie. Whether input is there or not.

• There is a built in Analogue to digital converter inside the microcontroller which could be used to read the input voltage given to the ADC pins of the µC.

• AVcc and AGND are the pins to power on the ADC peripheral and we use the voltage given in AREF as the analogue reference voltage.

• There is a 10 bit counter inside the µC for counting the ADC input as the fraction of AREF voltage. So the ADC has got a resolution of 10-bit and it has got an operational speed of 15kSPS (Kilo Samples per Second)

64

We need to set two registers for using ADC:i. ADCSRA – ADC Control and Status Register

ADEN: This bit is set to enable the ADC.ADSC: This bit is set to start an ADC ConversionADIF: ADC Interrupt flag set by the hardware when a conversion is over.ADIF: ADC Interrupt mask bit.ADSPx : ADC prescaler bit. ADC Sampling works well at a frequency range of 50kHz to 200kHz. So we need to prescale the system clock value down to a value within that frequency

65

• ii. ADMUX – ADC MultiplexerThis register is being mainly used to set the ADC source, ADC reference source and also the ADC bit alignment selector

66

• ADC Counter bit alignment selector bit - ADLAR

67

• ADC could be used in 8-bit and 10-bit modes.• We will be having ADCH and ADCL as the ADC

counter. If we are using the 8-bit mode then we could get the maximum reading as 255 and in 10bit mode we could get it as 1023.

• In 8 bit mode the input voltage will be (ADC_count * VREF) / 255

• In 10 bit mode the input voltage will be (ADC_count * VREF) / 1023

68

H/W for ADC

69

Program#include <avr/io.h>#include <util/delay.h>#include<avr/interrupt.h>

void main(){ DDRB = 0b00000111; //Green in PB0, Yellow in PB1, Red in PB2 PORTB = 0x00;

ADCSRA = (1<<ADEN) | (1<<ADSC) | (1<<ADIE);ADCSRA|= (1<<ADPS2)|(1<<ADPS1)|(0 << ADPS0); //Setting the prescalerADMUX = (1<<ADLAR)|(1<<MUX0)|(1<<MUX1)|(1<<MUX2); //ADC7 for I/P sei(); while(1) { }}

ISR(ADC_vect){ uint8_t x = ADCH; //Using the 8-bit ADC mode if( (((float)x*5)/255) > 3.5) { PORTB = 0x02; } else if( (((float)x*5)/255) < 1.5) { PORTB = 0x01; } else PORTB = 0x04; ADCSRA |= (1<<ADSC);

}

70

References

• http://www.newbiehack.com/• www.yazary.blogspot.com

• Embedded C Programming And the Atmel AVR

- By Richard H. Barnett, Larry O'Cull, Sarah Cox, Sarah Alison Cox

71

Thank You All…..

Jaydev E, Freeze Francis, Dhaneesh K, Surajnath P, Ananthu R Krishnan,

Siva Sankar

top related