Вы находитесь на странице: 1из 33

Digital I/O – Manipulare de porturi

Refference:

Registri de porturi
Port registers allow for lower-level and faster manipulation of the i/o pins of the microcontroller on an Arduino board.
The chips used on the Arduino board (the ATmega8 and ATmega168) have three ports:

 B (digital pin 8 to 13)


 C (analog input pins)
 D (digital pins 0 to 7)

Each port is controlled by three registers, which are also defined variables in the Arduino language.

The DDR register, determines whether the pin is an INPUT or OUTPUT.


The PORT register controls whether the pin is HIGH or LOW
The PIN register reads the state of INPUT pins set to input with pinMode(). The maps of the ATmega8 and ATmega168
chips show the ports. The newer Atmega328p chip follows the pinout of the Atmega168 exactly.

DDR and PORT registers may be both written to, and read.
PIN registers correspond to the state of inputs and may only be read.

PORTD maps to Arduino digital pins 0 to 7

DDRD - The Port D Data Direction Register - read/write


PORTD - The Port D Data Register - read/write
PIND - The Port D Input Pins Register - read only

PORTB maps to Arduino digital pins 8 to 13 The two high bits (6 & 7) map to the crystal pins and are not usable
DDRB - The Port B Data Direction Register - read/write
PORTB - The Port B Data Register - read/write
PINB - The Port B Input Pins Register - read only

PORTC maps to Arduino analog pins 0 to 5. Pins 6 & 7 are only accessible on the Arduino Mini
DDRC - The Port C Data Direction Register - read/write
PORTC - The Port C Data Register - read/write
PINC - The Port C Input Pins Register - read only

DDRD is the direction register for Port D (Arduino digital pins 0-7). The bits in this register control whether the pins in
PORTD are configured as inputs or outputs so, for example:

DDRD = B11111110; // sets Arduino pins 1 to 7 as outputs, pin 0 as input

DDRD = DDRD | B11111100; // this is safer as it sets pins 2 to 7 as outputs

// without changing the value of pins 0 & 1, which are RX & TX

//See the bitwise operators reference pages and The Bitmath Tutorial in the Playground

PORTD is the register for the state of the outputs. For example;

PORTD = B10101000; // sets digital pins 7,5,3 HIGH

Title: 1_Input_configurare_1.ino

Purpose:

This is an example how to configure the Atmega328P (AVR) to lit a LED on PORTB bit 5, connected to digital pin 13 (D13
on Arduino Uno and Nano). The PB5 state, acting as output, depends on PD2 state, acting as input with internal "PULL
UP" resistor.

Connect a button between digital D2 and GND.

2^7 2^6 2^5 2^4 2^3 2^2 2^1 2^0

HEX 0x 8 4 2 1 8 4 2 1

HEX 0x 8 4 2 1 8 4 2 1

bit7 bit6 bit5 bit4 bit3 bit2 bit1 bit0

DDRx DDx7 DDx6 DDx5 DDx4 DDx3 DDx2 DDx1 DDx0

PORTx PORTx7 PORTx6 PORTx5 PORTx4 PORTx3 PORTx2 PORTx1 PORTx0

PINx PINx7 PINx6 PINx5 PINx4 PINx3 PINx2 PINx1 PINx0


Title: 1_Input_configurare_1.ino

Purpose: This is an example how to configure the Atmega328P (AVR) to lit a LED on PORTB bit 5, connected to digital pin
13 (D13 on Arduino Uno and Nano). The PB5 state, acting as output, depends on PD2 state, acting as input with internal
"PULL UP" resistor.

#include <avr/io.h> //the very first most important library containing all internal registers synonyms

boolean bit ;

int main(void) //runs once and configure some very important things!

DDRB |= 0x20; // b00100000 make PB5 (bit 5 on Port B set to 1) as output

// PORTB |= 0x20; // b00100000 make PORT5 (bit 5 on Port B set to 1)

// to activate PB5 on HIGH state (supply). LED must be on

// PORTB &= ~0x20; //this will clear the bit 5 and put port in LOW state (sink).

//LED must stop litting

DDRD &= ~0x04; // clear bit 2 on Port D (reset to 0 ~b00000100) to make PD2 as input

PORTD |= 0x04; // b00000100 make PORT2 (bit 2 on Port D set to 1)

// (on HIGH state) to activate PD2's PULL UP resistor. Daca impedanta e mare se aprinde

// PORTD &= ~0x04; // this will clear the bit 2 and put port in HIGH impedance.

// PULL UP resistor will be removed. An external resistor must be used instead.

while(1) //runs forewer/ read PD2 input and change PB5 output status.

bit = (PIND & 0x04) >> 2; // pin 4

if (bit == 1) PORTB |= (1 << 5); // set PB5 = 1, (1 << 5) = b00100000 // se aprinde ledul 13

if (bit == 0) PORTB &= ~(1 << 5); // reset PB5 = 0 (clear bit), ~(1 << 5) = b11011111 // se stinge ledul

/* same thing can be written as

if (bit) PORTB |= 0x20; // (1 << 5) = b00100000

else PORTB &= ~0x20; // ~(1 << 5) = b11011111 */

}
Title: Output_configurare_1.ino

#include <avr/io.h> // the very first most important library containing all internal registers synonyms

int main(void) //runs once and configure some very important things!

DDRB |= 0x20; // b00100000 make PB5 (bit 5 on Port B set to 1) as output

PORTB |= 0x20; // b00100000 make PORT5 (bit 5 on Port B set to 1) to activate PB5 on HIGH state.
(supply). LED must be on

// PORTB &= ~0x20; // this will clear the bit 5 and put port in LOW state (sink). LED must stop litting

while(1)

; //runs forewer but do nothing yet :)

} //end while

} //end main
Intreruperi / Interrupts
Referinte

2^7 2^6 2^5 2^4 2^3 2^2 2^1 2^0

HEX 0x 8 4 2 1 8 4 2 1

HEX 0x 8 4 2 1 8 4 2 1

bit7 bit6 bit5 bit4 bit3 bit2 bit1 bit0

DDRx DDx7 DDx6 DDx5 DDx4 DDx3 DDx2 DDx1 DDx0

PORTx PORTx7 PORTx6 PORTx5 PORTx4 PORTx3 PORTx2 PORTx1 PORTx0

PINx PINx7 PINx6 PINx5 PINx4 PINx3 PINx2 PINx1 PINx0

To configure external interrupts the following registers must be used:

bit7 bit6 bit5 bit4 bit3 bit2 bit1 bit0

EICRA - - - - ISC11 ISC10 ISC01 ISC00

Description

ISC11 ISC10

0 0 The low level of INT1 generates an interrupt request.

0 1 Any logical change on INT1 generates an interrupt request.

1 0 The falling edge of INT1 generates an interrupt request.

1 1 The rising edge of INT1 generates an interrupt request.

ISC01 ISC00

0 0 The low level of INT0 generates an interrupt request.

0 1 Any logical change on INT0 generates an interrupt request.

1 0 The falling edge of INT0 generates an interrupt request.

1 1 The rising edge of INT0 generates an interrupt request.

bit7 bit6 bit5 bit4 bit3 bit2 bit1 bit0

EIMSK - - - - - - INT1 INT0

EIFR - - - - - - INTF1 INTF0


Title: Exteral_interrupt_INT0.ino

Purpose: This is an example how to configure the Atmega328P (AVR) to lit a LED on PORTB bit 5, connected to digital pin
13 (D13 on Arduino Uno and Nano). Use one switch connected to INT0 and GND. First push turn the LED ON and second
turn it OFF.

#include <avr/io.h> // the very first most important library containing

// all internal registers synonyms

//Interrupt Service Routines. They run if an event happens and clear corresponding interrupt flag
ISR(INT0_vect) // starts as soon as INT0 detects the rising edge
{

static boolean flag = 0;

flag = !flag;

if (flag == 1) PORTB |= 0x20; // b00100000 make PORT5 (bit 5 on Port B set to 1) //aprinde ledul

// to activate PB5 on HIGH state (supply). LED must be on

else PORTB &= ~0x20; // this will clear the bit 5 and put port in LOW state (sink).

int main(void) //runs once and configure some very important things!

DDRB |= 0x20; // b00100000 make PB5 (bit 5 on Port B set to 1) as output

DDRD &= ~0x02; // clear bit 2 on Port D (reset to 0 ~b00000100)

// to make PD2 (INT0) as input

PORTD |= 0x02; // b00000100 make PORT2 (bit 2 on Port D set to 1)

// (on HIGH state) to activate PD2's PULL UP resistor.

EIMSK = 0x01; // sets as active INT0

EICRA = 0x03; // start interrupt functions on rising edge

SREG |= 0x80; // bit7 "I" activates all global interrupts

// sei(); // "set interrupts" same as above SREG |= 0x80;

while(1)

; // runs forewer but do nothing yet :) // all happens in ISRs !!!

} //end while

} //end main
Title: External_interrupt_INT0_INT1.

Purpose: This is an example how to configure the Atmega328P (AVR) to lit a LED on PORTB bit 5, connected to digital pin
13 (D13 on Arduino Uno and Nano).

Use two switches connected to INT0, INT1 and GND. First switch turn the LED ON and second turn it OFF.

#include <avr/io.h> // the very first most importanr library containing

// all internal registers synonyms

//Interrupt Service Routines. They run if an event happens and clear corresponding interrupt flag

ISR(INT0_vect) // starts as soon as INT0 detects the rising edge

PORTB |= 0x20; // b00100000 make PORT5 (bit 5 on Port B set to 1)

// to activate PB5 on HIGH state (supply). LED must be on

ISR(INT1_vect) // starts as soon as INT1 detects the rising edge

PORTB &= ~0x20; // this will clear the bit 5 and put port in LOW state (sink). //LED must stop litting

int main(void) //runs once and configure some very important things!

DDRB |= 0x20; // b00100000 make PB5 (bit 5 on Port B set to 1) as output // led 13 devine iesire

DDRD &= ~0x0C; // clear bit 2,3 on Port D (reset to 0 ~b00001100) to make PD2 and PD3 as input

PORTD |= 0x0C; // b00001100 make PORT2,3 (bit 2,3 on Port D set to 1)

// (on HIGH state) to activate PD2 and PD3's PULL UP resistor. Devin intrari de tip pull up resistor

EIMSK = 0x03; // sets as active INT0 and INT1

EICRA = 0x0F; // start interrupt functions on rising edge for INT0 a nd INT1 intra in intrerupere cand trece de la 0 la 1

SREG |= 0x80; // in SREG (status register) bit7 "I" activates all global interrupts

// sei(); // "set interrupts" same as above SREG |= 0x80;

while(1)

; // runs forewer but do nothing yet :) // all happens in ISRs !!!

} //end while

} //end main
Numaratoare
Refference

2^7 2^6 2^5 2^4 2^3 2^2 2^1 2^0


HEX 0x 8 4 2 1 8 4 2 1
HEX 0x 8 4 2 1 8 4 2 1
bit7 bit6 bit5 bit4 bit3 bit2 bit1 bit0
DDRx DDx7 DDx6 DDx5 DDx4 DDx3 DDx2 DDx1 DDx0
PORTx PORTx7 PORTx6 PORTx5 PORTx4 PORTx3 PORTx2 PORTx1 PORTx0
PINx PINx7 PINx6 PINx5 PINx4 PINx3 PINx2 PINx1 PINx0

To configure external interrupts the following registers must be used:

bit7 bit6 bit5 bit4 bit3 bit2 bit1 bit0

EICRA - - - - ISC11 ISC10 ISC01 ISC00

Description

ISC11 ISC10

0 0 The low level of INT1 generates an interrupt request.

0 1 Any logical change on INT1 generates an interrupt request.

1 0 The falling edge of INT1 generates an interrupt request.

1 1 The rising edge of INT1 generates an interrupt request.

ISC01 ISC00

0 0 The low level of INT0 generates an interrupt request.

0 1 Any logical change on INT0 generates an interrupt request.

1 0 The falling edge of INT0 generates an interrupt request.

1 1 The rising edge of INT0 generates an interrupt request.

bit7 bit6 bit5 bit4 bit3 bit2 bit1 bit0

EIMSK - - - - - - INT1 INT0

EIFR - - - - - - INTF1 INTF0


Title: Numarare_interrupt_INT0_INT1.ino

Purpose: This is an example how to configure the Atmega328P (AVR) to lit a LED on PORTB bit 5, connected to digital pin
13 (D13 on Arduino Uno and Nano).

Use two switches connected to INT0, INT1 and GND. First switch turn the LED ON and second turn it OFF.

#include <avr/io.h> // the very first most importanr library containing all internal registers synonyms

const byte stop = 5; //stop value

volatilr byte counter = 0; //variable that count up on INT0 and down on INT1

//Interrupt Service Routines. They run if an event happens and clear corresponding interrupt flag
ISR(INT0_vect) // starts as soon as INT0 detects the rising edge
{
counter++; //increase counter value by 1
}

ISR(INT1_vect) // starts as soon as INT1 detects the rising edge


{
counter--; //decrease counter value by 1
}

int main(void) //runs once and configures some very important things!

DDRB |= 0x20; // b00100000 make PB5 (bit 5 on Port B set to 1) as output

DDRD &= ~0x0C; // clear bit 2,3 on Port D (reset to 0 ~b00001100) to make PD2 and PD3 as input

PORTD |= 0x0C; // b00001100 make PORT2,3 (bit 2,3 on Port D set to 1)

// (on HIGH state) to activate PD2 and PD3's PULL UP resistor.

EIMSK = 0x03; // sets as active INT0 and INT1

EICRA = 0x0F; // start interrupt functions on rising edge for INT0 and INT1

SREG |= 0x80; // in SREG (status register) bit7 "I" activates all global interrupts

// sei(); // "set interrupts" same as above SREG |= 0x80;

while(1) // runs forever

if (counter == stop) PORTB |= 0x20; // b00100000 make PORT5 (bit 5 on Port B set to 1)

// to activate PB5 on HIGH state (supply). LED must be on

else PORTB &= ~0x20; // this will clear the bit 5 and put port in LOW state (sink).

} //end while

} //end main
Title: Numarare_LCD_INT0.ino

Purpose: This is an example how to configure the Atmega328P (AVR) to lit a LED on PORTB bit 5, connected to digital pin
13 (D13 on Arduino Uno and Nano). Use one switch connected to INT0 and GND. First push turn the LED ON and second
turn it OFF.

#include <avr/io.h> // the very first most importanr library containing // all internal registers synonyms
#include <LiquidCrystal.h> //the library that allow to run LCD1602
const byte stop = 5;
volatile byte counter = 0;
LiquidCrystal lcd(8, 9, 4, 5, 6, 7); // select the pins used on the LCD panel

//Interrupt Service Routines. They run if an event happens and clear corresponding interrupt flag:
ISR(INT0_vect) // starts as soon as INT0 detects the rising edge
{
counter++; //increase counter value by 1
}
int main(void) //runs once and configure some very important things!

DDRB |= 0x20; // b00100000 make PB5 (bit 5 on Port B set to 1) as output


DDRD &= ~0x04; // clear bit 2 on Port D (reset to 0 ~b00000100) to make PD2 (INT0) as input
PORTD |= 0x04; // b00000100 make PORT2 (bit 2 on Port D set to 1(HIGH state)) to activate PD2's PULL UP resistor
EIMSK = 0x01; // sets as active INT0
EICRA = 0x03; // start interrupt functions on rising edge

lcd.begin(16, 2); // start the library


lcd.setCursor(0,0);
lcd.print("START");
SREG |= 0x80; // bit7 "I" activates all global interrupts

// sei(); // "set interrupts" same as above SREG |= 0x80;

while(1) // runs forewer

if (counter == 255) { //when counter == 0 clear the display

lcd.setCursor(0,0); // move to the first position of the first line e

lcd.print(" "); // clear displayed 4 digits

lcd.setCursor(0,0); // move to the first position of the first line


lcd.print(counter); // print counter value
} //end while

} //end main
Title: Numarare_LCD_INT0_INT1.ino

Purpose: This is an example how to configure the Atmega328P (AVR) to lit a LED on PORTB bit 5, connected to D13 on
Arduino. Use two switches connected to INT0, INT1 and GND. First switch turn the LED ON and second turn it OFF.

#include <avr/io.h> // the very first most important library containing


#include <LiquidCrystal.h> //the library that allow to run LCD1602 all internal registers synonyms

volatile byte counter = 0; //variable that count up on INT0 and down on INT1
// select the pins used on the LCD panel
LiquidCrystal lcd(8, 9, 4, 5, 6, 7);

//Interrupt Service Routines. They run if an event happens and clear corresponding interrupt flag
ISR(INT0_vect) // starts as soon as INT0 detects the rising edge
{
counter++; //increase counter value by 1
}
ISR(INT1_vect) // starts as soon as INT1 detects the rising edge
{
counter--; //decrease counter value by 1
}

int main(void) //runs once and configure some very important things!
{
DDRB |= 0x20; // b00100000 make PB5 (bit 5 on Port B set to 1) as output
DDRD &= ~0x0C; // clear bit 2,3 on Port D (reset to 0 ~b00001100)
// to make PD2 and PD3 as input
PORTD |= 0x0C; // b00001100 make PORT2,3 (bit 2,3 on Port D set to 1)
// (on HIGH state) to activate PD2 and PD3's PULL UP resistor.
EIMSK = 0x03; // sets as active INT0 and INT1
EICRA = 0x0F; // start interrupt functions on rising edge for INT0 and INT1
SREG |= 0x80; // in SREG (status register) bit7 "I" activates all global interrupts
// sei(); // "set interrupts" same as above SREG |= 0x80;
lcd.begin(16, 2); // start the library

lcd.setCursor(0,0);

lcd.print("START");

while(1) // runs forever

{
if (counter == 255)
{ //when counter == 0 clear the display
lcd.setCursor(0,0); // move to the first position of the first line e
lcd.print(" "); // clear displayed 4 digits
}
lcd.setCursor(0,0); // move to the first position of the first line

lcd.print(counter); // print counter value

} //end while

} //end main
Title: Numarare_Serial_INT0_INT1.ino

#include <avr/io.h> // the very first most important library containing

// all internal registers synonyms

volatile byte counter = 0; //variable that count up on INT0 and down on INT1

//Interrupt Service Routines. They run if an event happens and clear corresponding interrupt flag
ISR(INT0_vect) // starts as soon as INT0 detects the rising edge

counter++; //increase counter value by 1

ISR(INT1_vect) // starts as soon as INT1 detects the rising edge

counter--; //decrease counter value by 1

int main(void) //runs once and configure some very important things!

Serial.begin(9600); // start the library

DDRB |= 0x20; // b00100000 make PB5 (bit 5 on Port B set to 1) as output

DDRD &= ~0x0C; // clear bit 2,3 on Port D (reset to 0 ~b00001100) to make PD2 and PD3 as input

PORTD |= 0x0C; // b00001100 make PORT2,3 (bit 2,3 on Port D set to 1)

// (on HIGH state) to activate PD2 and PD3's PULL UP resistor.

EIMSK = 0x03; // sets as active INT0 and INT1

EICRA = 0x0F; // start interrupt functions on rising edge for INT0 and INT1

SREG |= 0x80; // in SREG (status register) bit7 "I" activates all global interrupts

// sei(); // "set interrupts" same as above SREG |= 0x80;

while(1) // runs forever

Serial.println(counter); // print counter value

} //end while

} //end main
Timer-Counter
Refference
2^7 2^6 2^5 2^4 2^3 2^2 2^1 2^0
HEX 0x 8 4 2 1 8 4 2 1
HEX 0x 8 4 2 1 8 4 2 1
bit7 bit6 bit5 bit4 bit3 bit2 bit1 bit0
DDRx DDx7 DDx6 DDx5 DDx4 DDx3 DDx2 DDx1 DDx0
PORTx PORTx7 PORTx6 PORTx5 PORTx4 PORTx3 PORTx2 PORTx1 PORTx0
PINx PINx7 PINx6 PINx5 PINx4 PINx3 PINx2 PINx1 PINx0

TCCR0A ☐ Timer/Counter Control Register A

bit7 bit6 bit5 bit4 bit3 bit2 bit1 bit0

COM0A1 COM0A0 COM0B1 COM0B0 ☐ ☐ WGM01 WGM00

Compare Output Mode, non-PWM Mode

COM0A1 COM0A0 Description


0 0 Normal port operation, OC0A disconnected.
0 1 Toggle OC0A on Compare Match
1 0 Clear OC0A on Compare Match
1 1 Set OC0A on Compare Match

Compare Output Mode, Fast PWM Mode(1)

COM0A1 COM0A0 Description

0 0 Normal port operation, OC0A disconnected.


0 1 WGM02 = 0: Normal Port Operation, OC0A Disconnected.
WGM02 = 1: Toggle OC0A on Compare Match.
1 0 Clear OC0A on Compare Match, set OC0A at BOTTOM, (non-inverting mode).
1 1 Set OC0A on Compare Match, clear OC0A at BOTTOM, (inverting mode).

Compare Output Mode, Phase Correct PWM Mode(1)

COM0A1 COM0A0 Description

0 0 Normal port operation, OC0A disconnected.


0 1 WGM02 = 0: Normal Port Operation, OC0A Disconnected.
WGM02 = 1: Toggle OC0A on Compare Match.
1 0 Clear OC0A on Compare Match when up-counting. Set OC0A on
Compare Match when down-counting.
1 1 Set OC0A on Compare Match when up-counting. Clear OC0A on
Compare Match when down-counting.

Compare Output Mode, non-PWM Mode

COM0B1 COM0B0 Description


0 0 Normal port operation, OC0B disconnected.
0 1 Toggle OC0B on Compare Match
1 0 Clear OC0B on Compare Match
1 1 Set OC0B on Compare Match
Compare Output Mode, Fast PWM Mode(1)

COM0B1 COM0B0 Description


0 0 Normal port operation, OC0B disconnected.
0 1 Reserved
1 0 Clear OC0B on Compare Match, set OC0B at BOTTOM, (non-inverting mode)
1 1 Set OC0B on Compare Match, clear OC0B at BOTTOM, (inverting mode).
Compare Output Mode, Phase Correct PWM Mode(1)

COM0B1 COM0B0 Description


0 0 Normal port operation, OC0B disconnected.
0 1 Reserved
1 0 Clear OC0B on Compare Match when up-counting. Set OC0B on
Compare Match when down-counting.
1 1 Set OC0B on Compare Match when up-counting. Clear OC0B on
Compare Match when down-counting.
TCCR0B ☐ Timer/Counter Control Register B

bit7 bit6 bit5 bit4 bit3 bit2 bit1 bit0

FOC0A FOC0B ☐ ☐ WGM02 CS02 CS01 CS00

Clock Select Bit Description

CS02 CS01 CS00 Description


0 0 0 No clock source (Timer/Counter stopped)
0 0 1 clkI/O/(No prescaling)
0 1 0 clkI/O/8 (From prescaler)
0 1 1 clkI/O/64 (From prescaler)
1 0 0 clkI/O/256 (From prescaler)
1 0 1 clkI/O/1024 (From prescaler)
1 1 0 External clock source on T0 pin. Clock on falling edge.
1 1 1 External clock source on T0 pin. Clock on rising edge.

TIMSK0 ☐ Timer/Counter Interrupt Mask Register

bit7 bit6 bit5 bit4 bit3 bit2 bit1 bit0

☐ ☐ ☐ ☐ ☐ OCIE0B OCIE0A TOIE

TIFR0 ☐ Timer/Counter 0 Interrupt Flag Register

bit7 bit6 bit5 bit4 bit3 bit2 bit1 bit0

☐ ☐ ☐ ☐ ☐ OCF0B OCF0A TOV0


Title: Numarare_Serial_CNT0.ino

Purpose: This is an example how to configure the Atmega328P (AVR) to lit a LED on PORTB bit 5, connected to digital pin
13 (D13 on Arduino Uno and Nano).

#include <avr/io.h> // the very first most importanr library containing

// all internal registers synonyms

int main(void) //runs once and configure some very important things!

Serial.begin(9600); // set serial communication at 9600 baud

DDRB |= 0x20; // b00100000 make PB5 (bit 5 on Port B set to 1) as output

DDRD &= ~0x10; // clear bit 4 on Port D (reset to 0 ~b00010000)

// to make PD4 (T0) as input

PORTD |= 0x10; // b00010000 make PORT2 (bit 2 on Port D set to 1)

// (on HIGH state) to activate PD2's PULL UP resistor.

TCCR0B = 0x07; // sets as active T0 on rising edge

while(1) // runs forewer

Serial.println(TCNT0); // print counter value

} //end while

} //end main
Title: Numarare_Serial_CNT0_OVI1.ino

Purpose: This is an example how to configure the Atmega328P (AVR) to lit a LED on PORTB bit 5, connected to digital pin
13 (D13 on Arduino Uno and Nano). Use one switch connected to INT0 and GND. First push turn the LED ON and second
turn it OFF.

#include <avr/io.h> // the very first most important library containing

// all internal registers synonyms

#include <avr/interrupt.h>

ISR(TIMER0_OVF_vect) // when TIMER0 overflows, interrupt starts function

PORTB |= 0x20; // turn ON the LED

int main(void) //runs once and configure some very important things!

Serial.begin(9600); // initialize serial communication at 9600 baud

DDRB |= 0x20; // b00100000 make PB5 (bit 5 on Port B set to 1) as output

DDRD &= ~0x10; // clear bit 4 on Port D (reset to 0 ~b00000100)

// to make PD4 (T0) as input

PORTD |= 0x10; // b00010000 make PORT4 (bit 4 on Port D set to 1)

// (on HIGH state) to activate PD4's PULL UP resistor.

TCCR0B = 0x07; // sets as active T0 on rising edge

TIMSK0 = 0x01; // sets as active TOV0 (Overflow interrupt enable) bit, cand se trece de 255

SREG |= 0x80; // set global interrupt bit (I) in SREG

while(1) // runs forever

Serial.println(TCNT0); // print counter value

} //end while

} //end main
Title: Numarare_Serial_CNT0_OVI_xN.
Purpose: This is an example how to configure the Atmega328P (AVR) to increase the counter
resolution, using overflow interrupt on PORTB bit 5, connected to digital pin 13 (D13 on Arduino Uno and Nano).

#include <avr/io.h> // the very first most importanr library containing all internal registers synonyms
#include <avr/interrupt.h>

byte overflows = 0;

word contor = 0;

ISR(TIMER0_OVF_vect) // when TIMER0 overflows, interrupt starts function


{
overflows++; // increments the number of overflows
}
int main(void) //runs once and configure some very important things!

Serial.begin(9600); // initialize serial communication at 9600 baud

//DDRB |= 0x20; // b00100000 make PB5 (bit 5 on Port B set to 1) as output

DDRD &= ~0x10; // clear bit 4 on Port D (reset to 0 ~b00010000) to make PD4 (T0) as input

PORTD |= 0x10; // b00010000 make PORT4 (bit 4 on Port D set to 1)

// (on HIGH state) to activate PD4's PULL UP resistor.

TCCR0B = 0x07; // sets as active T0 on rising edge

TIMSK0 = 0x01; // sets as active TOV0 (Overflow interrupt eneble) bit

SREG |= 0x80; // set globla interrupt bit (I) in SREG

while(1) // runs forewer

contor = 256 * overflows + TCNT0; // calculates entire value

Serial.print(overflows); // print overflows value

Serial.print("x 256 + "); // print a formula

Serial.print(TCNT0); // print counter value

Serial.print(" = "); // print =

Serial.println(contor); // print entire value

} //end while

} //end main
Title: Timer_Blink_CNT1_CompareA_1

Purpose: This is an example how to configure the Atmega328P (AVR) to lit a LED on PORTB bit 5, connected to digital pin
13 (D13) on Arduino. Use one switch connected to T0 and GND. Blink the LED by using TIMER1 Compare A Interrupt.

TCCR0A � Timer/Counter Control Register A


bit7 bit6 bit5 bit4 bit3 bit2 bit1 bit0
COM0A1 COM0A0 COM0B1 COM0B0 � � WGM01 WGM00

Compare Output Mode, non-PWM Mode


COM0A1 COM0A0 Description
0 0 Normal port operation, OC0A disconnected.
0 1 Toggle OC0A on Compare Match
1 0 Clear OC0A on Compare Match
1 1 Set OC0A on Compare Match

Compare Output Mode, Fast PWM Mode(1)

COM0A1 COM0A0 Description

0 0 Normal port operation, OC0A disconnected.

0 1 WGM02 = 0: Normal Port Operation, OC0A Disconnected.

WGM02 = 1: Toggle OC0A on Compare Match.

1 0 Clear OC0A on Compare Match, set OC0A at BOTTOM,

(non-inverting mode).

1 1 Set OC0A on Compare Match, clear OC0A at BOTTOM,

(inverting mode).

Compare Output Mode, Phase Correct PWM Mode(1)

COM0A1 COM0A0 Description

0 0 Normal port operation, OC0A disconnected.

0 1 WGM02 = 0: Normal Port Operation, OC0A Disconnected.

WGM02 = 1: Toggle OC0A on Compare Match.

1 0 Clear OC0A on Compare Match when up-counting. Set OC0A on

Compare Match when down-counting.

1 1 Set OC0A on Compare Match when up-counting. Clear OC0A on

Compare Match when down-counting.


Compare Output Mode, non-PWM Mode

COM0B1 COM0B0 Description

0 0 Normal port operation, OC0B disconnected.

0 1 Toggle OC0B on Compare Match

1 0 Clear OC0B on Compare Match

1 1 Set OC0B on Compare Match

Compare Output Mode, Fast PWM Mode(1)

COM0B1 COM0B0 Description

0 0 Normal port operation, OC0B disconnected.

0 1 Reserved

1 0 Clear OC0B on Compare Match, set OC0B at BOTTOM,

(non-inverting mode)

1 1 Set OC0B on Compare Match, clear OC0B at BOTTOM,

(inverting mode).

Compare Output Mode, Phase Correct PWM Mode(1)

COM0B1 COM0B0 Description

0 0 Normal port operation, OC0B disconnected.

0 1 Reserved

1 0 Clear OC0B on Compare Match when up-counting. Set OC0B on

Compare Match when down-counting.

1 1 Set OC0B on Compare Match when up-counting. Clear OC0B on

Compare Match when down-counting.

TCCR0B � Timer/Counter Control Register B

bit7 bit6 bit5 bit4 bit3 bit2 bit1 bit0

FOC0A FOC0B � � WGM02 CS02 CS01 CS00


Clock Select Bit Description

CS02 CS01 CS00 Description

0 0 0 No clock source (Timer/Counter stopped)

0 0 1 clkI/O/(No prescaling)

0 1 0 clkI/O/8 (From prescaler)

0 1 1 clkI/O/64 (From prescaler)

1 0 0 clkI/O/256 (From prescaler)

1 0 1 clkI/O/1024 (From prescaler)

1 1 0 External clock source on T0 pin. Clock on falling edge.

1 1 1 External clock source on T0 pin. Clock on rising edge.

TIMSK0 � Timer/Counter Interrupt Mask Register

bit7 bit6 bit5 bit4 bit3 bit2 bit1 bit0

� � � � � OCIE0B OCIE0A TOIE0

TIFR0 � Timer/Counter 0 Interrupt Flag Register

bit7 bit6 bit5 bit4 bit3 bit2 bit1 bit0

� � � � � OCF0B OCF0A TOV0

Modes of Operation

Mode WGM13 WGM12 WGM11 WGM10 Timer/Counter Mode of Operation Update of

CTC1 PWM11 PWM10 OCR1x TOV1

0 0 0 0 0 Normal 0xFFFF Immediate MAX


1 0 0 0 1 PWM, PhaseCorrect,8-bit 0x00FF TOP BOTTOM
2 0 0 1 0 PWM, PhaseCorrect,9-bit 0x01FF TOP BOTTOM
3 0 0 1 1 PWM, PhaseCorrect,10bit 0x03FF TOP BOTTOM
4 0 1 0 0 CTC OCR1A Immediate MAX
5 0 1 0 1 Fast PWM, 8-bit 0x00FF BOTTOM TOP
6 0 1 1 0 Fast PWM, 9-bit 0x01FF BOTTOM TOP
7 0 1 1 1 Fast PWM, 10-bit 0x03FF BOTTOM TOP
8 1 0 0 0 PWM, Phase & Freq Corr ICR1 BOTTOM BOTTOM
9 1 0 0 1 PWM, Phase & Freq Corr OCR1A BOTTOM BOTTOM
10 1 0 1 0 PWM, Phase Correct ICR1 TOP BOTTOM
11 1 0 1 1 PWM, Phase Correct OCR1A TOP BOTTOM
12 1 1 0 0 CTC ICR1 Immediate MAX
13 1 1 0 1 (Reserved) � � �
14 1 1 1 0 Fast PWM ICR1 BOTTOM TOP
15 1 1 1 1 Fast PWM OCR1A BOTTOM TOP
Normal Mode:

When the prescaler receives a pulse from a clock cycle and passes it onto the Control Logic. The Control Logic
increments the TCNTn register by 1. When TCNTn hits the TOP (0xFF in the 8 bit timers and 0xFFFF in the 16 bit timer) it
overflows to 0 and sets the TOVn bit in the TIFR register.

The problem with Normal Mode is that it is very hard to use for an exact interval, because of this Normal Mode is only
useful if you need a none-specific time interval (say you don't care if it happens every 1 or 2 ms as long as it happens at
the same time each time) its nice and easy option. Because, of this limitation many programmers choose to use CTC
mode for their timers.

CTC Mode:

CTC stands for "Clear Timer on Compare" and it does the following. When the prescaler receives a pulse from a clock
cycle and passes it onto the Control Logic. The Control Logic increments the TCNTn register by 1. The TCNTn register is
compared to the OCRn register, when a compare match occurs the TOVn bit is set in the TIFR register.

#include <avr/io.h> // the very first most importanr library containing all internal registers synonyms
#include <avr/interrupt.h>

ISR(TIMER1_COMPA_vect) // when TIMER1 overflows, interrupt starts function


{
static boolean ledbit = 0;
ledbit = !ledbit;
// toggle the LED when overflow occur
if (ledbit) PORTB |= 0x20; // turn ON the LED, la 31250 aprinde ledul (OCR1A)
else PORTB &= ~0x20; // turn OFF the LED
}

int main(void) //runs once and configure some very important things!

DDRB |= 0x20; // b00100000 make PB5 (bit 5 on Port B set to 1) as output

PORTB |= 0x20; // turn ON the LED

TCCR1A = 0; // reset all previous settings


TCCR1B = 0;
TCNT1 = 0; // preload timer 65536-16MHz/256/2Hz
OCR1A = 31250; // compare match register 16MHz/256/2Hz
TCCR1B |= (1 << WGM12); // CTC mode - Clear Timer on Compare match
TCCR1B |= (1 << CS12); // set prescaler as 256
TIMSK1 |= (1 << OCIE1A); // enable timer compare A interrupt
SREG |= 0x80; // set globla interrupt bit (I) in SREG

while(1) // runs forewer

} //end while

} //end main
Title: Timer_Blink_CNT1_OVI_1

Purpose: This is an example how to configure the Atmega328P (AVR) to lit a LED on PORTB bit 5, connected to digital pin
13 (D13 on Arduino Uno and Nano).

Clock Select Bit Description

CS02 CS01 CS00 Description

0 0 0 No clock source (Timer/Counter stopped)

0 0 1 clkI/O/(No prescaling)

0 1 0 clkI/O/8 (From prescaler)

0 1 1 clkI/O/64 (From prescaler)

1 0 0 clkI/O/256 (From prescaler)

1 0 1 clkI/O/1024 (From prescaler)

1 1 0 External clock source on T0 pin. Clock on falling edge.

1 1 1 External clock source on T0 pin. Clock on rising edge.

TIMSK0 � Timer/Counter Interrupt Mask Register

bit7 bit6 bit5 bit4 bit3 bit2 bit1 bit0

� � � � � OCIE0B OCIE0A TOIE0

TIFR0 � Timer/Counter 0 Interrupt Flag Register

bit7 bit6 bit5 bit4 bit3 bit2 bit1 bit0

� � � � � OCF0B OCF0A TOV0


#include <avr/io.h> // the very first most importanr library containing

// all internal registers synonyms

#include <avr/interrupt.h>

ISR(TIMER1_OVF_vect) // when TIMER1 overflows, interrupt starts function

static boolean ledbit = 0;

ledbit = !ledbit;

TCNT1 = 34286; // preload timer with 65536 - 16MHz/256/2Hz

// toggle the LED when overflow occur

if (ledbit) PORTB |= 0x20; // turn ON the LED

else PORTB &= ~0x20; // turn OFF the LED

int main(void) //runs once and configure some very important things!

DDRB |= 0x20; // b00100000 make PB5 (bit 5 on Port B set to 1) as output

// same as: in Arduino mode

PORTB |= 0x20; // turn ON the LED

TCCR1A = 0; // reset all previous settings

TCCR1B = 0;

TCNT1 = 34286; // preload timer 65536-16MHz/256/2Hz

TCCR1B |= (1 << CS12); // set prescaler as 256

TIMSK1 |= (1 << TOIE1); // enable timer overflow interrupt

SREG |= 0x80; // set globla interrupt bit (I) in SREG

while(1) // runs forewer

} //end while

} //end main
Title: Timer_PWM_CNT0_CompareA_1

Normal Mode:

When the prescaler receives a pulse from a clock cycle and passes it onto the Control Logic. The Control Logic
increments the TCNTn register by 1. When TCNTn hits the TOP (0xFF in the 8 bit timers and 0xFFFF in the 16 bit timer) it
overflows to 0 and sets the TOVn bit in the TIFR register.

The problem with Normal Mode is that it is very hard to use for an exact interval, because of this Normal Mode is only
useful if you need a none-specific time interval (say you don't care if it happens every 1 or 2 ms as long as it happens at
the same time each time) its nice and easy option. Because, of this limitation many programmers choose to use CTC
mode for their timers. (Valabil si pt urmatorul program)

CTC Mode:

CTC stands for "Clear Timer on Compare" and it does the following. When the prescaler receives a pulse from a clock
cycle and passes it onto the Control Logic. The Control Logic increments the TCNTn register by 1. The TCNTn register is
compared to the OCRn register, when a compare match occurs the TOVn bit is set in the TIFR register. (Valabil si pt
urmatorul program)

#include <avr/io.h> // the very first most importanr library containing all internal registers synonyms

#include <avr/interrupt.h>

ISR(TIMER1_COMPA_vect) // when TIMER1 overflows, interrupt starts function


{
static boolean ledbit = 0;
ledbit = !ledbit;
// toggle the LED when overflow occur
if (ledbit) PORTB |= 0x20; // turn ON the LED
else PORTB &= ~0x20; // turn OFF the LED
}
int main(void) //runs once and configure some very important things!

DDRB |= 0x20; // b0010 0000 make PB5 (bit 5 on Port B set to 1) as output

DDRD |= 0x40; // b0100 0000 make PD6 (bit 6 on Port D set to 1) as output

TCCR0A = 0; // reset all previous settings


TCCR0B = 0;
TCNT0 = 0; // preload timer 65536-16MHz/256/2Hz
OCR0A = 128; // compare match register 256/2 set PWM for 50% duty cycle

TCCR0A |= (1 << COM0A1); // Clear OC0A on Compare Match, set OC0A at BOTTOM, (non-inverting mode)

TCCR0A |= (1 << WGM01) | (1 << WGM00); // set fast PWM Mode

TCCR0B |= (1 << CS01); // set prescaler to 8 and starts PWM

while(1) // runs forewer


{
} //end while
} //end main
Title: Timer_PWM_CNT0_CompareAB_1

#include <avr/io.h> // the very first most importanr library containing all internal registers synonyms

#include <avr/interrupt.h>

ISR(TIMER1_COMPA_vect) // when TIMER1 overflows, interrupt starts function


{
static boolean ledbit = 0;
ledbit = !ledbit;
// toggle the LED when overflow occur
if (ledbit) PORTB |= 0x20; // turn ON the LED
else PORTB &= ~0x20; // turn OFF the LED
}

int main(void) //runs once and configure some very important things!

DDRB |= 0x20; // b0010 0000 make PB5 (bit 5 on Port B set to 1) as output
DDRD |= 0x40; // b0100 0000 make OC0A PD6 (bit 6 on Port D set to 1) as output
DDRD |= 0x20; // b0010 0000 make OC0B PD5 (bit 5 on Port D set to 1) as output
TCCR0A = 0; // reset all previous settings
TCCR0B = 0;
TCNT0 = 0;
/* Setting TCCR0A for a pair of complemmentary PWM signals
_ _
OC0A | |____| |____|
____ ____
OC0B |_| |_| |
the values of OCR0A and OCR0B must be equal to obtain the above signals
*/

TCCR0A |= (1 << COM0A1); // Clear OC0A on Compare Match, set OC0A at BOTTOM, (non-inverting mode)

TCCR0A |= (1 << COM0B1) | (1 << COM0B0); // set OC0B on Compare Match, clear OC0B at BOTTOM, (inverting mode)

OCR0A = 64; // compare match register 256/2 set PWM for 50% duty cycle

OCR0B = 64; // compare match register 256/2 set PWM for 50% duty cycle

TCCR0A |= (1 << WGM01) | (1 << WGM00); // set fast PWM Mode

TCCR0B |= (1 << CS01); // set prescaler to 8 and starts PWM

while(1) // runs forewer, but nothing to do yet :)

} //end while

} //end main
Frecventa
Title: Frecv_INT_1.ino a true Arduino sketch program file

Purpose: This is an example how to configure the Atmega328P (AVR) to measure frequency on T1 (PORTD bit 5),
connected to digital pin 5 (D5 on Arduino Uno and Nano) and print the value at serial port.
// other version of loop function
void loop() {
float period;
float floatfrq;
int range;
long frq;
measurement(1000); // 1000ms standard gate time
while (measurement_ready==false); // waits till measurement starts
frq=frequency;
floatfrq=frq; // type conversion (required!!)
period=(1/floatfrq); // period = 1/Frequenz -

if ((frq >= 0)&& (frq < 10)) {range=0;}; // Hertz


if ((frq >= 10)&& (frq < 100)) {range=1;};
if ((frq >= 100)&& (frq < 1000)) {range=2;};
if ((frq >= 1000)&& (frq < 10000)) {range=3; floatfrq=floatfrq/1000;}; // KHz
if ((frq >= 10000)&& (frq < 100000)) {range=4; floatfrq=floatfrq/1000;};
if ((frq >= 100000)&& (frq < 1000000)) {range=5; floatfrq=floatfrq/1000;};
if (frq >= 1000000) {range=6; floatfrq=floatfrq/1000000;}; // MHz

Serial.print("Frequency (Hz): ");


Serial.print(frq);
Serial.print(" Period (sec): ");
Serial.println(period,7);

lcd.setCursor(0, 0);
lcd.print("Freq: ");
lcd.setCursor(0, 1);
lcd.print("Per.: ");
switch(range) {
case 0: // 1Hz thru 10Hz
lcd.setCursor(6, 0); lcd.print(frq);
lcd.setCursor(13,0); lcd.print("Hz ");
lcd.setCursor(6, 1); lcd.print(period,3);
lcd.setCursor(13, 1); lcd.print("s ");
break;
case 1: // 10Hz thru 100Hz
period=period*1000; // convert from seconds to ms
lcd.setCursor(6, 0); lcd.print(frq);
lcd.setCursor(13,0); lcd.print("Hz ");
lcd.setCursor(6, 1); lcd.print(period,2);
lcd.setCursor(13, 1); lcd.print("ms");
break;
case 2: // 100Hz thru 1KHz
period=period*1000;
lcd.setCursor(6, 0); lcd.print(frq);
lcd.setCursor(13,0); lcd.print("Hz ");
lcd.setCursor(6, 1); lcd.print(period,3);
lcd.setCursor(13, 1); lcd.print("ms");
break;
case 3: // 1KHz thru 10KHz
period=period*1000;
lcd.setCursor(6, 0); lcd.print(floatfrq,3);
lcd.setCursor(13,0); lcd.print("KHz");
lcd.setCursor(6, 1); lcd.print(period,3);
lcd.setCursor(13, 1); lcd.print("ms");
break;
case 4: // 10KHz thru 100KHz
period=period*1000*1000;
lcd.setCursor(6, 0); lcd.print(floatfrq,2);
lcd.setCursor(13,0); lcd.print("KHz");
lcd.setCursor(6, 1); lcd.print(period,2);
lcd.setCursor(13, 1); lcd.print("us");
break;
case 5: // 100KHz thru 1MHz
period=period*1000*1000; // convert from s to �
lcd.setCursor(6, 0); lcd.print(floatfrq,1);
lcd.setCursor(13,0); lcd.print("KHz");
lcd.setCursor(6, 1); lcd.print(period,3);
lcd.setCursor(13, 1); lcd.print("us");
break;
case 6: // above 1MHz
period=period*1000*1000;
lcd.setCursor(6, 0); lcd.print(floatfrq,3);
lcd.setCursor(13,0); lcd.print("MHz");
lcd.setCursor(6, 1); lcd.print(period,3);
lcd.setCursor(13, 1); lcd.print("us");
break;
}
}
Title: Freq_meter_Arduino_pulseIn_1
This code is based on a simpler version that has become standard among Arduino users. Some problems with the
original code have been fixed and operation speed has been improved (slightly).
STRATEGY:
This code is actually a period counter with conversion of period to frequency in software. Refresh time is less for higher
frequency inputs, which provides a pseudo auto-ranging operation. A prescaler is needed for frequencies higher than
one third CPU Clock. If a prescaler is used, its division factor should be set in the "int prescale = N;" code line. This will
cause frequency to be multiplied by the pre-scal factor before it is written to the LCD. Higher prescale factors may
noticeably slow counting of VLF and audio signals.
Title: Freq_meter_Arduino_pulseIn_2
Title: Perioada1
Purpose: This is an example how to configure the Atmega328P (AVR) to measure time period
on ICP - Input Capture Pin (PORTB bit 0), connected to digital pin 8 (D8 on Arduino Uno and Nano) and print the value at
serial port
Forme de reprezentare a numerelor

Operatori comune pentru regiștri

Вам также может понравиться