Sei sulla pagina 1di 79

Embedded

Systems
Engr. Rashid Farid Chishti
chishti@iiu.edu.pk

Chapter 07: AVR Programming in C


International Islamic University H-10, Islamabad, Pakistan
http://www.iiu.edu.pk
Languages
 High Level Languages
 Easy to develop and update
 C Language
 Acceptable performance
 Easy to develop and update High Level Languages
(like VB, VC, C#)
 Portable
C Language
 Low Level Languages
Machine Language
 High performance
 Not portable
Why program the AVR in C ?
 It is easier and less time consuming to write in C than in Assembly.
 C is easier to modify and update.
 You can use code available in function libraries.
 C code is portable to other microcontrollers with little or no
modification.
 While Assembly language produces a hex file that is much smaller
than C.
 Programming in Assembly language is often tedious and time
consuming.
 C programming is less time consuming and much easier to write,
but the hex file size produced is much larger than if we used
Assembly language.
A simple C program
// Write a program that calculate the sum of {1,3,…,13,15}

int main ()
{
unsigned int I, Sum = 0;
for (int I = 1 ; I <= 15 ; I+=2)
sum += I;
while (1);
return 0;
}

4
Data Types in Arduino
Data Type Size Range
bool 1 byte true(1) or false(0)
byte 1 byte 0 ~ 28-1 = 0 to 255
unsigned char (8 bits)
char 1 byte (-27) ~ (+27-1) = -128 ~ +127
signed char (8 bits) Used for storing Characters
short 2 bytes (-215) ~ (+215-1) =
signed short (16 bits) -32,768 ~ +32,767
int 2 bytes (-215) ~ (+215-1) =
signed int (16 bits) -32,768 ~ +32,767
word 2 bytes 0 ~ 216-1 = 0 to 65,535
unsigned short
unsigned int
long 4 bytes (-231) ~ (+231-1) =
signed long (32 bits) -2,14,74,83,648 ~ +2,14,74,83,647
Data Types in Arduino
Data Type Size Range
unsigned long 4 bytes 0 ~ (232 - 1) =
(32 bits) 0 ~ 4,29,49,67,295
float 4 bytes -3.4028 × 1038 ~ 3.4028 × 1038
double (32 bits)

 Other useful data types are


 arrays e.g. char myStr[] = "hello world";
 string() e.g. string str = "Hello String";
 void e.g. void setup() { // ... }
 sizeof() e.g. sizeof(str);
 const e.g. const float pi = 3.14;
 static e.g. static int lenth;
 PROGMEM e.g. const PROGMEM char msg[]
= {"I AM PREDATOR"};
ATmega328 Pinout
 Vital Pins:
 Power
+5V
 VCC
 Ground
 Crystal
 XTAL1
 XTAL2
 Reset
+5V

+5V

 I/O pins
 PORTB, PORTC, and PORTD
 Internal ADC pins
 AREF, AVCC, ADCn

7
ATmega328 Simplest Connection
Vcc

ATmega328

7
VCC
Vcc 20
AVCC

22pF
10K
10
XTAL1

1 16MHz
RESET
XTAL2 9

Reset 22pF
Button
8
GND
22
GND

8
I/O Ports in AVR
 ATmega328 is 28-pin chip
 A total of 23 pins are
set aside for the 3 ports
PORTB, PORTC, PORTD.
 Each port has 3 I/O reg-
isters associated with it
 They are designated as
DDRx (Data Direction Reg-
ister), PORTx(Data Reg-
ister), and PINx(Port INput pins).
 For example, for Port B we have PORTB, DDRB,
PINB registers.
 each of the I/O registers is 8 bits wide, and
each port has a maximum of 8 pins.
The structure of IO pins
I/O Ports in AVR
Port Mem. Usage Port Mem. Usage
Address Address
PINB 0x23 Input PIND 0x29 Input
DDRB 0x24 Direction DDRD 0x2A Direction
PORTB 0x25 Output PORTD 0x2B Output
PINC 0x26 Input
DDRC 0x27 Direction
PORTC 0x28 Output
Data Direction Register
( DDRx
 )
DDRx register is used for the purpose of
making a given port an input or output
port.
 Setting (writing a one) to a bit in the
DDRx configures the pin as an Output.
 Clearing (writing a zero) to a bit in the
DDRx configures the pin as an Input. e.g.
 Imagine a person who has 0 dollars, he can
only get money, not give it. Similarly
when DDR contains 0’s the port gets data.
DDRC = 0xFF;
// Configure PRTC as output

DDRB = 0x00;
// Configure PRTB for input
Port Input Pin Register ( PINx )
 To read the data present at the pins, we
should read the PINx register.
 To send data out to pins we use the PORTx
register .
 There is a pull-up resistor for each of
the AVR pins.

Different States of a Pin in the AVR Microcontroller


DDRx
PORTx
0 1
0 Input & high impedance Out 0
1 Input & Pull-up Out 1
Data Register ( PORTx )
 The PORTx register controls if the pull-up is activated or not
 Writing a 1 to the PORTx register will activate the internal pull-
up resistor
 Writing a 0 to the PORTx register will deactivate or turn off the
internal pull-up resistor

DDB = 0x00;
//configure PORTB for input
PORTB = 0xFF;
//turn-on the pull-up resistors
Example

15
Example 1
// Write a program that sends values 0 to 9 on Port B continuously.

// the setup function runs once when you press


// reset or power the board
void setup(){
DDRB = 0xFF;
}

// the loop function runs over and over again


// forever
void loop(){
for (int i = 0; i <= 9; i++)
PORTB = i;
}

16
Example 2
// Write a program that sends values 00-FF to Port D continuously.

// the setup function runs once when you press


// reset or power the board
void setup(){
DDRD = 0xFF;
}

// the loop function runs over and over again


// forever
void loop(){
PORTD++;
}

17
Example 3
// Write a program to toggle Port D 200 times only.

// the setup function runs once when you press


// reset or power the board
void setup(){
DDRD = 0xFF;
PORTD = 0xAA;
for (int i = 0; i <= 200; i++)
PORTD = ~PORTD;
}

// the loop function runs over and over again


// forever
void loop(){
}

18
Time Delay in Arduino
 You can use predefined functions of Arduino to make
time delays
 Syntax delay(ms)
 Parameters ms: the number of milliseconds to
pause (unsigned long)
 Returns Nothing

19
Example 4
// Write a program to toggle all bits of PORTD 50,000 times only.

void setup(){
DDRD = 0xFF; // PORTD is output
for(unsigned int i=0; i<50000 ; i++){
PORTD = ~PORTD;
delay(10); // put 10 ms sec delay
}
}

void loop(){
}

// Run the above program on your simulator to see how Port D toggles
// Notice that the maximum value for unsigned int is 65,535.

20
Example 5
// Write a program to toggle all bits of PORTD 100,000 times only.

void setup(){
DDRD = 0xFF; // PORTD is output
for(long i=0; i<100000 ; i++){
PORTD = ~PORTD;
delay(10); // put 10 ms sec delay
}
}

void loop(){
}

// Run the above program on your simulator to see how Port D toggles
// Notice that the maximum value for long is 2,14,74,83,647.

21
Example 6
// Write a program to send string a “hello world” to Port D
// only once.

char msg[] = "hello world";

void setup(){
DDRD = 0xFF; // PORTD is output
for(int i=0; msg[i]; i++){ // loop breaks at NULL
PORTD = msg[i] ; // send the character to PORTB
delay(1000); // put 1 sec delay
}
}

void loop(){
}

22
Example 7
// Write a program to send following bytes to Port D
// {0x01, 0x02,0x04,0x08,0x10,0x20,0x40,0x80} continuously.

byte num[] = {0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80};


const int PAUSE = 500;
int i;

void setup(){
DDRD = 0xFF; // PORTD is output
}
void loop(){
for( i=0; i<8; i++){ // loop breaks at i=8
PORTD = num[i] ; // send Byte to PORTB
delay(PAUSE);
}
for( i=7; i>=0; i--){ // loop breaks at i=-1
PORTD = num[i] ; // send Byte to PORTB
delay(PAUSE);
}
} 23
Bit-wise logical operators

~ 1110 1011
-----------
0001 0100
= 0x14

1110 1011 1110 1011 1110 1011


& 1100 1110 | 1100 1110 ^ 1100 1110
----------- ----------- -----------
1100 1010 1110 1111 0010 0101
= 0xCA = 0xEF = 0x25
Example 8
// Write a Program to Show the Result of
// (a) 1110 1011 & 1100 1110 on PORTD
// (b) 1110 1011 | 1100 1110 on PORTD
// (c) 1110 1011 ^ 1100 1110 on PORTD
// with 5 sec delay after each output

const int PAUSE = 5000;


int i;

void setup(){
DDRD = 0xFF; // PORTD is output
}

void loop(){
PORTD = 0xEB & 0xCE ; delay(PAUSE);
PORTD = 0xEB | 0xCE ; delay(PAUSE);
PORTD = 0b11101011 ^ 0xCE ; delay(PAUSE);
}

25
Example 9
// Write a Program to toggle only lower 4 bits of PORTD with 1 sec
// delay without disturbing the higher 4 bits of PORTD.
// Initial Value of PORTD is 0xFF.

const int PAUSE = 1000;


int i;

void setup(){
DDRD = 0xFF; // PORTD is output
PORTD = 0xAA; // Initialize PORTD with 0xFF
}

void loop(){
PORTD = PORTD ^ 0x0F ; delay(PAUSE);
}

26
Simple Shift Operations in AVR
 data >> number of bits to be shifted right
 data << number of bits to be shifted left

1110 0000 >> 3 0000 0001 << 2


-------------- --------------
0001 1100 0000 0100
= 0x1C = 0x04
Example 10
// Write a Program to Show the Result of
// (a) 1110 0000 >> 3 on PORTD
// (a) 0000 0001 << 2 on PORTD
// with 3 sec delay after each output

const int PAUSE = 3000;


int i;

void setup(){
DDRD = 0xFF; // PORTD is output
}

void loop(){
PORTD = 0b11100000 >> 3; delay(PAUSE);
PORTD = 0b00000001 << 2; delay(PAUSE);
}

28
Example 11
// 8 LEDs are connected to each pin of Port D. Write a program to
// turn on each LED on PORTD from pin PD0 to PD7 with some delay.

const int PAUSE = 500;

void setup(){
DDRD = 0xFF; // PORTD is output
}

void loop(){
for(int i =0; i<8; i++){ // loop breaks at i=8
PORTD = 1<<i ; // Turn On One LED at a time
delay(PAUSE);
}
}

29
Setting a bit in a Byte to 1
 We can use | operator to set a bit of a byte to 1

xxxx xxxx xxxx xxxx


| 0001 0000 | 1<<4
OR
------------ ------------
xxx1 xxxx xxx1 xxxx

PORTB |= (1<<4); //Set bit 4 (5th bit) of PORTB


Clearing a bit in a Byte to 0
 We can use & operator to clear a bit of a byte to
0
xxxx xxxx xxxx xxxx
& 1110 1111 & ~(1<<4)
OR
------------ ------------
xxx0 xxxx xxx1 xxxx

PORTB &= (1<<4); //Clear bit 4 (5th bit) of PORTB


Checking a bit in a Byte
 We can use & operator to see if a bit in a byte is
1 or 0
xxxx xxxx xxxx xxxx
& 0001 0000 & (1<<4)
OR
------------ ------------
000x 0000 000x 0000

If(PINC & (1<<4)) // Check if the bit 4


// (5th bit) of PINC Register
// is 1
Example 12
// A Push Button is connected to PB4 with other end connected to
// ground. Write a program to send 0x0F on PORTD when the input on
// PB4 is logic 0 and 0xF0 otherwise.

void setup(){
DDRB = DDRB & 0b11101111 ; // PB4 as input
PORTB = PORTB | 0b00010000 ; // Enable Pull-up at PB4
DDRD = 0xFF ; // PORTD as output
}

void loop(){
if( PINB & 0b00010000) // if we get logic 1 at PB4
PORTD = 0xF0 ; //
else
PORTD = 0x0F ; //
} 33
Example 13
// 1 LED is connected to PORTB.5(PB5). A Push Button is connected
// to PB4 with other end connected to ground. Write a program to
// turn ON LED when the input on
// PB5 is logic 0 and turn OFF LED
// otherwise.

void setup(){
DDRB = DDRB | 0b00100000 ; // PB5 as output
DDRB = DDRB & 0b11101111 ; // PB4 as input
PORTB = PORTB | 0b00010000 ; // Enable Pull-up at PB4
}

void loop(){
if( PINB & 0b00010000) // if we get logic 1 at PB4
PORTB = PORTB & 0b11011111 ; // Turn OFF LED
else
PORTB = PORTB | 0b00100000 ; // Turn ON LED
} 34
Example 14
// 1 LED is connected to PORTB.5(PB5). A Push Button is connected
// to PB4 with other end connected to ground. Write a program to
// turn ON LED when the input on
// PB5 is logic 0 and turn OFF LED
// otherwise.
// Use Shift Operators for
// masking
#define LED_PIN 5
void setup(){
DDRB = DDRB | (1<<LED_PIN) ; // PB5(LED) as output
DDRB = DDRB & ~(1<<4) ; // PB4 as input
PORTB = PORTB | (1<<4) ; // Enable Pull-up at PB4
}

void loop(){
if( PINB & (1<<4)) // if we get logic 1 at PB4
PORTB = PORTB & ~(1<<LED_PIN) ; // Turn OFF LED
else
PORTB = PORTB | (1<<LED_PIN) ; // Turn ON LED
} 35
36
37
38
pinMode() function in Arduino
 pinMode() Configures the specified pin to behave either
as an input or an output.

 Syntax pinMode(pin , mode)


 Parameters
 pin: the number of the pin whose mode you wish to
set
 mode : INPUT, OUTPUT, or INPUT_PULLUP.
 Returns Nothing

39
digitalWrite() function in Arduino
 digitalWrite() Writes a HIGH or a LOW value to a digital
pin.

 Syntax digitalWrite (pin , value)


 Parameters
 pin: the pin number
 value : HIGH or LOW.

 Returns Nothing

40
digitalReD() function in Arduino
 digitalRead() Reads the value from a specified digital pin,
either HIGH or LOW.

 Syntax digitalRead (pin)


 Parameters
 pin: the number of the digital pin you want to read

 Returns HIGH or LOW.

41
Example 15
// Write a program to blink on board LED with some delay in Adriano

const unsigned int LED_PIN = 13;


const unsigned int PAUSE = 500;

void setup() {
pinMode(LED_PIN, OUTPUT);
}
void loop() {
digitalWrite(LED_PIN, HIGH);
delay(PAUSE);
digitalWrite(LED_PIN, LOW);
delay(PAUSE);
}

42
Example 16
// Write a program to Read input from pin 7 and send it to pin 13

int ledPin = 13; // LED connected to digital pin 13


int inPin = 7; // pushbutton connected to digital pin 7
int val = 0; // variable to store the read value

void setup() {
pinMode(ledPin, OUTPUT); // sets the digital pin 13 as output
pinMode(inPin, INPUT); // sets the digital pin 7 as input
}

void loop() {
val = digitalRead(inPin); // read the input pin
digitalWrite(ledPin, val); // sets the LED to the button's value
}

43
Example 17
// Write a program to read PB3 and PB4 of PORTB and issue an ASCII
// character to Port D

void setup(){
DDRB = DDRB & 0b11100111 ; // Set PB3 and PB4 as input
PORTB = PORTB | 0b00011000; // Enable Pull-up at PB3 and PB4
DDRD = 0xFF; // Set PORTD as output port
}

void loop(){
switch( PINB & 0b0001 1000){ // make decision
case(0b00000000): PORTD = '0'; break; // issue ASCII 0
case(0b00001000): PORTD = '1'; break; // issue ASCII 1
case(0b00010000): PORTD = '2'; break; // issue ASCII 2
case(0b00011000): PORTD = '3'; break; // issue ASCII 3
}
}

44
Example 17 Simulation in Proteus

45
Example 18
// Write a program to monitor bit 3 of Port B. If it is 1 make bit 4
// of Port B input; otherwise, change pin 4 of Port B to output.

void setup(){
DDRB = DDRB & ~(1<<3) ; // Set PB3 as input
PORTB = PORTB | (1<<3) ; // Enable Pull-up at PB3
}

void loop(){
if( PINB & (1<<3)) // if input pin is logic 1
DDRB = DDRB & ~(1<<4) ; // Set PB4 as input pin
else
DDRB = DDRB | (1<<4) ; // Set PB4 as output pin
}

46
BCD, Packed BCD and ASCII
conversion.

ASCII and BCD Codes for Digits 0–9

BCD Codes
Packed BCD

BCD1 BCD0
Example 19
// Write a program to convert packed BCD 0x29 to ASCII and display
// the bytes on PORTC with 2 sec delay.

byte P_BCD = 0x29, L, R;

void setup(){
DDRD = 0xFF ; // Set Port D as output port
R = P_BCD & 0x0F; // Clear upper 4 bits
R = R | 0x30; // Make it ASCII
L = P_BCD & 0xF0; // Clear lower 4 bits
L = L >> 4; // Shift it to lower 4 bits
L = L | 0x30; // Make it ASCII
} 0x29 0x29
0xF0 & 0x0F &
void loop(){ ---- ----
PORTD = L; delay(2000); 0x20 >> 4 0x09
PORTD = H; delay(2000); = 0x02 0x30 |
} ---- ----
0x22 0x39
L = '2' R ='9' 48
Example 20
// Write a program to convert to convert ASCII digits of ‘2’ and ‘9’
// to packed BCD and display Packet BCD number on PORTD.

byte P_BCD, L = '2', R = '9';


void setup(){
DDRD = 0xFF ; // Set Port D as output port
L &= 0x0F; // Clear upper 4 bits
L <<= 4; // Shift it to upper 4 bits
R &= 0x0F; // Clear upper 4 bits
P_BCD = L | R; // Combine two to make packed BCD
PORTD = P_BCD; // Show on PORTD
0x22 0x39
} 0x0F & 0x0F &
---- ----
void loop(){ 0x02 << 4 R = 0x09
L = 0x20
}
P_BCD = L | R
= 0x20 | 0x09
= 0x29 49
Example 21
// Write a program that has two BCD numbers 0x74. Swap these numbers
// to 0x74 and show the answer on PORTD.

byte P_BCD = 0x74, L , R;

void setup(){
DDRD = 0xFF ; // Set Port D as output port
R = P_BCD & 0x0F; // R = 0x04
R = R << 4; // R = 0x40
L = P_BCD & 0xF0; // L = 0x70
L = L >> 4; // L = 0x07
PORTD = L|R; // PORTD = 0x47 0x74 0x74
} 0xF0 & 0x0F &
---- ----
void loop(){ 0x70 >> 4 0x04 << 4
L = 0x07 R = 0x40
}
PORD = L | R
= 0x07 | 0x40
= 0x47 50
Example 22
// Write a program to convert 0b11111101 (= 0xFD = 253) to decimal
// and display each digit after two sec delay on PORTD.

byte N = 0xFD, D0,D1,D2;

void setup(){
DDRD = 0xFF ; // Set Port D as output port
D0 = N % 10; N /= 10; // D0 = 3, N = 25
D1 = N % 10; N /= 10; // D1 = 5, N = 2
D2 = N; // D2 = 2
}

void loop(){
PORTD = D2; delay(2000); // Show 2
PORTD = D1; delay(2000); // Show 5
PORTD = D0; delay(2000); // Show 3
}

51
Check Sum
 To detect data corruption
 Calculating checksum byte:
 Add the bytes together and drop the carries
 Take the 2’s complement of the total sum
 Testing checksum
 Add the bytes together and drop the carries
 Add the checksum byte to the sum
 If the result is not zero, data is corrupted

52
Check Sum Byte in ROM
 Add the bytes together and drop the carries.
 Take the 2's complement of the total sum.
 This is the checksum byte, which becomes the last byte of the
series.
 E.g. For 25H, 62H, 3FH, and 52H
sum = 25H, 62H, 3FH, and 52H = 118H
discard caries, sum = 18H
checksum = ~sum + 1
= ~(18H) + 1
= E7 + 1 = E8
 Error = 25H + 62H + 3FH + 52H + E8 = 200
 After discarding carries if remaining 8-bit answer is zero that
means no error.
Example 23
// Write program to program to calculate the checksum byte for
// {0x25, 0x62, 0x3F, 0x52} and show it on PORTD

byte data[] = {0x25, 0x62, 0x3F, 0x52}, sum = 0,check_sum;

void setup(){
DDRD = 0xFF ; // Set Port D as output port
for(int i=0; i<4; i++) // loop for i= 0 to 3
sum += data[i] ; // add them together sum = 0x18
check_sum = ~sum + 1; // check_sum = ~ 0x18 + 1 = 0xE8
PORTD = check_sum; // PORTD = 0xE8
}

void loop(){
}

54
Example 24
// Write a program to add the checksum byte 0xE8 with data
// {0x25, 0x62, 0x3F, 0x52}. If the data is good, send ASCII
// character 'G'(0x47) to PORTD. Otherwise, send 'B'(0x42) to PORTD.

byte data[] = {0x25, 0x62, 0x3F, 0x52}, sum = 0, check_sum = 0xE8;

void setup(){
DDRD = 0xFF ; // Set Port D as output port
for(int i=0; i<4; i++) // loop for i= 0 to 3
sum += data[i] ; // add them together sum = 0x18
sum += check_sum; // check_sum = 0x18 + 0xE8 = 0x00
PORTD = sum ? 'B':'G'; // PORTD = ‘G’ if sum == 0x00
}

void loop(){
}

55
Memory Types In AVR
 Flash Memory
 Not deleted when power is off
 Big in size
 Suitable for codes, tables and fixed data
 EEPROM
 Not deleted when power is off
 Not very big in size
 Suitable for small data that may be modified but should not
be lost when power is off
 RAM
 deleted when power is off
 Suitable for storing the data we want to manipulate
because we have fast access to read or modify them.
Accessing Flash Memory
 You can Store data in flash (program) memory instead of
SRAM using the keyword PROGMEM.
 the keyword PROGMEM tells the compiler "put this
information into flash memory", instead of into SRAM.
 #include <avr/pgmspace.h>
 Syntax: const dataType variableName[] PROGMEM =
{data0, data1, data3…};
 PROGMEM can also be used on a single variable.
 Using PROGMEM is also a two-step procedure. After
getting the data into Flash memory, it requires special
methods (functions), also defined in the pgmspace.h
library, to read the data from program memory back into
SRAM, so we can do something useful with it. 57
Accessing Flash
 These are
 pgm_read_byte(address_short)
 pgm_read_byte_near(address_short)
 pgm_read_byte_far(address_long)
 pgm_read_word(address_short)
 pgm_read_word_near(address_short)
 pgm_read_word_far(address_long)
 pgm_read_dword(address_short)
 pgm_read_dword_near(address_short)
 pgm_read_dword_far(address_long)
 pgm_read_float(address_short)
 pgm_read_float_near(address_short)
 pgm_read_float_far(address_long)
 pgm_read_ptr(address_short)
 pgm_read_ptr_near(address_short)
 pgm_read_ptr_far(address_long)

58
Example 25
// Write a program to store {5,6,7,4} in Flash and then read and
// show each byte on PORTD with 1 sec delay.

#include <avr/pgmspace.h>
const byte PROGMEM lookup[] ={5,6,7,4};

void setup(){
DDRD = 0xFF ; // Set Port D as output port
}

void loop(){
for(int i=0; i<4; i++){ // loop from i= 0 to 3
PORTD = pgm_read_byte(&lookup[i]);
delay(1000);
}
}

59
Example 26
// Write a program to store “ABC” in Flash and then read and
// show each byte on PORTD with 1 sec delay.

#include <avr/pgmspace.h>
const char PROGMEM msg[] ="ABC";

void setup(){
DDRD = 0xFF ; // Set Port D as output port
}

void loop(){
for(int i=0; i<3 ; i++){ // loop for i= 0 to 3
PORTD = pgm_read_byte_near(msg + i);
delay(1000);
}
}

60
EEPROM
 EEPROM isEEPROM
a place to Register
Address store (EEAR)
data. It is not
EEPROM Data Register (EEDR)
deleted when power is off
EEPROM Control Register (EECR)
 ATmega328 has 1024 bytes of EEPROM
 In AVR 3 registers are dedicated to EEPROM
 EEARH:EEARL
 EEDR
 EECR

61
Accessing EEPROM in AVR
 Every member of the AVR microcontrollers has some amount
of on-chip EEPROM.
 The data in SRAM will be lost if the power is disconnected.
 EEPROM memory can save stored data even when the power
is cut off.
 The Size of EEPROM in different AVR Micro-controllers is given
below

Chip Bytes Chip Bytes Chip Bytes

ATmega8 512 ATmega 16 512 ATmega328 1024

ATmega64 2048 ATmegal28 4096 ATmega256RZ 4096

ATmega640 4096 ATmegal280 4096 ATmega2560 4096


EEPROM Registers
 There are three I/O registers that are directly
related to EEPROM. These are
 EECR (EEPROM Control Register)

 EEDR (EEPROM Data Register)

 EEARH-EEARL (EEPROM Address Register High-Low)

 EEPROM Data Register (EEDR)


To Read/write data to EEPROM, you have to
Read/write to the EEDR register.
 EEPROM Address Register (EEARH and EEARL)
 The EEARH:EEARL registers together make a 16-bit
register to address each location in EEPROM memory
space.
 When you want to read from or write to EEPROM, you
should load the EEPROM location address in EEAR.
EEPROM Registers
 Only 10 bits of the EEAR registers are used in ATmega328.
Because ATmega328 has 1024-byte EEPROM locations,
 ATmega16 has 512 bytes of EEPROM So 9 bits of the EEAR
registers are used

Bit 15 14 13 12 11 10 9 8
EEARH - - - - - - EEAR9 EEAR8

EEARL EEAR7 EEAR6 EEAR5 EEAR4 EEAR3 EEAR2 EEAR1 EEAR0

Bit 7 6 5 4 3 2 1 0
Figure 6-15: EEPROM Address Register

 EEPROM Control Register (EECR)


The EECR register is used to select the kind of operation to
perform on. The operation can be start, read, and write.
EEPROM Registers
 The bits of the EECR register are as follows:
 EEPROM Read Enable (EERE): If EEPE is zero, Setting EERE bit
to one will cause a read operation. When a read operation
starts, one byte of EEPROM will be read into the EEPROM
Data Register (EEDR). The EEAR register specifies the address
of the desired byte.
 EEPROM Program Enable (EEPE) and EEPROM Master
Program Enable (EEMPE): When EEMWE is set,then within
four clock cycles setting EEPE will start a write operation. If
EEMPE is zero, setting EEPE to one will have no effect.

EECR - - EEPM1 EEPM0 EERIE EEMPE EEPE EERE

Bit 7 6 5 4 3 2 1 0
Figure 6-16: EEPROM Control Register
EEPROM Registers
 The When you set EEMPE to one, the hardware clears the bit
to zero after four clock cycles. This prevents unwanted write
operations on EEPROM contents.
 Notice that you cannot start read or write operations before
the last write(program) operation is finished. You can check
for this by polling the EEPE bit. If EEPE is zero it means that
EEPROM is ready to start a new read or write(program)
operation.
 EEPROM Ready Interrupt Enable (EERIE): This will be
explained later on. In Figure 6-16, bit number 6 and 7 of EECR
are unused at the present time and are reserved.
EEPROM Registers
 EEPROM Programming Mode Bits (EEPM1:EEPM0): These
bits define which programming action that will be triggered
when writing EEPE.
 While EEPE is set, any write to EEPMn will be ignored.
 During reset, the EEPMn bits will be reset to 0b00 unless the
EEPROM is busy programming.
Programming the AVR to Write on EEPROM
 To write on EEPROM the following steps should be followed.
1. Wait until EEPE becomes zero.
while(EECR & (1<<EEPE));
2. Write new EEPROM address to EEAR (optional).
EEAR = Address;
3. Write new EEPROM data to EEDR (optional).
EEDR = Data;
4. Set EEMPE bit to one.
EECR |= (1<<EEMPE);
5. Within four clock cycles after setting EEMPE, set EEPE to
one.
EECR |= (1<<EEPE);
68
Programming the AVR to Write on EEPROM
void EEPROM_Write(unsigned int Address, byte Data)
{
// Wait for completion of previous write
while(EECR & (1<<EEPE));
// Set up address and Data Registers
EEAR = Address; EEDR = Data;
// Write logical one to EEMPE
EECR |= (1<<EEMPE);
// Start EEPROM write by setting EEPE
EECR |= (1<<EEPE);
}

69
Programming the AVR to Read from EEPROM
 To read from EEPROM the following steps should be followed.
1. Wait until EEWE becomes zero.
while(EECR & (1<<EEPE));

2. Write new EEPROM address to EEAR.


EEAR = Address;

3. Set the EERE bit to 1


EECR |= (1<<EERE);

4. Read EEPROM data from EEDR.


return EEDR;
70
Programming the AVR to Read from EEPROM
byte EEPROM_Read(unsigned int Address){
// Wait for completion of previous write
while(EECR & (1<<EEPE));
// Set up address register
EEAR = Address;
// Start eeprom read by writing EERE
EECR |= (1<<EERE);
// Return data from Data Register
return EEDR;
}

71
Example 27
// Write a program to store ‘a' into location Ox005F of EEPROM.

void EEPROM_Write(unsigned int Address, byte Data){


while(EECR & (1<<EEPE)); // Wait for completion of previous write
EEAR = Address; EEDR = Data; // Set up address and Data Registers
EECR |= (1<<EEMPE); // Write logical one to EEMPE
EECR |= (1<<EEPE); // Start EEPROM write by setting EEPE
}

void setup(){
EEPROM_Write(0x5F, 'a');
}

void loop(){

72
Example 28
// Write a program to read the content of location 0x005F of EEPROM
// into PORTD.

byte EEPROM_Read(unsigned int Address){


while(EECR & (1<<EEPE)); // Wait for completion of previous write
EEAR = Address; // Set up address register
EECR |= (1<<EERE); // Start EEPROM read by writing EERE
return EEDR; // Return data from Data Register
}

void setup(){
DDRR = 0xFF; // Set PORTD as Output Port
PORTD = EEPROM_Read(0x5F);
}

void loop(){

73
Example 29 (1/2)
// Write a program to write two bytes at address 0x10 and 0x12 of
// EEPROM and then read the data from these two addresses and then
// show this data on PORTD with one sec delay.

void EEPROM_Write(unsigned int Address, byte Data){


while(EECR & (1<<EEPE)); // Wait for completion of previous write
EEAR = Address; EEDR = Data; // Set up address and Data Registers
EECR |= (1<<EEMPE); // Write logical one to EEMPE
EECR |= (1<<EEPE); // Start EEPROM write by setting EEPE
}

byte EEPROM_Read(unsigned int Address){


while(EECR & (1<<EEPE)); // Wait for completion of previous write
EEAR = Address; // Set up address register
EECR |= (1<<EERE); // Start EEPROM read by writing EERE
return EEDR; // Return data from Data Register
}

74
Example 29 (2/2)
void setup(){
DDRD = 0xFF; // Set PORTD as Output Port
EEPROM_Write(0x10, 'a');
EEPROM_Write(0x12, 'b');
}

void loop(){
PORTD = EEPROM_Read(0x10);
delay(1000);
PORTD = EEPROM_Read(0x12);
delay(1000);
}

75
Example 30
// Write a program to write a string “www.iiu.edu.pk” to EEPROM
// starting from address 0x100 .
void EEPROM_Write(unsigned int Address, byte Data){
while(EECR & (1<<EEPE)); // Wait for completion of previous write
EEAR = Address; EEDR = Data; // Set up address and Data Registers
EECR |= (1<<EEMPE); // Write logical one to EEMPE
EECR |= (1<<EEPE); // Start EEPROM write by setting EEPE
}
void EEPROM_Write_Str(unsigned int Address, byte Data[]){
while(Data[Address]) // loop until we find NULL in the string
EEPROM_write(Address++, Data[i]); // Write then increment address
EEPROM_write(Address, 0); // Write NULL also
}

void setup(){
EEPROM_Write(0x100, "www.iiu.edu.pk");
}

void loop(){
}
76
Using EEPROM Library in Arduino
 You can Store data in EEPROM memory instead of SRAM
using the keyword EEMEM.
 the keyword EEMEM tells the compiler "put this
information into EEPROM", instead of into SRAM.
 #include <avr/eeprom.h>
 Syntax: dataType variableName[] EEMEM =
{data0, data1, data3…};
 EEMEM can also be used on a single variable.
 Using EEMEM is also a two-step procedure. After getting
the data into EEPROM, it requires special methods
(functions), also defined in the eeprom.h library, to read
the data from EEPROM back into SRAM, or to write data
to EEPROM. 77
Using EEPROM Library in Arduino
 These are
 uint8_t eeprom_read_byte (const uint8_t *__p)
 uint16_t eeprom_read_word (const uint16_t *__p)
 uint32_t eeprom_read_dword (const uint32_t *__p)
 float eeprom_read_float (const float *__p)
 void eeprom_read_block (void *__dst, const void *__src, size_t __n)
 void eeprom_write_byte (uint8_t *__p, uint8_t __value)
 void eeprom_write_word (uint16_t *__p, uint16_t __value)
 void eeprom_write_dword (uint32_t *__p, uint32_t __value)
 void eeprom_write_float (float *__p, float __value)
 void eeprom_write_block (const void *__src, void *__dst, size_t __n)
 void eeprom_update_byte (uint8_t *__p, uint8_t __value)
 void eeprom_update_word (uint16_t *__p, uint16_t __value)
 void eeprom_update_dword (uint32_t *__p, uint32_t __value)
 void eeprom_update_float (float *__p, float __value)
 void eeprom_update_block (const void *__src, void *__dst, size_t __n)
78
Example 31
// Write a program to write a byte to EEPROM then read it and show it
// on PORTD.

#include <avr/eeprom.h>

byte EEMEM myByte; // reserve a location in EEPROM

void setup(){
DDRD = 0xFF;
eeprom_write_byte(&myByte,'G'); // Write to EEPROM
PORTD = eeprom_read_byte(&myByte); // Read from EEPROM
}

void loop(){
}

79

Potrebbero piacerti anche