Topic 10 - AVR IO in C (ISMAIL - FKEUTM 2018)
Topic 10 - AVR IO in C (ISMAIL - FKEUTM 2018)
AVR Input/Output
Interface with C
ISMAIL ARIFFIN
FKE UTM
CONTENTS
Real World I/O
AVR I/O Interface
Elementary I/O Interface
LED Control
MSI devices
Real World Input/Output
o Real world devices for sending and receiving data in electronic
system.
o Input devices – data provider – sense heat, pressure, image: Switch,
Keypad, Keyboard, Microphone,, Sensor (Temperature, Gas. Water
Level) , Transducer, Scanner, Camera, Rain Gauge )
o Output devices – data controller – beacon signal, flare light, siren
sound, run motor, display text : Light Emitting Diode (LED), Liquid
Crystal Display (LCD), Lamps (Home, Street) Electrical Motor ,
Actuator (Rotational TV Aerial ), Video monitor, Speaker, Printer
o Real world external devices need an interface circuit to
interconnect with the AVR microcontroller.
o I/O interface scheme:
o Elementary I/O: Simple two-state devices such as LED and switch.
o Parallel I/O: Data exchanged one byte at a time.
o Serial I/O: Data exchanged one bit at a time.
Real World
Air
Interface to AVR
Water Gas
Soil
Sensors Valves
LDR Real world Sprinklers
IR Environment
CCD
Switches LED
Keypad LCD
RFID, Human Light
Keyboard Alarm
Buzzer
DC Motor
AVR I/O Interface Features
(I/O Memory – I/O Task)
AVR Interface Pins
FORTY (40) interface pins:
Power Supply (4)
- Vcc, Avcc, Gnd (2)
Reset (1) – Active low
Aref (ADC volt ref ) (1)
External Clock (2)
Xtal2, Xtal1
Dual function pins - shared
1. I/O (32) = PORT (4)
2. ADC (8), External
Interrupts (3), Serial, Timers
ATMega32 Supply & Reset
o The pins marked ‘Gnd’ are to
be grounded.
o ‘Vcc & AVcc’ are to be given
5V.
o The ‘Reset’ pin is also high but
we usually prefer to put a
switch at this point for the
reset of the chips. If the switch
is pressed for a minimum pulse
of time then it will Reset the
chip.
Example: To set Port A pins 0 to 3 for input, pins 4 to 7 for output, we write
C code
DDRA = 0b11110000; // configure pins
bit 7 6 5 4 3 2 1 0
DDRA 1 1 1 1 0 0 0 0
Register Input Pins Address (PINx) is used to read input data from port.
Example: To read the input pins of Port A, we write C code
unsigned char temp; // temporary variable
temp = PINA; // read input
Depending on the device selected in your project, file ‘io.h’ will automatically
redirect to a specific header file.
Example
For ATmega32, the specific header file is ‘avr/iom32.h’.
This header file is printed in Appendix A of the lab notes.
It lists the C names and addresses for all ATmega32 registers.
We always use the C names in our code.
Configuring AVR I/O Pin
#include <avr/io.h>
#include <avr/io.h>
Int main () {
DDRB=0x00 ;
DDRC=0xFF ;
while (1) {
temp = PINB ; // read data from port B
sum = temp + 5 ;
PORTC = sum ; // send data to port C
}
. return 1 ;
}
I/O Port Registers: Pull-Up Resistor
o Example of codes with pull-up resistor is activated for port C.
#include <avr/io.h>
Int main () {
DDRB=0x00 ; // make port B as input
DDRC=0xFF ; // make port C as output
PORTB = 0xFF ; // pull-up resistors of PORTB
while (1) {
temp = PINB ; // read input from port B
result = temp + 5 ; // add input to 5
PORTC = result ; // send result to port C
}
return 1 ;
}
I/O Port Registers: Example I/O Program
o The following code will toggle all 8 bits of Port B forever with some time delay
between “on” and “off” states:
while (1) {
PORTB=0xFF ;put 0xFF on port B pins
_delay_ms(50) ; // delay 50ms
PORTB=0x00 ;put 0x00 on port B pins
_delay_ms(50) ; // delay 50ms
}
return 1;
}
I/O Port Registers: Example I/O Program
o Write a program that toggles PORTA.4 continuously.
#include <avr/io.h>
#include <util/delay.h>
int main(void) {
volatile unsigned char temp ;
DDRA= (1<<PORTA4) ; // Porta.4 as output
temp = (1<<PORTA4) ; // initial LED display
while (1) {
PORTA = temp ; // PORTA4 LED display
_delay_ms(75)
temp = ~temp ; // toggel LED
}
return 1 ;
}
I/O Port Registers: Example I/O Program
o Write a program to perform the following:
a) Keep monitoring the PB2 bit until it becomes HIGH;
b) when PB2 becomes HIGH, write value $45 to Port C, and also send a
HIGH-to-LOW pulse to PD3.
volatile unsigned char temp ;
int main () {
DDRB = ~ (1 << PINB2); // PINB2 as input
DDRC = 0xFF ; // PORTC = output PB2
DDRD =(1<<PORTD3) ; PD3 as output
while {
temp = PINB |(1<< PINB2) ;
if (temp == (1<<PINB2)) { PD3 PortC
PORTC = 0x45 ;
PORTD = (1<<PORTD3) ; // high PD3
_delay_ms(75) ;
PORTD =~ (1<<PORTD3); //low PD3
}
else
break;
}
return 1 ;
}
Elementary I/O Interface
Elementary I/O: Introduction
o Elementary I/O is a two-state peripheral devices which allowing
to a state condition. e.g. bulb, the bulb can only either light On or
light Off.
o In AVR, it can involve more than one bit at a time, i.e BCD
o Requirements:
o Bit signals can be written to output devices via AVR program
o Bit signals can be read from input devices via AVR program
o Support devices:
o Latches such as 74LS374 for output.
o Tri-state buffers such as 74LS244 for input.
o Output devices:
o LED, bulbs, 7-segment display, iquid crsytal display (LCD), relay coils.
o Input devices:
o Push/toggle/DIP switched, Proximity switch, Rotary BCD coder,
Matrix keypad, Temperature sensor, Light Dependent Resistor (LDR)
Elementary Output: LED
o LED is a semiconductor device that
converts electrical energy directly into
a discrete colour of light.
o LED has two terminals and must be
connected correctly.
o Anode (+) – long lead and has shorter
end inside the led.
o Cathode (-) - short lead, has larger end
inside the led and sometimes slight flat
on the body of round led.
o LED is easily damaged by heat.
o It has variety of colors depending by
the semiconductor material used.
8-bit Parallel LED panel
Active High Panel (Common Cathode) Active Low Panel (Common Anode)
RGB LED
Wiring RGB LED
Active Low Device (Common Anode)
Active High Device(Common Cathode)
Elementary Output: LEDs
o Never connect an LED directly to a
battery or power supply! It will be
destroyed almost instantly because too
much current will pass through and
burn it out.
o LEDs must have a resistor in series to
limit the current to a safe value, for
quick testing purposes a 1k resistor is
suitable for most LEDs if your supply
voltage is 12V or less.
Elementary Output: LEDs
o The resistor value, R is given by:
R = (VS – VL) / I
LSB
PORTA
MSB
volatile unsigned char temp = 0xFF ; // initial common anode LEDS display
while (1) {
PORTC=temp ; // display LED
_delay_ms(1000) ; // hold LED for 1s
--temp : // next count-up display
}
return 1;
}
Elementary Output : Exercises
o Write a FLASH LED program to on and off all the common anode
eight LED at port C in the interval of 1 second.
#define F_CPU 1000000 // CPU frequency 1 MHz
#include <avr/io.h> // io memory
#include <util/delay.h> // delay
while (1) {
PORTC=temp ; // LED display
_delay_ms(1000) ; // hold on 1s
temp = ~temp : // toggle
}
return 1;
} Project: Milestone 1
Elementary Output: 7-Segment Display
o Two types of common in 7
segment display:
o Common-anode - requires VCC,
LED ON when Output is LOW.
o Common-cathode - NOVCC, LED
ON when Output is HIGH.
o Note: TTL and CMOS devices are
normally not used to drive the
common-cathode display directly
because of current (mA)
requirement. A buffer circuit is
used between the decoder chips
and common-cathode display.
Seven Segment
Elementary Output: 7-Segment Display
o There are applications where you need to display a
decimal digit using a seven segment LED display.
o The display could represent e.g. the number of
times a switch was pressed. dp
o Digits 0-9 and hex A-F can be displayed by giving
the proper 7-segment codes
dp G f e d c b a 0x q g f e d c b a 0x
0 0 1 1 1 1 1 1 3f 8 1 1 1 1 1 1 1 7f
1 0 0 0 0 1 1 0 06 9 1 1 0 0 1 1 1 67
2 1 0 1 1 0 1 1 5b A 1 1 1 0 1 1 1 77
3 1 0 0 1 1 1 1 4f b 0 0 1 1 1 1 1
4 1 1 0 0 1 1 0 66 C 0 1 1 1 0 0 1
5 1 1 0 1 1 0 1 6d d 1 0 1 1 1 1 0
6 1 1 1 1 1 0 1 7d E 1 1 1 1 0 0 1
7 0 0 0 0 1 1 1 09 F 1 1 1 0 0 0 1
3
#include <avr/io.h>
int main () [
DDRC=0xFF; //set portC as output
PORTC= 0xFF; // pull-up resistor of PORTC
while (1) {
PORTC=0x06 ; // segment=digit character 1
}
return 1;
}
Elementary Output: 7-Segment Display
Example
o Example: A common cathode 7-
segment is connected to PORTA.
Write a code that display 3 on the 7-
segment.
#include <avr/io.h>
Elementary Output: 7-Segment Display Using Array
o Example: Using the 7-segment display connected to PORT B, write C code to
display number 0 to 9 continuously in interval of 1 second. .
#define F_CPU 1000000
#include <avr/io.h>
#include <avr/pgmspace.h>
#include <util/delay.h>
int main(){
unsigned char tempdata,i;
DDRB=0xFF ; //set portB as output
PORTB=0xFF ; //pul-up resistor
ATmega32
while (1) { 0
i=0 ;
8
5 6 1
do{ PORTB
tempdata= pgm_read_byte_near(&digit[i]); 4 2
PORTB=tempdata; 3
_delay_ms(1000); //1 sec
i++;
} while (i<=9) ;
} Project: Milestone 2
return 1;
}
Elementary Output: Two 7-Segment Displays
● What happens if you need to drive two 7-segment
LEDs connected to Port B, but don’t have enough
ports?
─ Assume you do have one more output pin
available
o Port C, bit 0
o Assume it has been configured as an output
o The following circuit would work …..
Elementary Output: Two 7-Segment Displays
● Your program must output the code for LED 1 on Port B and
then select LED 1 by placing a 0 on PC0
● Then your program must output the code for LED 2 on Port B
and then select LED 2 by placing a 1 on PC0
─ You must then continue to alternately light the two LEDs
CC
4-Digit 7-Segment LED Display
4-Digit 7-Segment LED Display Wiring
Segment (dp, g, f, e, d, b, c, b and a
int main() {
DDRB = ~(1<<PORTB0) | (1<<PORTB7) ;// PB0input,PB7output
PORTB = (1<<PORTB0) ; // Pull-up PB0
volatile unsigned temp:
while (1) {
temp = PINB ; // read PB0
if (temp == ~(1<<PORTB0))
PORTB = 1 << PORTB7 ; // PB7 LED is ON
else
break;
}
return 1;
}
Elementary Input: Parallel Switches
o Example: Parallel switches are connected
at pin PA0 to PA7. write a program to get +5V
AVR 1K
the status of the switches and display
PA0
them at the common anode LEDs
PA1
connected to Port C.
PA2
#include <avr/io.h>
PA3
int main(){ PA4
DDRA=0x00 ;//make PORTA as input PA5
PORTA=0xFF ;//pull-up PORTA
DDRC=0xFF ;//make PORTC as output PA6
PA7
volatile unsigned char temp;
while (1) {
temp=PINA ;read switch data
VCC
Buffer 0 Buffer 1
Gnd Gnd
Read Buffer 0
Store Buffer 0
Enable Buffer 1
Read Buffer 1
Store Buffer 1
MSI Devices: PISO
o PISO is parallel input serial output, 74LS165.
o It used to save number of input pins into µC.
o Has two control pins, one data input into µC: total 3 pins
PIN_2
VCC/Gnd
PIN_0
PIN_1
MSI Devices: Latch level trigger
o To store data by level trigger.
o It used to increase number of output pins.
o Has one control pin.
MSI Devices: Latch edge trigger
o To store data by edge trigger.
o It used to increase number of output pins.
o Has one control pin.
PIN_0
(clk)
PIN_1
(enable)
MSI Devices: SIPO
Gnd
PIN_0 (CLK)
VCC
PIN_1 (data out)
Port_C,
Port_C, Latch 0 PIN_3 (clk) Latch 1
PIN_2 (clk)
Gnd Gnd
Gnd
No bus sharing, output can always enable
MSI Devices: Output
o Example: increase number of output pins of port B from 8 to 16.
#include (avr/io.h>
Prepare LED
Send to LED
Prepare 7Seg
Send to 7Seg
MSI Devices: Bi-directional Buffer
o Can either be input or output.
o It used to control shared data bus.
o Eg. 74LS245.
PIN_1 (enable)
PIN_0 (direction)
Matrix Keypad
Switch Input Arrangement
• Switch Input Arrangement depends on type application
of input needed.
• It one bit input to multiple bits (maximum of 8 per
group)
• Data from the switch may be read directly, or as a
certain protocol (example the matrix keyboard).
• If input data is read at a 8-bit word size, and the data
from the switch is not a full 8 bits (because the switch
arrangement is not a full 8-bit, caution must be taken
when reading the data from the 8 bit input such that
the bits that is not connected to switch are mask off
(not taken as part of data).
MSI Devices: Keypad Encoder
o Have both inputs (push-button) and output (to micro-p).
o It used to read keypads.
o Eg. MM74C922.
interrupt
PIN_0
PIN_1
(enable)
MSI Devices: Keypad Encoder
0 to 15 for MM74C922
0 to 19 for MM74C923
MSI Devices: Keypad Encoder
o Example: write a program in order to input the data from the
keypad. In the program you should:
o Interrupt to Port C, Pin4
o Enable Port C, Pin5
o Data connected to Port B, Pin 0-3
0 1 2 3
4 5 6 7
8 9 A B
C D E F
Function ReadKeyPad() -1
int ReadKeyPad(void)
{
int keyPressed;
unsigned char upperNibble, keyCode, i;
upperNibble = 0xff;
for(i=0; i<4; i++)
{
_delay_ms(1);
KB_PORT_OUT = ~(0x01 << i);
_delay_ms(1); //delay for port o/p settling
upperNibble = KB_PORT_IN | 0x0f;
Function ReadKeyPad () -2
if (upperNibble != 0xff)
{
_delay_ms(20); //key debouncing delay
upperNibble = KB_PORT_IN | 0x0f;
if(upperNibble == 0xff) goto OUT;
keyCode = (upperNibble & 0xf0) | (0x0f & ~(0x01 << i));
while (upperNibble != 0xff)
upperNibble = KB_PORT_IN | 0x0f;
_delay_ms(20); //key debouncing delay
Function ReadKeyPad () -3
switch (keyCode) //generating key characetr to display on LCD
{
case (0xee): keyPressed = 0;
break;
case (0xde): keyPressed = 1;
break;
case (0xbe): keyPressed = 2;
break;
case (0x7e): keyPressed = 3;
break;
case (0xed): keyPressed = 4;
break;
Function ReadKeyPad () -4
case (0xdd): keyPressed = 5;
break;
case (0xbd): keyPressed = 6;
break;
case (0x7d): keyPressed = 7;
break;
case (0xeb): keyPressed = 8;
break;
case (0xdb): keyPressed = 9;
break;
case (0xbb): keyPressed = 0xA;
break;
Function ReadKeyPad () -5
case (0x7b): keyPressed = 0xB;
break;
case (0xe7): keyPressed = 0xC;
break;
case (0xd7): keyPressed = 0xD;
break;
case (0xb7): keyPressed = 0xE;
break;
case (0x77): keyPressed = 0xF;
break;
default : keyPressed = 255;
}//end of switch
OUT:;
}//end of if
}//end of for
return (keyPressed);
}
LCD panel RT204-1
A Full Wiring of LCD panel RT204-1
LCD conections: PortA --> LCD Data lines,
PD7 --> EN, PD6 --> RW, PD5 --> RS
Figure 1
Programming LCD
• Refer to LCD Commands.pdf for list of
commands.
• To write a command you have to do the
following steps:
1. Set LCD in command mode
2. Load data to port
3. Write data to LCD
4. Wait 2 clock cycle
5. Disable LCD
6. wait for 1ms
Function LCD_WriteCommand()
• The following Write a command instruction to the LCD based on LCD
Commands.pdf whose connection is as given in Figure 1. This function is
the used to write command to LCD for other function of the Lcd.
void LCD_WriteCommand (unsigned char Command)
{
PORTD &= ~0x20;// Set PORTD
LCD in &=
command
~0x80 mode
PORTA = Command;// Load data to port
PORTD |= 0x80; // Enable Write data to LCD
asm("nop"); //Wait 2 clock cycles
asm("nop");
PORTD &= ~0x80; // Disable Write data LCD
_delay_ms(1);// wait for 1ms
}
Function LCD_WriteDaTa()
• This function is the used to write one byte of data to LCD after the
command is selected. Some command may not need data, but some does.
For example the data of the character to print after selecting a command to
print character at LCD.
void LCD_WriteData (unsigned char Data)
{
PORTD |= 0x20 ;// Set LCD in data mode
PORTA = data ;// Load data to port
PORTD |= 0x80; // Enable Write data to LCD
asm("nop"); //Wait 2 clock cycles
asm("nop");
PORTD &= ~0x80; // Disable Write data LCD
_delay_ms(1);// wait for 1ms
}
Function LCD_init()
• Before you use the LCD you must initialize it as follows:
void LCD_init(void)
{
_delay_ms(100); // wait for 100ms
LCD_WriteCommand (0x38); // 8 data lines
LCD_WriteCommand (0x08); // display off
LCD_WriteCommand (0x01); // clear LCD memory
/*Clears all display and returns the cursor to
the home position (Address 0).*/
_delay_ms (10); // 10ms delay after clearing LCD
LCD_WriteCommand (0x06); // cursor setting
LCD_WriteCommand (0x0f); // display ON
}
Display ON/OFF
RS R/W DB7 DB6 DB5 DB4 DB3 DB2 DB1 DB0
=== === === === === === === === === ===
0 0 0 0 0 0 1 D C B
Command that Controls display of characters and cursor.
Details
D: The display is ON when D = 1 and OFF when D = 0.
C: The cursor is displayed when C = 1 and is not displayed when C = 0.
B: The character at the cursor position blinks when B = 1.
Functions to position cursor at LCD
• Position the LCD cursor at "row", "column"
void LCD_Cursor (char row, char column)
{
switch (row)
{
case 1: LCD_WriteCommand (0x80 + column - 1); break;
case 2: LCD_WriteCommand (0xc0 + column - 1); break;
default: break;
}
}
Exercise:
Write an AVR
program to display
digit 0 until 9 at the
common cathode 7-
segment as shown
in the given circuit
SUMMARY
Learn Elementary I/O devices