Types of Interfaces • Basic digital I/O operation • Bit access • PORT access • Analog Interface • ADC • DAC / PWM • Communication Line • USART • I2C • SPI • USB • Device Specific Interface • LCD • Camera • Keypad • Etc. Basic I/O Operation (Initialization) • Most of PORTs of microcontroller need to be initialized before accessed • Special function (if any) • Data direction • Initial value • AVR basic port operation • As Input • As Output • Can be configured at bit basis Basic I/O Operation (as Input) • AVR port can be configured as • Input floating • For interfacing with push-pull driven input • SPDT switch • Logic gates • Op-amp • Etc. • Input with internal resistor pull-up • For interfacing with pull driven only input • Dipswitch • Keypad • Push button • Open drain/open collector output • Etc. • Each bit in each port can be configured independently Basic I/O Operation (as Output) • AVR port can be configured as • Output Push Pull • Symmetric sink and source capability • Up to 20mA per pin • But can not exceed 100mA per port. • Initial condition can be set to logic 1 or 0 • Each bit in each port can be configured independently AVR Bit Microcontroller Port • All its ports are 8 bit wide • Every port has 3 registers associated with it each one with 8 bits • Every bit in those registers configure pins of particular port • Bit0 of these registers is associated with Pin0 of the port • Bit1 of these registers is associated with Pin1 of the port, …. and like wise for other bits. GPIO Register • Each GPIO PORT in AVR has three registers as follows : • DDRx register (Data direction register) • PORTx register (Port write register) • PINx register (Port read register) • (x can be replaced by A,B,C,D as per the AVR you are using) Hardware Schematic on each GPIO pin DDRx register • DDRx (Data Direction Register) configures data direction of port pins. • Means its setting determines whether port pins will be used for input or output. • Writing 0 to a bit in DDRx makes corresponding port pin as input, while writing 1 to a bit in DDRx makes corresponding port pin as output. • Example: • to make all pins of port A as input pins : DDRA = 0b00000000; • to make all pins of port A as output pins : DDRA = 0b11111111; • to make lower nibble of port B as output and higher nibble as input : DDRB = 0b00001111; PORTx register • PORTx is used for two purposes. • To output data • when port is configured as output • To activate/deactivate pull up resistors • when port is configures as input PORTx register as Output • When you set bits in DDRx to 1, corresponding pins becomes output pins. • Data can be written into respective bits in PORTx register. • This will immediately change state of output pins according to data you have written. • Example : • to output 0xFF data on port b • DDRB = 0b11111111; //set all pins of port b as outputs • PORTB = 0xFF; //write data on port • to output data in variable x on port a • DDRA = 0xFF; //make port a as output • PORTA = x; //output variable on port • to output data on only 0th bit of port c • DDRC.0 = 1; //set only 0th pin of port c as output • PORTC.0 = 1;1 //make it high. PORTx register as Input • When you set bits in DDRx to 0, i.e. make port pins as inputs • corresponding bits in PORTx register are used to activate/deactivate pull-up registers associated with that pin. • In input mode, when pull-up is enabled, default state of pin becomes ‘1’. • Even if it did not connected to anything, it will read as 1. • when it externally driven to zero(i.e. connect to ground / or pull-down), it will be read as 0. Enabling Internal Pull Up Resistors • Making the DDRx bits to 0 will configure the PORTx as Input. • The corresponding bits in PORTx register can be used to enable/disable pull-up resistors associated with that pin. • To enable pull-up resistor, set bit in PORTx to 1, and to disable set it to 0. Example • to make port a as input with pull-ups enabled and read data from port a • DDRA = 0x00; //make port a as input • PORTA = 0xFF; //enable all pull-ups • y = PINA; //read data from port a pins • to make port b as tri stated input • DDRB = 0x00; //make port b as input • PORTB = 0x00; //disable pull-ups and make it tri state • to make lower nibble of port a as output, higher nibble as input with pull-ups enabled • DDRA = 0x0F; //lower nib> output, higher nib> input • PORTA = 0xF0; //lower nib> set output pins to 0, higher nib> enable pull-ups Internal Pull up resistor • Activated when pin is connected to pull down only logic, for example: • Push button • Dip switch • Open drain or open collector output • etc. • Deactivated if the input capable of giving push/pull logic (logic 1 or logic 1) to reduce the power consumption when input pull down the line, for example • TTL or CMOS circuit • Other logic IC pin • Other GPIO pin • SPDT Switch • Etc. Simple I/O register summary register bits → DDRx.n PORTx.n PINx.n pin function↓ tri stated input 0 0 read data bit x = PINx.n; pull-up input 0 1 read data bit x = PINx.n; output 1 write data bit writing 1 toggles the PORTx.n = x; state of the output pin. PINx.n = 1; Problem Example • An AVR MCU is used to control these following I/O • PORT A is connected to LED with initial condition all LEDs are off (active high) • PORTB bit 0-3 are connected to dipswitch • PORTB bit 4-5 are connected to push button • PORTC bit 0-3 are connected to SPDT switch • PORTC bit 4-5 are connected to open drain comparator • Please make program in C to initialize those configurations Problem Example #2 • Please describe the results of each configuration 1. DDRA = 0xF0; PORTA = 0x0F; 2. DDRB = 0xFF; PORTB = 0xF0; 3. DDRC = 0x00; PORTC = 0xF0; 4. DDRD = 0x0F; PORTD = 0xF0; 5. DDRA = 0xFF; PORTA = 0x0F; 6. DDRB = 0xAA; PORTB = 0x00; 7. DDRC = 0xBB; PORTC = 0xFF; 8. DDRD = 0xCC; PORTD = 0x0F; Logic Manipulation • Shifting • Rotating • Masking Logic shifting operation • In C language the operator to shift logic data are • << to shift bit(0) left • >> to shift bit(s) right • Syntax: • x = x>>n // x is shifted n bits to the right • x = x<<n // x is shifted n bits to the left • When shifted left the least significant bit(s) will become zero • When shifted right the most significant bit(s) will become zero • Logic Shifting Example • X = 0XFF<<2 • X will become 0x3FC if X can contain 12bit data or more (short, long, etc) • X will become 0xFC if X only can contain 8 bit data (char or unsigned char) • X = 0XFF>>2 • X will become 0x3F Logic Rotate operation • In C language the operator to rotate operation actually use combination of shift and or logic operation. • Syntax for 1 bit shift for 8 bit data • X = X>>1 | X<<7 // 1 bit rotate right • X = X<<1 | X>>7 // 1 bit rotate left • Syntax for 1 bit shift for 16 bit data • X = X>>1 | X<<15 // 1 bit rotate right • X = X<<1 | X>>15 // 1 bit rotate left Exercise #3 • How to rotate 2 bit data from 8 bit data in • Rotate right operation • Rotate left operation • How to rotate 3 bit data from 16 bit data in • Rotate right operation • Rotate left operation Bits input masking • Masking can be used to ignore other logic in one port whenever other pins are needed • For example, we need to read 4 pin dipswitch combination which is located to pin 0, 1, 2, 3 of port A. • We want to read just those pins data to variable X. • We need byte masking to filter other pins and make at zero for example • How to mask it? • The ignored pins can be masked with logic 0, and the required pins are masked with logic 1 • The mask byte is 0B00001111 • X = PINA & 0B0001111 • Result of X will vary between 0000 to 1111 according to the dipswitch combination. Bits Output Masking • Output masking is used to modify several bit(s) from the same port without affecting other pins • How to do it? • We need to read first the existing data from the port • We mask the data from the reading (filter the unused pin(s)) • Combine the masked data with the data to be written using OR operation Example • Motor driver is driven using on off logic using two bits data. Those motor driver are connected to pin 0 and 1 from port B. • We want to update pin 0 to logic 1, and pin 1 to logic 0. 0B01 • How to make it? • X = PINB; // read the existing data of PORTB • X = X & 0B11111100; // remove data from bit 0, 1 • X = X | 0B01; // write the data to the masked data • PORTB = X; // rewrite the manipulated data to PORTB • We can simply write: • PORTB = (PINB & 0B11111100)|0B01; Assignment Make a data rotation in PORT B for nibble high (bit 4- 7) to right and nibble low (0-3) to left. Initial data of port B is 0B10000001. So the data will be 1. 01000010 2. 00100100 3. 00011000 4. 10000001 // return to initial data