Arduino Mega 2560
Arduino Mega 2560
Memory-Mapped I/O Datasheet Page: 399 Pin Mapping ATmega2560 Memory-Mapped I/O Datasheet Page: 399
AVR Microcontroller I/O PORT Programming: PORTs must be programmed before used as an INPUT(s) or an OUTPUT(s) PORTs have some other functions as ADC, Timers, Counters, Interrupts, Serial Communications, etc. PORTX Number of Pins PORTA 8-bit bi-directional I/O port (PA7..PA0) PORTB 8-bit bi-directional I/O port (PB7..PB0) PORTC 8-bit bi-directional I/O port (PC7..PC0) PORTD 8-bit bi-directional I/O port (PD7..PD0) PORTE 8-bit bi-directional I/O port (PE7..PE0) PORTF 8-bit bi-directional I/O port (PF7..PF0) Analog inputs to the A/D Converter PORTG 6-bit bi-directional I/O port (PG5..PG0) PORTH 8-bit bi-directional I/O port (PH7..PH0) PORTJ 8-bit bi-directional I/O port (PJ7..PJ0) PORTK 8-bit bi-directional I/O port (PK7..PK0) PORTL 8-bit bi-directional I/O port (PL7..PL0)
Each PORT has three I/O registers PORTx (PORTB) DDRx (Data Direction Register, DDRB) PINx (Port INput pins, PINB) DDRx is used to assign (set) the port as an INPUT or an OUTPUT For INPUT DDRBx pin = 0 (0b0000_0000) For OUTPUT DDRBx pin = 1 (0b1111_1111) Port(s) must be initialized as an input or an output in start of the code. To set port B as an output, DDRBx port bits must be all ONEs. Otherwise data will not go from port register to the pins of AVR. Upon reset, DDRX register become zero (Reset makes port as an INPUT, 0x00)
Role of PINx and PORTx Registers: To read data present at the pins, we should read the PINx register (To bring data into CPU from pins we read contents of the PINx register) To send data out to pins we use the PORTx register Internal PULL-UPs of AVR: To use internal pull-ups for INPUT. DDRx register must be zero PORTx register set to 0xFF (to use internal pull-ups) AVR Microcontroller has Four valued Logic 1 X (Unknown, Don't Care) Z (High Impedance or Open Circuit, Floating state, uncertain state)
C Data Types for the AVR:
I/O PORT Programming: Write an AVR program to send values 0x00 to PORTF and 0xFF to PORTK. #include <avr/io.h> int main (void) { DDRF = 0xFF; DDRK = 0xFF; while(1) PORTF = 0x00; PORTK = 0xFF; } return 0;
Time Delay By using a for loop By using predefined C functions (library) Using AVR timers Crystal frequency is the important factor in calculating time delays Complier used to compile the C program (code)
Write a program to toggle PORTK continuously with a 250ms delay Write a program to toggle PORTK continuously with a 250ms delay. Crystal frequency is 16MHz. #include <avr/io.h> void delay100ms(void) { unsigned int i; for(i=0;i<42150;i++); } int main (void){ DDRK = 0xFF; while(1) PORTK = 0xFF; delay100ms(); PORTK = 0x00; return 0; #include <avr/io.h> #include<util/delay.h> int main (void) { DDRK = 0xFF; while(1) PORTK = 0xFF; _delay_ms(250); PORTK = 0x00; } return 0;
LEDs are connected to pins of PORTK LEDs are connected to pins of PORTK. Write a program that shows the count from 00H to FFH (0000 0000 to 1111 1111) on the LEDs. #include <avr/io.h> #include<util/delay.h> int main (void) { DDRK = 0xFF; while(1) PORTK++; _delay_ms(200); } return 0;
Write a program to get a byte of data from PORTF, and then send it to PORTK. #include <avr/io.h> int main (void) { DDRK = 0xFF; // OUTPUT DDRF = 0x00; // INPUT while(1) PORTK = PINF; } return 0; #include <avr/io.h> int main (void) { unsigned char temp; DDRK = 0xFF; // OUTPUT DDRF = 0x00; // INPUT while(1) temp = PINF; PORTK = temp; } return 0;
I/O PORT Bit-wise Programming: Bit-wise Operators in C: AND (&), OR (|), EX-OR (^), INVERTER (~), SHIFT RIGHT (>>), SHIFT LEFT (<<)
Write a program to toggle only bit 4 of PORTK continuously without disturbing the rest of the pins #include <avr/io.h> #include<util/delay.h> int main (void) { DDRK = 0xFF; // OUTPUT while(1) PORTK = PORTK | 0b00010000; //set bit 4 of PORTK _delay_ms(100); PORTK = PORTK & 0b11101111; //set clear 4 of PORTK } return 0;
Write a program to get the status of bit 5 of PORTF and send it to bit 7 of PORTK continuously. #include <avr/io.h> int main (void) { DDRF = DDRF & 0b11011111; // pin 5 of PORTF is INPUT DDRK = DDRK | 0b10000000; // pin 7 of PORTK is OUTPUT while(1) if (PINF & 0b00100000) //check pin 1 of PINF PORTK = PORTK | 0b10000000; //set pin 7 of PORTK else PORTK = PORTK & 0b01111111; //clear pin 7 of PORTK } return 0;
A door sensor is connected to bit 1 of PORTF, and LED (buzzer) is connected to bit 7 of PORTK. Write a program to monitor door sensor and, when it opens, turn on the LED (buzzer). #include <avr/io.h> int main (void) { DDRF = DDRF & 0b11111101; // pin 1 of PORTF is INPUT DDRK = DDRK | 0b10000000; // pin 7 of PORTK is OUTPUT while(1) if (PINF & 0b00000010) //check pin 1 of PINF PORTK = PORTK | 0b10000000; //set pin 7 of PORTK else PORTK = PORTK & 0b01111111; //clear pin 7 of PORTK } return 0;
according to the following table: Write a program to read pins 0 and 1of PORTF, and issues a value (data or number) to PORTK according to the following table: #include <avr/io.h> int main (void) { unsigned char z; DDRK = 0xFF; DDRF = 0x00; while(1) z = PINF; z = z & 0b00000011; switch (z) case (0): PORTK = 0x0F; break; } case (1): PORTK = 0x55; pin 1 Pin 0 Value 0x0F 1 0x55 0xAA 0xF0 case (2): { PORTK = 0xAA; break; } case (3): PORTK = 0xF0; return 0;
Compound assignment operator in C: To reduce coding (typing), we can use compound statements for bit-wise operators in C. Write a program to get the status of bit 5 of PORTF and send it to bit 7 of PORTK continuously. #include <avr/io.h> int main (void) { DDRF &= 0b11011111; // pin 5 of PORTF is INPUT DDRK |= 0b10000000; // pin 7 of PORTK is OUTPUT while(1) if (PINF & 0b00100000) //check pin 1 of PINF PORTK |= 0b10000000; //set pin 7 of PORTK else PORTK &= 0b01111111; //clear pin 7 of PORTK } return 0;
Bit-wise shift operation in C: There are two bit-wise shift operators. Examples of shift operators in C: 0b00010000 >> 3 = 0b00000010 //shifting right 3 times 0b00010000 << 3 = 0b10000000 //shifting left 3 times 1 << 3 = 0b00001000 //shifting left 3 times Bit-wise shift operation and bit manipulation: For improving code clarity; Instead of writing “0b00100000”, we can write “0b00000001 << 5” or simply “1 << 5” OR Sometimes we need numbers like 0b11101111. To generate such a number, first shift then invert it. “0b11101111” can be written as “~ (1<<4)”
Write a program to get the status of bit 5 of PORTF and send it to bit 7 of PORTK continuously. #include <avr/io.h> int main (void) { DDRF = DDRF & ~(1<<5); // pin 5 of PORTK is INPUT: DDRK &= (~ (1<<5)); DDRK = DDRK | (1<<7); // pin 7 of PORTF is OUTPUT: DDRF |= (1<<7); while(1) if (PINF & (1<<5)) //check pin 1 of PINF PORTK = PORTK | (1<<7); //set pin 7 of PORTK: PORTK |= (1<<7); else PORTK = PORTK & ~(1<<7); //clear pin 7 of PORTK PORTK &= ~(1<<7); } return 0;
A door sensor is connected to bit 1 of PORTF, and LED (buzzer) is connected to bit 7 of PORTK. Write a program to monitor door sensor and, when it opens, turn on the LED (buzzer). #include <avr/io.h> #define SENSOR 1 #define LED 7 int main (void) { DDRF &= ~(1<<SENSOR); // pin 1 of PORTF is INPUT DDRK |= (1<<LED); // pin 7 of PORTK is OUTPUT while(1) if (PINF & (1<<SENSOR)) //check pin 1 of PINF PORTK |= (1<<LED); //set pin 7 of PORTK else PORTK &= ~(1<<LED); //clear pin 7 of PORTK } return 0;
To generate more complicated numbers, simply OR the numbers. Example: one in position B7 and another in B4. (1<<7)|(1<<4)