Beruflich Dokumente
Kultur Dokumente
(NTIL)
Nalanda Telematics & Informatics Limited (NTIL) is engaged in the design and development of embedded systems for host of real time industry applications with rich expertise in the hardware and firmware designs on microprocessors, micro -controllers and DSPs not limiting to 8051/AVR /ARM/DSP. The company specializes in interfacing different types of peripherals for USB/RS232/I 2C/Ethernet devices to micro -controllers. NTIL developed inhouse expertise in the entire smart card development using micro -controllers. Smart card product suite (ISO 7816) by NTIL provides a universal smart card reader with serial/USB interface along with a card devel opment kit. NTIL also supplies c ontactless readers and Reader Modules based on Philips's Mifare & Icode Technology. A unique micro -controller based product used for remote management of utilities based on GSM technology has been conceived and deployed for different applications. In a similar fashion, for automatic mapping of utilities NTIL has developed a product based AVR micr o-controller and GPS technology with complete hardware, firmware to software design and development expertise for building products with embedded Ethernet on micro -controller platform. At NTIL the entire gamut of activities from design to end product are carried out with highest quality standards.
MICROCONTROLLERS
A microcontroller is a SPECIAL PURPOSE COMPUTER. Unlike a general purpose computer which can run thousands of program s, a microcontroller does only on e thing well - the task which it is programmed to carry out. General characteristics of a microcontroller are as follows,
y
Microcontrollers are embedded inside some other device, generally a consumer product, in order to con trol the features and actions of that device. Thus a microcontroller is also known as an EMBEDDED CONTROLLER.
Microcontrollers are dedicated to one task only and run a specific program which is burnt into its FLASH MEMORY.
devices. A
consumes about 50 mW of power compared to 150W consumed by a desktop plugged to a wall socket.
y
A microcontroller has a dedicated input device such as a keypad or switches and often, but not always, a small LED or an LCD display for output. A microcontroller
also takes inputs from the device it is controlling and sends the output to the relevant components of the device.
y
A microcontroller is often small in size and of low cost as its components are chosen to minimize the size and cost of the chip.
A microcontroller is often , but not always, ruggedized in some way as it has to operate under extreme conditions in some applications.
Uniform instruction format, using a single word with the opcode in the same bit positions in every instruction demanding less complex decoding.
Identical general purpose registers enabling any register to be used in any context , simplifying compiler design.
Simple addressing modes. Complex addressing is performed through sequences of arithmetic and/or load -store operations.
The need for a family of microcontrollers is due to the sheer number and varied nature of devices and applications that they can run. Thus , depending upon various demands such as amount of memory required, number of I/O lines , type of interface etc. a suitable microcontroller can be chosen to optimize the size and reduce the cost of the whole system. The basic function of a microcontroller is to read the input and set the output accordingly. The microcontroller pins are designed to be either input or output. These are called GENERAL PURPOSE I/O LINES or GPIO lines. A group of these I/O lines is called a port. Besides these GPIO lines there are also some special purpose pins which are clubbed with these I/O lines.
ller V
ed amil of
ri
rojects
me
s the
Tmega
hich
icrocontrollers.
V
V
Tmega
Tmega has I/ I/ I/ I/ I/ I/ lines distri ted among orts as follows,
y y y y y
Pins 01-08: Port B (PB0-PB7) Alternate functions of Port B PB0: T0 (Timer/Counter0 External Counter Input) OC0 (Timer/Counter0 Output Compare Match Output) y PB1: T1 (Timer/Counter1 External Counter Input ) y PB2: AIN0 (Analog Comparator Positive Input) y PB3: AIN1 (Analog Comparator Negative Input) y PB4: SS (SPI Slave Select Input) y PB5: MOSI (SPI Bus Master Output/Slave Input) y PB6: MISO (SPI Bus Master Input/Slave Output) y PB7: SCK (SPI Bus Serial Clock) Pin 09: RESET (Reset Input) Pin 10-17: Port D (PD0-PD7) Alternate functions of Port D y PD0: RXD (USART Input Pin) y PD1: TXD (USART Output Pin) y PD2: INT0 (External Interrupt 0 Input) y PD3: INT1 (External Interrupt 1 Input) y PD4: XCK (USART External Clock Input/Output) y PD5: OC1A (Timer/Counter1 Output Compare A Match Output) y PD6: WR (Write Strobe To External Memory) y PD7: RD (Read Strobe From External Memory) Pin 18: XTAL1 (Input To The Inverting Oscillating Amplifier & Input To The Internal Clock Operating Circuit ) Pin 19: XTAL2 (Output From The Inverting Oscillator Am plifier) Pin 20: GND (Ground) Pin 21-28: Port C (PC0-PC7) Alternate functions of Port C y PC0: A8 (External Memory Interface Address Bit 8) y PC1: A9 (External Memory Interface Address Bit 9) y PC2: A10 (External Memory Interface Address Bit 10) y PC3: A11 (External Memory Interface Address Bit 11) y PC4: A12 (External Memory Interface Address Bit 12) y PC5: A13 (External Memory Interface Address Bit 13) y PC6: A14 (External Memory Interface Address Bit 14) y PC7: A15 (External Memory Interface Address Bit 15) Pins 29-31: Port E (PE2-PE0) o Alternate functions of Port E y PE2: OC1B (Timer/Counter Output Compare B Match Output) y PE1: ALE (Address Latch Enable To External Memory)
y
y y
y y y y
PE0: ICP (Timer/Counter1 Input Capture Pin) INT2 (External Interrupt2 Input) Pins 32-39: Port A (PA7-PA0) Alternate functions of Port A y PA7: AD7 (External Memory Interface Address & Data Bit 7) y PA6: AD6 (External Memory Interface Address & Data Bit 6) y PA5: AD5 (External Memory Interface Address & Data Bit 5) y PA4: AD4 (External Memory Interface Address & Data Bit 4) y PA3: AD3 (External Memory Interface Address & Data Bit 3) y PA2: AD2 (External Memory Interface Address & Data Bit 2) y PA1: AD1 (External Memory Interface Address & Data Bit 1) y PA0: AD0 (External Memory Interface Address & Data Bit 0) Pin 40: VCC (Digital Supply Voltage)
y
High-performance, Low -power AVR 8-bit Microcontroller RISC Architecture o o o o o 130 Powerful Instructions Most Single Clock Cycle Execution 32 x 8 General Purpose Working Registers Fully Static Operation Up to 16 MIPS Throughput at 16 MHz On-chip 2-cycle Multiplier
Endurance: 10,000 Write/Erase Cycles o Optional Boot Code Section with Independent Lock bits
y y
In-System Programming by On-chip Boot Program True Read-While-Write Operation o 512 Bytes EEPROM
Endurance: 100,000 Write/Erase Cycles o o o 512 Bytes Internal SRAM Up to 64K Bytes Optional External Memory Space Programming Lock for Software Security
Peripheral Features o o One 8-bit Timer/Counter with Separate Prescaler and Compare Mode One 16-bit Timer/Counter with Separate Prescaler, Compare Mode, and Capture
o o o o
y
Programmable Serial USART Master/Slave SPI Serial Interface Programmable Watchdog Timer with Separate On-chip Oscillator On-chip Analog Comparator
Special Microcontroller Features o o o Power-on Reset and Programmable Brown -out Detection Internal Calibrated RC Oscillator External and Internal Interrupt Sources
TRAINERS KIT
A custom made microcontroller kit was used for all applications and mini projects during the training period. The board has open architecture. The microcontroller pins are not connected to any peripherals. Instead, all port lines are brought out to the berg strip. These port lines can be connected to the desired peripherals through connecting cables. The board has following peripherals,
y y y y y y y y y y y y
8 LEDs 8 Switches 216 Character alpha-numeric LCD 44 Matrix keypad 8-bit ADC 8-bit DAC 2 12V Relays Buzzer EEPROM Real time clock Level translation circuit for serial communication Motor drive circuit
ESS
IES
Power dapter Input
onnecting
ables
Serial
able it
utput:
V V
Mode #1: The board waits for a new program to be dumped into the flash memory of the microcontroller.
Mode #2: The board executes the program already burnt into the flash memory of the microcontroller.
The microcontroller decides which mode to boot up with the help of the boot loader. The flash memory in the microcontroller has a section called the boot load section. When the board is powered up, the control is transferred to this section of the flash memory. The boot load code does the following,
y y y
Check the status of PC0 I/O line (First line of Port C) If PC0 = 0; Go to Mode #1. If PC0 = 1; Go to Mode #2.
The status of PC0 can be controlled by connecting it to any one of the on board switches. When the switch is pressed , PC0 = 0 and when not pressed, PC0 = 1. So if a new program is to be dumped into the microcontroller, the switch connected to PC0 should be kept pressed while powering up the board.
AVR STUDIO
AVR STUDIO is a utility provided by ATMEL for writing programs, compiling them and dumping them into the microcontrollers flash memory. Using the AVR STUDIO utility we can create new projects, i.e. programs, compile them and dump them into the microcontroller flash memory. AVR STUDIO also provides debugging tools to check the functionality of the written program before dumping it into the microcontroller flash memory.
HIGHER NIBBLE
LOWER NIBBLE
Each bit in the register can be assigned only two possible values either 1 or 0. Thus, if bits 0, 2, 4, 5, 6, 7 are to be set high and the rest to be low, then, the bi nary assignment would be 11110101. To convert this binary value to hexadecimal, first of all the binary value is broken up into two 4-bit sections known as NIBBLES. Bits 0-3 form the lower nibble and bits 4 -7 form the higher nibble. Now the binary value of each nibble is converted into its hexadecimal equivalent. 11110101 = 1111 HN
3 2 1 0
0101 LN
1111 (BIN) = 2 1+2 1+2 1+2 1 = 8+4+2+1 = 15 (DEC) = F (HEX) 0101 (BIN) = 230+221+2 10+201 = 0+4+0+1 = 5 (DEC) = 5 (HEX) Therefore, in place of assigning 11110101 we can simply assign 0xF5.
bit7 DDRB = 0xF0; (Lower nibble of port B is configured as I/P and higher nibble as O/P) OUTPUT INPUT
bit0
After configuring the port lines one can either write data (0 or 1) to a port line (If it is configured as output) or read from it. Each port has a separate register called PORTX which enables one to write data to the port lines by setting them high or low. bit7 PORTB = 0x55; (Alternate bits are set as high) bit0
LOW
HIGH
For reading data from a port one has to read the PINX register associated with each port. If PINX is assigned to some variable of unsigned char acter type, the value of the variable will be the status of the port. bit7 status = PINB; (The value of status will be 0xAA) bit0
VCC
RESISTOR
MICRO
LED
SWITCHES
The trainer kit accommodates 8 switches. The switch is a broken connection. One end of this connection is connected to the ground while the other end is brought out to a berg strip. In between there is a break in connection where the switch is placed. The connection is closed when the switch is pressed and is open when the switch is not pressed. Internal pull -ups are also present at the berg strip end which, when switches are connected to the port lines, connects the port lines to VCC through a resistor. These pull -ups need to be activated before reading the status of the port line. The internal pull -ups can be activated by assigning value 1 to the corresponding bit in the register . Now if the switch is not pressed the port lines retain the value 1 and if pressed, they are set to 0. VCC
MICRO
RESISTOR
SWITCH
GND
LCD INTERFACE
The LCD acronym stands for LIQUID CRYSTAL DISPLAY. The LCD provided on the board is alphanumeric, i.e. it can display alphabets as well as numerals. The LCD has two rows and each row has 16 characters. Thus, the LCD is called 216 LCD. The LCD operates on +5V voltage supply. The LCD has two types of lines,
y y
The data that will be put on data lines will be of two types
y y
Data for display to the LCD is to be given in ASCII form. In this form, each character is assigned a character code. For example, the ASCII code for A is decimal 65 or hex 0x41.
The Register Select control line enables the LCD to determine whether the received data is a command or is it intended to be displayed. If RS = 0; the data put on the data lines will be taken as a command. If RS = 1; the data put on the data lines will be taken as data for display. The Read/Write control line tells the LCD whether a read operation is required or a write operation is to be performed. If RW = 0; write operation is performed. If RW = 1; Read operation is performed. The enable control line instructs the LCD to take in the data. For this purpose, the enable control line is toggled, first making it high, giving a small delay and making it low. Now, before beginning to s tart displaying data on the LCD, the LCD needs to be initialized. Initialization involves sending commands to the LCD which will configure it. Some the commands that need to be configured are as follows,
y
The LCD supports both 4 -bit and 8-bit data interface , so one of them has to be chosen.
The characters on the LCD are displayed as a matrix of dots. Each character can be displayed as a 57 matrix or a 58 matrix. Thus, LCD has to be configured for the character size.
y y
The cursor can be made visible or invisible; it can either be steady or made to blink. After displaying a character the cursor can be incremented automatically or it can stay put.
8 bit data interface 5x7 character font 2 line display Display on Show cursor No blinking of cursor Clear display Cursor home
0x0E
y y y
0x01
y y
0x06 0x80
For clearing a bit, bitwise AND operation is carried out between the byte containing the required bit and the complement of the mask. Required Byte
1
Bitwise AND Operation
1
Mask
Synchronization between the receiving and transmitting ends is very important. Each character is represe nted by a byte, i.e. 8 bits, and all the bits are transferred serially. So the receiving end should know when the new character begins or the previous character ends. For this purpose two extra bits called the start and stop bits are associated with ea ch byte that is being transmitted. The start bit is a low bit while the stop bit is a high bit. At the beginning of a new character transfer, there will be a start bit followed by the byte to be transmitted and the stop bit at the end. Thus, communication is synchronized between the transmitting and the receiving ends.
The rate or speed at which the bits are being transferred also matters. Both the transmitting and the receiving ends should operate at the same speed. This rate of transfer is called the BAUD RATE and is measured in bits/second.
The number of data bits can be 5, 6, 7, 8 or 9 but 8 -bit characters are the most used ones.
For addressing each of the above mentioned issues the microcontroller is provided with a set of registers which are as follows,
UART BAUD RATE REGISTER (UBRR): UBRR is a 16 bit register split into two 8 -bit registers,
y y
The relation between UBRR, Baud Rate and the oscillator frequency at which the micro controller board is working is given as, UBRR = (F/(16BAUD RATE)) - 1 UART CONTROL & STATUS REGISTERS (UCSR) There are three control and status registers,
y y y
UCSRA contains the Receive Complete (RXC : bit7) and the UART Data Register Empty (UDRE: bit5) bits. Before reading the received bit we need to check whether the whole character has been received or not . RXC remains 0 as long as the character hasnt been completely and changes to 1 when it has been complete ly received. bit7 UCSRA RXC UDRE bit0
UCSRB contains the Receive Enable (RXE : bit4) and Transmit Enable (TXE : bit3) bits. Both the bits are to be set to 1 for enabling reception and transmission of data serially through UART. bit7 UCSRB RXE TXE UCSZ2 bit0
UCSRC contains Register Select (URSEL: bit7) for choosing whether to use the register as UBRRH or UCSRC (Single register is used in both ways). URSEL should be 1 when writing
UCSRC and 0 when writing UBBRH. It also accommodates UART Character Size (UCSZ0: bit 1, UCSZ1: bit 2) bits, which combine with UCSZ2 bit in UCSRB to determine the data width. UCSZ0 0 0 0 0 1 UCSZ1 0 0 1 1 1 UCSZ2 0 1 0 1 1 Data Width 5-bit 6-bit 7-bit 8-bit 9-bit
bit7
bit0
URSEL
UCSZ1 UCSZ0
OPERATING MOTORS
The microcontroller I/O pins can be used to operate motors indirectly as they dont have the drive capability to run them directly. A motor drive IC LM293D is used in between the I/O pins and the motors. The IN1 and IN2 pins of the IC are connected to two GPIO lines of the microcontroller. These pins are to be configured as output pins for the microcontroller. Truth table for motor control IC is as follows, ENABLE 1 1 1 IN1 0 1 0 IN2 1 0 0 Motor Status Clockwise Rotation Counter-Clockwise Rotation Stop
Enable +5V
+12V
Micro Controller
IN1
OUT1
L293D
DC Motor IN2 OUT2
The CS, RD and WR lines are inputs to the ADC while the INTR line is an output from the ADC. The digital output from the ADC is fed a port of the microcontroller. The control sequence for reading the digital output is as follows, 1. CS is made low. 2. WR is toggled: WR is made low, a delay is given, WR is made high. This starts the analog to digital conversion. 3. INTR line is monitored. It stays high as long is conversion is taking place and goes low when conversion is complete. 4. RD is made low. 5. Digital output is read from the port.
The trainers kit also has an on -board potentiometer of range 0 5V. This potentiometer can be connected to the input pin. Thus, the input can be varied and the correspo nding change in the output can be observed either through Hyperterminal or on the LCD. Digital Output
Micro
ADC
Analog Input
Controller
Analog Output
DAC
Micro Controller
MATRIX KEYPAD
A Matrix Keypad consists of sixteen (16) keys arranged in the form of a 44 matrix, from which it derives its name. The internal structure of the keypad consists of eight (8) data lines, one for each row and column. These data lines are brought out on two (2) berg strips having four (4) pins each, one strip for the columns and the other for the rows. The data lines for columns and rows are place d perpendicular to each other and the switches are positioned at their points of intersection. The rows and the columns of the keypad are connected to separate Ports of the microcontroller. One of these Ports is configured as input to the microcontroller w hile the other is configured as outpu t. Initially, all the data line s are set to logic value 1. When the switch is unpressed, the logic value of the intersecting data lines remains 1. But when the switch is pressed, the logic value of the intersecting data lines becomes 0. Thus, when a key is pressed, the logic values of the corresponding data lines change to 0. This causes a change in the status of the Port lines. By reading the status of the input pins for a specific status of the output pin, the pressed key can be identified.
R0
7 4 1 C
8 5 2 0
9 6 3 E
F1
R1
F2
F3
R2
F4
R3
C1 Keys
C2 Data Lines
C3
If key 8 is pressed, then, R0 = 0 & C1 = 0 Status of the port connected to the row nibble = 0xFE
1
R3
1
R2
1
R1
0
R0
R0 = 0 Pressed Key = 8 C1 = 0;
1
C3
1
C2
0
C1
1
C0
The status of the ROW and COLUMN Ports depend upon the pins to which the row and column nibbles have been connected. I have connected the row nibble to Port B as R0 - R3 connected to PB4 - PB7 and column nibble to Port C as C0 - C3 connected to PC4 - PC7. The status of the ports for all keys are as follows, (Values as per the afore mentioned connections)
KEY VALUE
COLUMN STATUS
PORT
0 1 2 3 4 5 6 7 8 9 F1 F2 F3 F4 E C
0xF7 0xFB 0xFB 0xFB 0xFD 0xFD 0xFD 0xFE 0xFE 0xFE 0xFE 0xFD 0xFB 0xF7 0xF7 0xF7
0xFD 0xFE 0xFD 0xFB 0xFE 0xFD 0xFB 0xFE 0xFD 0xFB 0xF7 0xF7 0xF7 0xF7 0xFB 0xFE
PROGRAM 1
Switching LEDS on and off (The program switches all the LEDs on and switches them off after 2 seconds . The process goes on repeating itself. ) /********************************************************************************************************** Port B : LEDs ****************************************************************************************************************/ #include<avr/io.h> #include<util/delay.h> int main() { DDRB = 0xFF; PORTB = 0xFF; while(1) { PORTB = ~PORTB; _delay_ms(2000); } }
//Configue Port B as output //Set all bits to 1; Switch off all the Leds initially
//Invert the status of Port B //Introduce a time delay of 2000 milli seconds
PROGRAM 2
Blinking LEDs (The program initially switches on all the LEDs and then toggles each LED every 2 seconds. The process goes on repeating itself.) /******************************************************************************************************** Port B: LEDs ********************************************************************************************************/ #include<avr/io.h> #include<util/delay.h> int main() { unsigned char blink; blink = 0x01; DDRB = 0xFF; //Configure Port B as output PORTB = 0x00; //Switch on all LEDs while(1) { PORTB = blink; _delay_ms(2000); blink = blink<<1; if(blink == 0x00) blink = 0x01; }}
PROGRAM 3
Toggling an LED (The program keeps on toggling an LED endlessly.) /******************************************************************************************************** Port B: LEDs PB4: LED to be toggled ********************************************************************************************************/ #include<avr/io.h> #include<util/delay.h> #define setbit(port,bit) port=port|(1<<bit) #define clearbit(port,bit) port=port&(~(1<<bit)) int main() { DDRB = 0xFF; PORTB = 0xFF; while(1) { clearbit(PORTB,4); _delay_ms(1000); setbit(PORTB,4); _delay_ms(1000); } } / /Clear bit 4 of Port B ; Switch on the LED //Time delay of 1000 milli seconds //Set bit 4 of Port B; Switch off the LED //Configure Port B as output //Switch off all LEDs
PROGRAM 4
Controlling LEDs through switches ( The program identifies the switch which has been pressed and switches on the corresponding LED ) #include<avr/io.h> int main() { DDRB = 0xFF; DDRC = 0x00; PORTC = 0xFF; PORTB = 0xFF; while(1) PORTB = PINC; }
//making PORTB output // making PORTC input // activate internal pull -ups // all LEDs switched off initially
PROGRAM 5
Serial communication (The program receives a character from a PC and transmits back the character next in line to the received one.) #include<avr/io.h> #include<util/delay.h> void uart_init() { UBRRL = 51; UBRRH = 0; UCSRB = 0x18; UCSRC = 0x86; } unsigned char rx_char() { while((UCSRA & 0x80)==0); return UDR; } void tx_char(unsigned char tx) { while((UCSRA & 0x20)==0); UDR = tx; } int main() { DDRB = 0x00; PORTB = 0xFF; uart_init(); while(1) { switch(PINB) { case 0xFE:tx_char('1');break; case 0xFD:tx_char('2');break; case 0xFB:tx_char('3');break; case 0xF7:tx_char('4');break; case 0xEF:tx_char('5');break; case 0xDF:tx_char('6');break; case 0xBF:tx_char('7');break; case 0x7F:tx_char('8');break; } _delay_ms(2000); } }
PROGRAM 6
LCD (The program displays character A on the LCD.) #include<avr/io.h> #include<util/delay.h> #define setbit(PORT,BIT) PORT = PORT|(1<<BIT) #define clearbit(PORT,BIT) PORT = PORT&(~(1<<BIT)) void lcdcmd(unsigned char cmd) { PORTB = cmd; clearbit(PORTC,5); //RS low clearbit(PORTC,6); //RW low setbit(PORTC,7); //Enable high _delay_ms(100); clearbit(PORTC,7); //Enable low _delay_ms(100); } void lcddata(unsigned char data) { PORTB = data; setbit(PORTC,5); //RS high clearbit(PORTC,6); setbit(PORTC,7); _delay_ms(100); clearbit(PORTC,7); _delay_ms(100); } void lcdinit() { lcdcmd(0x38); //Function set:8 bit, 2 line, font size 5x7 lcdcmd(0x0E); //Display on, Cursor on as an underscore lcdcmd(0x06); //Cursor to be post incremented after any write data or read data operation lcdcmd(0x01); //Clear display lcdcmd(0x80); //Address set for display data RAM access } int main() { DDRB = 0xFF; //port B o/p DDRC = 0xFF; //port c o/p lcdinit(); lcddata('A'); }
PROGRAM 7
4 bit LCD (The program operates the LCD in 4 -bit mode.) #include<avr/io.h> #include<util/delay.h> #define set(PORT,BIT) PORT = PORT|(1<<BIT) #define clr(PORT,BIT) PORT = PORT&(~(1<<BIT)) void lcdcmd(unsigned char cmd) { PORTC = cmd&0xF0; clr(PORTC,2); set(PORTC,3); _delay_ms(100); clr(PORTC,3); _delay_ms(100); PORTC = ((cmd&0x0F)<<4); clr(PORTC,2); set(PORTC,3); _delay_ms(100); clr(PORTC,3); _delay_ms(100); } void lcddata(unsigned char data) { PORTC = data&0xF0; set(PORTC,2); set(PORTC,3); _delay_ms(100); clr(PORTC,3); _delay_ms(100); PORTC = ((data&0x0F)<<4); set(PORTC,2); set(PORTC,3); _delay_ms(100); clr(PORTC,3); _delay_ms(100); } void lcd_init() { lcdcmd(0x03); lcdcmd(0x03);
lcdcmd(0x03); lcdcmd(0x02); lcdcmd(0x28); lcdcmd(0x08); lcdcmd(0x01); lcdcmd(0x0F); } int main() { DDRC = 0xFF; lcd_init(); lcddata('A'); }
PROGRAM 8
LCD & UART (The program receives data from a PC and displays it on the LCD.) #include<avr/io.h> #include<util/delay.h> #define set(PORT,BIT) PORT = PORT | (1<<BIT) #define clr(PORT,BIT) PORT = PORT & (~(1<<BIT)) void uart_init() { UBRRL = 51; //baud rate 9600 for 8 MHz freq. UBRRH = 0; UCSRB = 0x18;//rx or tx enable UCSRC = 0x86;//length of chracter:8 bits } unsigned char rx_char() { while((UCSRA & 0x80) == 0); //Do nothing while true return UDR; } void lcdcmd(unsigned char cmd) { PORTB = cmd; clr(PORTC,5); //RS low
clr(PORTC,6); //RW low set(PORTC,7); //Enable high _delay_ms(100); clr(PORTC,7); //E nable low _delay_ms(100); } void lcddata(unsigned char data) { PORTB = data; set(PORTC,5); clr(PORTC,6); set(PORTC,7); _delay_ms(100); clr(PORTC,7); _delay_ms(100); } void lcd_init() { lcdcmd(0x38); //Function set:8 bit, 2 line, font size 5x7 lcdcmd(0x0E); //Display on, Cursor on as an underscore lcdcmd(0x06); //Cursor to be post incremented after any write data or read data operation lcdcmd(0x01); //Clear display lcdcmd(0x80); //Address set for display data RAM access } int main() { unsigned char data; DDRB = 0xFF; //port B o/p DDRC = 0xFF; //port C o/p uart_init(); lcd_init(); while(1) { data = rx_char(); lcddata(data); } } //RS high //RW low //Enable high //Enable low
PROGRAM 9
Analog to digital converter. (The program senses the analog input and displays the digital output on PC scree n through UART.) /***************************************************************************************************************** Control lines: Port A Data lines: Port B CS = PA0 RD = PA1 RW = PA2 *****************************************************************************************************************/ #include<avr/io.h> #include<util/delay.h> #define set(PORT,BIT) PORT = PORT|(1<<BIT) #define clr(PORT,BIT) PORT = PORT&(~(1<<BIT)) void uart_init() { UBRRL = 51; UBRRH = 0; UCSRB = 0x18; UCSRC = 0x86; } void tx_char(unsigned char tx) { while((UCSRA & 0x20)==0); UDR = tx; } void conv(unsigned char data) { unsigned char d1,d2,d3,d4,d5; d1 = (data/100)+48; d2 = ((data%100)/10)+48; d3 = (data%10)+48; tx_char(d1); tx_char(d2); tx_char(d3); tx_char(32); //Conversion to ASCII values
d4 = (data/51)+48; d5 = (((data%51)*10)/51)+48; tx_char(d4); tx_char('.'); tx_char(d5); tx_char('V'); tx_char(13); tx_char(10); } int main() { unsigned char adcdata; DDRA = 0xFF; DDRB = 0x00; PORTB = 0xFF; uart_init(); clr(PORTA,0); while(1) { clr(PORTA,2); _delay_ms(100); set(PORTA,2); _delay_ms(100); clr(PORTA,1); _delay_ms(100); adcdata = PINB; set(PORTA,1); conv(adcdata); _delay_ms(100); } } //Port A i/p //Port B o/p
PROGRAM 10
Digital to analog converter. /************************************************** Data lines: Port B DAC o/p: PA1 ***************************************************/ #include<avr/io.h> #include<util/delay.h> void uart_init() { UBRRL = 51; UBRRH = 0; UCSRB = 0x18; UCSRC = 0x86; } unsigned char rxchar() { while((UCSRA & 0x20)==0); return UDR; } void txchar(unsigned char tx) { while((UCSRA & 0x80)==0); UDR = tx; } int main() { unsigned char temp,temp1,temp2; DDRA = 0xFF; DDRB = 0xFF; uart_init(); temp1 = rxchar(); txchar(46); temp2 = rxchar(); temp1 = temp1*51; temp2 = temp2*5; temp = temp1+temp2; PORTB = temp; _delay_ms(100); }
PROGRAM 11
Motor operation. #include<avr/io.h> #include<util/delay.h> #define set(PORT,BIT) PORT = PORT|(1<<BIT) #define clr(PORT,BIT) PORT = PORT&(~(1<<BIT)) int main() { DDRB = 0xFF; while(1) { PORTB = 0x0A; _delay_ms(5000); PORTB = 0x02; _delay_ms(5000); PORTB = 0x08; _delay_ms(5000); PORTB = 0x05; _delay_ms(5000); } }
PROGRAM 12
Wall following ROBOT. /***************************** left sensor: PA0 front sensor: PA4 ******************************/ #include<avr/io.h> #include<util/delay.h> int main() { DDRA = 0x00; //Port A i/p DDRB = 0xFF; //Port B 0/p PORTA = 0xFF; //Activate internal pullups PORTB = 0xA0; //Forward _delay_ms(2000); while(1) { switch(PINA) { case 0xFE: PORTB = 0xA0;break; //Left sensor detecting, move forward case 0xFF: PORTB = 0x80;break; //None of the sensors detecting, turn left case 0xEE: PORTB = 0x20;break; //Both sensors detecting, turn right } } }
PROGRAM 13
Matrix keypad (The program identifies the key pressed and displays it on the LCD.) /***************************************************************************************************************** Port B:Rows Port C:Columns Port A:LCD data lines Port D:LCD control lines RS:PD0 RW:PD1 EN:PD2 *****************************************************************************************************************/ #include<avr/io.h> #include<util/delay.h> #define set(PORT,BIT) PORT = PORT|(1<<BIT) #define clr(PORT,BIT) PORT = PORT&(~(1<<BIT)) void lcdcmd(unsigned char cmd) { PORTA = cmd; clr(PORTD,5); clr(PORTD,6); set(PORTD,7); _delay_ms(100); clr(PORTD,7); _delay_ms(100); } void lcddata(unsigned char data) { PORTA = data; set(PORTD,5); clr(PORTD,6); set(PORTD,7); _delay_ms(100); clr(PORTD,7); _delay_ms(100); } void lcdinit() { lcdcmd(0x38); lcdcmd(0x0E); lcdcmd(0x06); lcdcmd(0x01); lcdcmd(0x80); }
unsigned char keypad() { while(1) { PORTB = 0xFE; if(PINC!= 0xFF) _delay_ms(1000); switch(PINC) { case 0xEF:return '7';break; case 0xDF:return '8';break; case 0xBF:return '9';break; case 0x7F:return 'A';break; } PORTB = 0xFD; if(PINC!= 0xFF) _delay_ms(1000); switch(PINC) { case 0xEF:return '4';break; case 0xDF:return '5';break; case 0xBF:return '6';break; case 0x7F:return 'B';break; } PORTB = 0xFB; if(PINC!= 0xFF) _delay_ms(1000); switch(PINC) { case 0xEF:return '1';break; case 0xDF:return '2';break; case 0xBF:return '3';break; case 0x7F:return 'C';break; } PORTB = 0xF7; if(PINC!= 0xFF) _delay_ms(1000); switch(PINC) { case 0xEF:return 'X ';break; case 0xDF:return 'Y';break; case 0xBF:return 'Z';break; case 0x7F:return '#';break; } } }
int main() { DDRB = 0xFF; DDRC = 0x00; PORTC = 0xFF; DDRD = 0xFF; DDRA = 0xFF; lcdinit(); while(1) { lcddata(keypad()); } }
PROGRAM 14
Calculator (Using keypad and LCD) /***************************************************************************************************************** Port B:Rows Port C:Columns Port A:LCD data lines Port D:LCD control lines RS:PD5 RW:PD6 EN:PD7 *****************************************************************************************************************/ #include<avr/io.h> #include<util/delay.h> #define set(PORT,BIT) PORT = PORT|(1<<BIT) #define clr(PORT,BIT) PORT = PORT&(~(1<<BIT)) void lcdcmd(unsigned char cmd) { PORTA = cmd; clr(PORTD,5); clr(PORTD,6); set(PORTD,7); _delay_ms(100); clr(PORTD,7); _delay_ms(100); } void lcddata(unsigned char data) { PORTA = data; set(PORTD,5); clr(PORTD,6); set(PORTD,7); _delay_ms(100); clr(PORTD,7); _delay_ms(100); } void lcdinit() { lcdcmd(0x38); lcdcmd(0x0E); lcdcmd(0x06); lcdcmd(0x01); lcdcmd(0x80); }
unsigned char keypad() { while(1) { PORTB = 0xFE; if(PINC!= 0xFF) _delay_ms(1000); switch(PINC) { case 0xEF:return '7';break; case 0xDF:return '8';break; case 0xBF:return '9';break; case 0x7F:return '+';break; } PORTB = 0xFD; if(PINC!= 0xFF) _delay_ms(1000); switch(PINC) { case 0xEF:return '4';break; case 0xDF:return '5';break; case 0xBF:return '6';break; case 0x7F:return '-';break; } PORTB = 0xFB; if(PINC!= 0xFF) _delay_ ms(1000); switch(PINC) { case 0xEF:return '1';break; case 0xDF:return '2';break; case 0xBF:return '3';break; case 0x7F:return '*';break; } PORTB = 0xF7; if(PINC!= 0xFF) _delay_ms(1000); switch(PINC) { case 0xEF:return 'X';break; case 0xDF:return '0';break; case 0xBF:return '#';break; case 0x7F:return '/';break; } } }
int main() { int op1,op2,op3,s1,sum =0,result=0; unsigned char d1,d2,d3,d4,temp=0; DDRB = 0xFF; DDRC = 0x00; PORTC = 0xFF; DDRD = 0xFF; DDRA = 0xFF; lcdinit(); while(1) { while(1) { temp = keypad(); if(temp == '#') break; lcddata(temp); s1 = temp-48; sum = (sum*10)+s1; } op1 = sum; op2 = keypad(); lcddata(op2); temp = 0; sum = 0; while(1) { temp = keypad(); if(temp == '#') break; lcddata(temp); s1 = temp-48; sum = (sum*10)+s1; } op3 = sum; switch(op2) { case '+':result = op1+op3;break; case '-':result = op1-op3;break; case '*':result = op1*op3;break; case '/':result= op1/op3;break; }
PROGRAM 15
Using interrupts and timer. #include<avr/io.h> #include<avr/interrupt.h> int count; void timer_init() { TCCR0 = TCCR0|((1<<CS02)|(1<<CS00)); TIMSK = TIMSK|(1<<TOIE0); TCNT0 = 0; } ISR(TIMER0_OVF_vect) { count++; if(count==33) { PORTB = ~PORTB; count = 0; } } int main() { unsigned char data; UBRRL = 51; UBRRH =0; UCSRB = 0x18; UCSRC = 0x86; DDRB = 0xFF; PORTB = 0x55; count = 0; timer_init(); sei(); while(1) { while(!(UCSRA & 0x80)); data = UDR; while(!(UCSRA & 0x20)); UDR = data +1; } }
//set prescaler value to 1024 //enable overflow interrupt enable //initialise counter
PROGRAM 16
Using interrupts. #include<avr/io.h> #include<avr/interrupt.h> #include<util/delay.h> void uart_init() { UBRRL = 51; UBRRH = 0; UCSRB = 0x98; UCSRC = 0x86; } ISR(UART_RX_vect) { unsigned char data; data = UDR; UDR = data+1; } int main() { DDRB = 0xFF; PORTB = 0x55; uart_init(); sei(); while(1) { _delay_ms(1000); PORTB = 0xAA; _delay_ms(1000); PORTB = 0x55; } }
PROGRAM 17
External interrupts . #include<avr/io.h> #include<avr/interrupt.h> #include<util/delay.h> void interrupt_en() { MCUCR = MCUCR|(1<<ISC01); GICR = GICR|(1<<INT0); } ISR(INT0_vect) { PORTB = ~PORTB; } int main() { unsigned char data; DDRB = 0xFF; DDRD = 0x00; PORTD = 0xFF; PORTB = 0x55; interrupt_en(); sei(); while(1); }