Manipulare Porturi
Manipulare Porturi
Manipulare 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:
Each port is controlled by three registers, which are also defined variables in the Arduino language.
DDR and PORT registers may be both written to, and read.
PIN registers correspond to the state of inputs and may only be read.
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:
//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;
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.
HEX 0x 8 4 2 1 8 4 2 1
HEX 0x 8 4 2 1 8 4 2 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). 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!
// PORTB &= ~0x20; //this will clear the bit 5 and put port in LOW state (sink).
DDRD &= ~0x04; // clear bit 2 on Port D (reset to 0 ~b00000100) to make PD2 as input
// (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.
while(1) //runs forewer/ read PD2 input and change PB5 output status.
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
}
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!
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)
} //end while
} //end main
Intreruperi / Interrupts
Referinte
HEX 0x 8 4 2 1 8 4 2 1
HEX 0x 8 4 2 1 8 4 2 1
Description
ISC11 ISC10
ISC01 ISC00
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.
//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
{
flag = !flag;
if (flag == 1) PORTB |= 0x20; // b00100000 make PORT5 (bit 5 on Port B set to 1) //aprinde ledul
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!
while(1)
} //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.
//Interrupt Service Routines. They run if an event happens and clear corresponding interrupt flag
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
// (on HIGH state) to activate PD2 and PD3's PULL UP resistor. Devin intrari de tip pull up resistor
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
while(1)
} //end while
} //end main
Numaratoare
Refference
Description
ISC11 ISC10
ISC01 ISC00
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
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
}
int main(void) //runs once and configures some very important things!
DDRD &= ~0x0C; // clear bit 2,3 on Port D (reset to 0 ~b00001100) to make PD2 and PD3 as input
EICRA = 0x0F; // start interrupt functions on rising edge for INT0 and INT1
SREG |= 0x80; // in SREG (status register) bit7 "I" activates all global interrupts
if (counter == stop) PORTB |= 0x20; // b00100000 make PORT5 (bit 5 on Port B set to 1)
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!
} //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.
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");
{
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
} //end while
} //end main
Title: Numarare_Serial_INT0_INT1.ino
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
int main(void) //runs once and configure some very important things!
DDRD &= ~0x0C; // clear bit 2,3 on Port D (reset to 0 ~b00001100) to make PD2 and PD3 as input
EICRA = 0x0F; // start interrupt functions on rising edge for INT0 and INT1
SREG |= 0x80; // in SREG (status register) bit7 "I" activates all global interrupts
} //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
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).
int main(void) //runs once and configure some very important things!
} //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/interrupt.h>
int main(void) //runs once and configure some very important things!
TIMSK0 = 0x01; // sets as active TOV0 (Overflow interrupt enable) bit, cand se trece de 255
} //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;
DDRD &= ~0x10; // clear bit 4 on Port D (reset to 0 ~b00010000) to make PD4 (T0) as input
} //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.
(non-inverting mode).
(inverting mode).
0 1 Reserved
(non-inverting mode)
(inverting mode).
0 1 Reserved
0 0 1 clkI/O/(No prescaling)
Modes of Operation
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>
int main(void) //runs once and configure some very important things!
} //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).
0 0 1 clkI/O/(No prescaling)
#include <avr/interrupt.h>
ledbit = !ledbit;
int main(void) //runs once and configure some very important things!
TCCR1B = 0;
} //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>
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 |= (1 << COM0A1); // Clear OC0A on Compare Match, set OC0A at BOTTOM, (non-inverting mode)
#include <avr/io.h> // the very first most importanr library containing all internal registers synonyms
#include <avr/interrupt.h>
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
} //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 -
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