You are on page 1of 31

Atmel AVR Workshop

Manual
Muhammad Aqeel Arshad 12-Jan-12

Electrical Engineering Department School of Science and Technology

This workshop is intended for students and hobbyists both. It is assumed that you know C language along with basic knowledge of digital circuits and knowledge of Microprocessor systems is a plus.

UMT

AVR-Microcontroller Workshop

SST

Preface:
An Embedded System is any electronic system that uses a computer chip, but that is not a general-purpose workstation, desktop or laptop computer. Such systems use microcontrollers (MCUs) or microprocessors (MPUs), or they may use custom-designed chips. The embedded systems market uses the lion's share of all the electronic components in the world. Embedded systems are employed in automobiles, planes, trains, space vehicles, machine tools, cameras, consumer electronics, office appliances, network appliances, video games, cellphones, PDAs, GPS navigation as well as robots and toys. Low-cost consumer products can use microcontroller chips that cost less than a few hundred Rupees. In Engineering Institutes theory about Embedded Systems is taught in courses like Microprocessor and Microcontroller Based Systems, Digital System Design, Computer Architecture and Organization but students pay little attention to the practical implementation of Embedded Systems. So they face a lot of difficulty doing their Final Year Projects, which mostly are built using microcontrollers. This workshop is intended for students and hobbyists both. It is assumed that you know C language along with basic knowledge of digital circuits and knowledge of Microprocessor systems is a plus. You will also learn the language of datasheets The PCB is built to make a starter board using Proteus software. Atmega 16 microcontroller is easily available in local market and is also low cost. Most of the times you will see different register names; dont get afraid from that just open up the data sheet of the MCU and you can get detailed understanding of that register along with functionality of each bit. Join www.avrfreaks.net and Remember Google is Your Friend. Happy Programming Muhamamd Aqeel Arshad

UMT

AVR-Microcontroller Workshop

SST

Back Ground Information Overview of the Microcontroller


High-performance, Low-power AVR 8-bit Microcontroller Advanced RISC Architecture 131 Powerful Instructions Most Single-clock Cycle Execution 32 x 8 General Purpose Working Registers High Endurance Non-volatile Memory segments 16K Bytes of In-System Self-programmable Flash program memory 512 Bytes EEPROM 1K Byte Internal SRAM JTAG (IEEE std. 1149.1 Compliant) Interface Peripheral Features Two 8-bit Timer/Counters with Separate Pre-scalers and Compare Modes One 16-bit Timer/Counter with Separate Prescaler, Compare Mode, and Capture Mode Real Time Counter with Separate Oscillator Four PWM Channels 8-channel, 10-bit ADC Byte-oriented Two-wire Serial Interface Programmable Serial USART Master/Slave SPI Serial Interface Programmable Watchdog Timer with Separate On-chip Oscillator On-chip Analog Comparator Special Microcontroller Features Power-on Reset and Programmable Brown-out Detection Internal Calibrated RC Oscillator I/O and Packages 32 Programmable I/O Lines, 40 pin DIP package Operating Voltages 4.5 - 5.5V for ATmega16 Power Consumption @ 1 MHz, 3V, and 25C for ATmega16L Active: 1.1 mA, Idle Mode: 0.35 mA, Power-down Mode: < 1 A

UMT

AVR-Microcontroller Workshop

SST

Introduction to AVR Studio: AVR Studio 5 is Integrated Development (IDE) Tool from ATMEL. It runs on MS Visual Studio, so a programmer is no longer need to remember the syntaxes. It automatically gives suggestions about the syntaxes. It supports two programming languages, assembly and C. System requirements for AVR Studio 5. Pentium 4(1 GB RAM is recommended). Windows XP with SP3 or windows 7.

Lets have a look at the features of AVR Studio before we proceed.


It is an Integrated Development Environment (IDE) for AVR Software. It allows chip simulation and in-circuit emulation. It supports the whole AVR family of Microcontrollers (MCUs). It has easy to use User Interface (UI) and gives complete overview. It uses same UI for simulation and emulation.

UMT 1. I/O Ports

AVR-Microcontroller Workshop

SST

I/O Ports are the most basic interface to the Microcontroller. The port pins are grouped using 8 bit ports. There are 4 ports in ATMEGA16, namely, PORTA, PORTB, PORTC and PORTD. Each port pin consists of three register bits: DDxn1, PORTxn, and PINxn. The DDxn bit in the DDRx Register selects the direction of this pin. If DDxn is written logic one, Pxn is configured as an output pin. If DDxn is written logic zero, Pxn is configured as an input pin. If programmed as output, The PORTxn bit sets the logical value of the port pin. If programmed as input and the PORTxn is written logic one, the pull-up resistor is activated. To switch the pull-up resistor off, PORTxn has to be written logic zero or the pin has to be configured as an output pin. The port pins are tri-stated when a reset condition becomes active, even if no clocks are running. The PINxn register is a read only register that reflects the current logical value on the port pin. The PINx register is primarily used when the port is programmed as input.

Example 1 LEDs:

UMT

AVR-Microcontroller Workshop

SST

Although connecting an LED to AVR Microcontroller is the easiest thing to do it may be a good start to connecting things to microcontroller. The Current capability of AVR Microcontroller is strong enough to drive an LED. A limiting resistor is however added to control the Light intensity. In order to instruct the Microcontroller to produce voltage level on its pin, the direction of the port pin is to be programmed as output. This is done through DDRx Register. The Reset Value of the DDRx register is such that all port pins are programmed as inputs, so we will exclusively program them as outputs. The direction setting is to be done on the first time only as during the life cycle of the program the direction of the pin will remain as output. After this a logic LOW on the pin will produce a Low Voltage Level and glow the LED and a logic HI on the pin turns LED off. The schematic of the example is given below. Port B is chosen to drive LEDs.

Programming: Structure of code - Main block - Initialize the PORTB C as OUTPUT using DDRB Register. - Turn on the LEDs by Writing 1s at the PORTB Register. - Delay to make us See the LED Glow.

UMT -

AVR-Microcontroller Workshop Turn Off by Writing 0 at the PORTB Register. Delay Go back to turn on LED Step.

SST

AVR Studio 5: 1. Open AVR studio 5. 2. On the start page goto new project or click File then New and then on Project.

3. Now select C Executable Project. 4. And in the name below write LED_blinky and Select the location where you want to save the project and press OK.

5. Select the device by writing ATMEGA16 in the upper right box and press OK.

UMT

AVR-Microcontroller Workshop

SST

6. Write down the code in the C file LED_BLINKY.C.

7. Remember to change DEBUG option to Release. Press F-7 or go-to Build and press build Solution to Generate the hex file. #include <avr/io.h> //contains all the register names and other related stuff #define F_CPU 8000000UL #include <util/delay.h> // for delay purpose int main(void) { DDRB = 0xFF; while(1) { // // // main function make all portb as output infinite loop

PORTB = 0X00; _delay_ms(1000); PORTB = 0XFF; _delay_ms(1000); } }

//All pins //delay of //All Pins //delay of

at 0 logic=0 volt 1000ms = 1sec for 1Mhz Clock of MCU at 1 logic =5VDC 1000ms = 1sec for 1Mhz Clock of MCU

8. You can also check your design by simulating this example code in Proteus software. 9. Connect your Dev-board to USB Port and make sure you have installed the drivers of it USBTINY programmer. 10. Open Sina Prog.exe and select Atmega16 in device. 11. Select USBtiny as programmer. 12. Select the hex file by clicking on the File Icon and select \Release\LED_Blinky.hex

UMT

AVR-Microcontroller Workshop

SST

13. Click on the Flash program and wait for few sec to program the MCU. 14. Connect the red jumpers to connect PORTB to LEDs. 15. Now you see a Blinking LED at 1Hz rate. 16. Try editing line #define F_CPU 4000000UL before #inlude<util/delay.h> line. 17. What change do you see? 18. DONT FORGET TO REMOVE JUMOPERS OR T WILL GIVE YOU ERROR IN BURNING IT. Exercise 2 Push Buttons:

UMT

AVR-Microcontroller Workshop

SST

Push button gives a way to give input. In the below example two push buttons are connected to control one LED. If you press 1 push button LED turn on other turn off the LED. To read the status of input, PINx register is used. And to set any Pin as input write zero in specific DDRx Pin register. Programming: Set pin 1 of Portc as output. Set pin 2 and 3 of Portc as input (by default all pins are set to input). Enable internal pull-up at pin 2 and 3. Check if Value of bit 1 in PINC Reg is 0 than turn on the LED. Else Check if Value of bit 2 in PINC Reg is 0 than turn off the LED. Go back to check bit 1.

AVR Studio 5 Code:


#include <avr/io.h> #define F_CPU 8000000UL #include <util/delay.h> int main(void) { DDRB=0XFF; DDRA = 0X00; PORTA = 0XFF; while(1) { //contains all the register names and other related stuff // for delay purpose // // main function Make all pins of Portb as output 1111_1111

// PORTA is as Input 0000_0000 // enable internal pull on PORTA , all pins pulled up. // infinite loop

if (bit_is_clear(PINA,3)) { PORTB=0b00001111; _delay_ms(100); } else { PORTB=0x00; } } }

// to check if sw4 on pinA register //turn on the lower four bis //delay 100 mille sec.

// turn off the whole portb

Remember PINx Reg contain the status on the Port. Bit_is_clear(PINA,1) function tell us if the value of pin 1 is 0 or not. Check your code by burning it on ATmega 16 and make appropriate connections. Can you make 6 LED turn On and OFF by a Switch. Or make a digital DICE.

UMT

AVR-Microcontroller Workshop

SST

Exercise 3 . Hello World on LCD


When you start working with LCD modules you will start feeling the real power of MCU and your imaginations will be touching sky you will wonder how many exciting powerful gadgets you can create and thats so very easily. LCD Modules can present textual information to user. Its like a cheap monitor that you can hook in all of your gadgets. They come in various types. The most popular one can display 2 lines of 16 characters. These can be easily interfaced to MCU's, thanks to the API (Functions used to easily access the modules) we provide. LCD interfacing is just fun!

The most common connector used for the 44780 based LCDs is 14 pins in a row, with pin centers 0.100" apart. The pins are wired as:

Pins 1 2 3 4 5 6 7 - 14

Description Ground Vcc Contrast Voltage "R/S" _Instruction/Register Select "R/W" _Read/Write LCD Registers "E" Clock Data I/O Pins

As you would probably guess from this description, the interface is a parallel bus, allowing simple and fast reading/writing of data to and from the LCD. This waveform will write an ASCII Byte out to the LCD's screen. The ASCII code to be displayed is eight bits long and is sent to the LCD either four or eight bits at a time. If four bit

UMT

AVR-Microcontroller Workshop

SST

mode is used, two "nibbles" of data (Sent high four bits and then low four bits with an "E" Clock pulse with each nibble) are sent to make up a full eight bit transfer. The "E" Clock is used to initiate the data transfer within the LCD. Sending parallel data as either four or eight bits are the two primary modes of operation. While there are secondary considerations and modes, deciding how to send the data to the LCD is most critical decision to be made for an LCD interface application. Eight bit mode is best used when speed is required in an application and at least ten I/O pins are available. Four bit mode requires a minimum of six bits. To wire a microcontroller to an LCD in four bit mode, just the top four bits (DB4-7) are written to. The "R/S" bit is used to select whether data or an instruction is being transferred between the microcontroller and the LCD. If the Bit is set, then the byte at the current LCD "Cursor" Position can be read or written. When the Bit is reset, either an instruction is being sent to the LCD or the execution status of the last instruction is read back (whether or not it has completed). The different instructions available for use with the 44780 are shown in the table below: R/S R/W D7 D6 D5 D4 D3 D2 D1 D0 Instruction/Description 4 5 14 13 12 11 10 9 8 7 Pins 0 0 0 0 0 0 0 0 0 1 Clear Display 0 0 0 0 0 0 0 0 1 * Return Cursor and LCD to Home Position 0 0 0 0 0 0 0 1 ID S Set Cursor Move Direction 0 0 0 0 0 0 1 D C B Enable Display/Cursor 0 0 0 0 0 1 SC RL * * Move Cursor/Shift Display 0 0 0 0 1 DL N F * * Set Interface Length 0 0 0 1 A A A A A A Move Cursor into CGRAM 0 0 1 A A A A A A A Move Cursor to Display 0 1 BF * * * * * * * Poll the "Busy Flag" 1 0 D D D D D D D D Write a Character to the Display at the Current Cursor Position 1 1 D D D D D D D D Read the Character on the Display at the Current Cursor Position

Thanks to already provided libraries, we will not write the above instructions instead we will include already available library. The data port is connected at PORTC while RS ,RW and EN are connected to PD4 , PD5 and PD6 respectively. In this project we will include two files mylcd.h and mylcd.c. These files contain all the function to display at LCD.

Create a new project named LCD

UMT

AVR-Microcontroller Workshop

SST

Goto Add, Existing Item... then add the both files lcd_lib.h and lcd_lib.c. Also #include lcd_lib.h in your main program LCD.c

UMT

AVR-Microcontroller Workshop

SST

AVR Studio Code:


#include <avr/io.h> #define F_CPU 8000000UL #include " lcd_lib.h" #include <util/delay.h> int main(void) { LCDinit(); _delay_ms(100); LCDclr();//clears LCD LCDstring("Hello World",11); LCDGotoXY(0,1); LCDstring("::UMT AVR SST::",15); while(1) { //TODO:: Please write your application code } }

Exercise 4. Hello World on Serial Port.


If you look at the pin details you will find that ATMega 16 has one Serial port also called USART (Universal Synchronous Asynchronous Receiver Transmitter). RX (Receive) pin is at 14 while TX (Transmitter) is at pin 15. Two types of methods are used, one is Interrupt based (Buffered) while other is polling based (nonBuffered). Before you can send or receive any data, first you need to initialize serial port as TX/RX Pins are multiplexed with PD0 and PD1 Pins. To get a better understanding about serial communication . Refer to datasheet of Atmega16.

Initialization:

UMT

AVR-Microcontroller Workshop

SST

FOCS is System Oscillator frequency. To know about these registers, just search them in data sheet and you will the answer. Here our Baud rate is 9600pbs while data is 8 bits wide with 2 stop bits.

USART TRANSMIT DATA:

UMT USART RECEIVE DATA:

AVR-Microcontroller Workshop

SST

Circuit Diagram:

No external connection is needed as all the hardware is already connected on the PCB. The initialization consists of setting up Timers and Port Registers. Serial port is initialized through 'InitUART'. The InitUART function is a very comprehensive function for UART Initialization as it takes care of different speed modes of controller, current clock frequency etc. and decide for a best possible baud rate generator register value. It takes the data bit size, parity and stop bit values through parameters and sets the USART Registers accordingly. After initialization the system continuously wait for a byte to be received from UART and then displays its Value. To get a byte from USART, UART_Receive function is called which checks the current port state and return SUCCES if a byte has been received or failure if the receive register is empty.

UMT

AVR-Microcontroller Workshop

SST

AVR Studio 5 Code. Set avr Internal clock to Int. 8Mhz from SinaProg

#include <stdint.h> #include <avr/io.h> #define F_CPU 8000000UL #include <util\delay.h> #include <avr/pgmspace.h> #include <string.h> #define USART_BAUDRATE 9600 #define BAUD_PRESCALE (((F_CPU / (USART_BAUDRATE * 16UL))) - 1) void USART_init( unsigned int baudrate ) { UBRRH = (unsigned char) (baudrate>>8); UBRRL = (unsigned char) baudrate; //Setting baudrate //Setting baudrate

UMT

AVR-Microcontroller Workshop

SST

UCSRB = ( 1 << RXEN ) | ( 1 << TXEN ); //Enable receiver and transmitter UCSRC = (1 << URSEL) | ( 1 << UCSZ1 ) | ( 1 << UCSZ0 );//8 bits 1 stop bit no parity } void USART_Transmit( unsigned char data ) { /* Wait for empty transmit buffer */ while ( !( UCSRA & (1<<UDRE)) ); /* Put data into buffer, sends the data */ UDR = data; _delay_ms(10); } unsigned char USART_Receive( void ) { /* Wait for data to be received */ while ( !(UCSRA & (1<<RXC))); /* Get and return received data from buffer */ return UDR; } void COM_puts(unsigned char *str) { for( ;*str != '\0'; ) { USART_Transmit( *str++ ); } } int main(void) { USART_init(BAUD_PRESCALE); while(1) { USART_Transmit('C'); } } Write the code for transmitting a whole string Hello world And simulate it on Proteus using Mhz crtytal settings.

Exercise 5. Analogue to Digital Conversion (ADC):


The ATmega16 features a 10-bit successive approximation ADC. The ADC is connected to an 8-channel Analog Multiplexer which allows 8 single-ended voltage inputs constructed from the pins of Port A. The single-ended voltage inputs refer to 0V (GND).

Most real world data is analog. Whether it be temperature, pressure, voltage, etc, their variation is always analog in nature. For example, the temperature inside a boiler is around 800C. During its light-up, the temperature never approaches directly to 800C. If the ambient temperature is 400C, it will start increasing gradually

UMT

AVR-Microcontroller Workshop

SST

to 450C, 500C and thus reaches 800C over a period of time. This is an analog data. Now, we must process the data that we have received. But analog signal processing is quite inefficient in terms of accuracy, speed and desired output. Hence, we convert them to digital form using an Analog to Digital Converter (ADC). Signal Acquisition Process:

In general, the signal (or data) acquisition process has 3 steps.

In the Real World, a sensor senses any physical parameter and converts into an equivalent analog electrical signal. For efficient and ease of signal processing, this analog signal is converted into a digital signal using an Analog to Digital Converter (ADC). This digital signal is then fed to the Microcontroller (MCU) and is processed accordingly.

Interfacing Sensors:

In general, sensors provide with analog output, but a MCU is a digital one. Hence we need to use ADC. For simple circuits, comparator op-amps can be used. But even this wont be required if we use a MCU. We can straightaway use the inbuilt ADC of the MCU. In ATMEGA16/32, PORTA contains the ADC pins.

Suppose we use a 5V reference. In this case, any analog value in between 0 and 5V is converted into its equivalent ADC value as shown above. The 0-5V range is divided into 2^10 = 1024 steps. Thus, a 0V input will give an ADC output of 0, 5V input will give an ADC output of 1023, whereas a 2.5V input will give an ADC output of around 512. This is the basic concept of ADC.

UMT ADC Prescaler:

AVR-Microcontroller Workshop

SST

The ADC of the AVR converts analog signal into digital signal at some regular interval. This interval is determined by the clock frequency. In general, the ADC operates within a frequency range of 50kHz to 200kHz. But the CPU clock frequency is much higher (in the order of MHz). So to achieve it, frequency division must take place. The prescaler acts as this division factor. It produces desired frequency from the external higher frequency. There are some predefined division factors 2, 4, 8, 16, 32, 64, and 128. For example, a prescaler of 64 implies F_ADC = F_CPU/64. For F_CPU = 16MHz, F_ADC = 16M/64 = 250kHz. Now, the major question is which frequency to select? Out of the 50kHz-200kHz range of frequencies, which one do we need? Well, the answer lies in your need. There is a trade-off between frequency and accuracy. Greater the frequency, lesser the accuracy and vice-versa. So, if your application is not sophisticated and doesnt require much accuracy, you could go for higher frequencies. ADC Registers: We will discuss the registers one by one. ADMUX ADC Multiplexer Selection Register The ADMUX register is as follows.

ADMUX Register The bits that are highlighted are of interest to us. In any case, we will discuss all the bits one by one.

Bits 7:6 REFS1:0 Reference Selection Bits These bits are used to choose the reference voltage. The following combinations are used.

Reference Voltage Selection

UMT

AVR-Microcontroller Workshop

SST

ADC Voltage Reference Pins

The ADC needs a reference voltage to work upon. For this we have a three pins AREF, AVCC and GND. We can supply our own reference voltage across AREF and GND. For this, choose the first option. Apart from this case, you can either connect a capacitor across AREF pin and ground it to prevent from noise, or you may choose to leave it unconnected. If you want to use the VCC (+5V), choose the second option. Or else, choose the last option for internal Vref. Lets choose the second option for Vcc = 5V.

Bit 5 ADLAR ADC Left Adjust Result Make it 1 to Left Adjust the ADC Result. We will discuss about this a bit later. Bits 4:0 MUX4:0 Analog Channel and Gain Selection Bits There are 8 ADC channels (PA0PA7). Which one do we choose? Choose any one! It doesnt matter. How to choose? You can choose it by setting these bits. Since there are 5 bits, it consists of 2^5 = 32 different conditions as follows. However, we are concerned only with the first 8 conditions. Initially, all the bits are set to zero.

ADCSRA ADC Control and Status Register A The ADCSRA register is as follows.

ADCSRA Register

UMT

AVR-Microcontroller Workshop

SST

The bits that are highlighted are of interest to us. In any case, we will discuss all the bits one by one.

Bit 7 ADEN ADC Enable As the name says, it enables the ADC feature. Unless this is enabled, ADC operations cannot take place across PORTA i.e. PORTA will behave as GPIO pins. Bit 6 ADSC ADC Start Conversion Write this to 1 before starting any conversion. This 1 is written as long as the conversion is in progress, after which it returns to zero. Normally it takes 13 ADC clock pulses for this operation. But when you call it for the first time, it takes 25 as it performs the initialization together with it. Bit 5 ADATE ADC Auto Trigger Enable Setting it to 1 enables auto-triggering of ADC. ADC is triggered automatically at every rising edge of clock pulse. View the SFIOR register for more details. Bit 4 ADIF ADC Interrupt Flag Whenever a conversion is finished and the registers are updated, this bit is set to 1 automatically. Thus, this is used to check whether the conversion is complete or not. Bit 3 ADIE ADC Interrupt Enable When this bit is set to 1, the ADC interrupt is enabled. This is used in the case of interrupt-driven ADC. Bits 2:0 ADPS2:0 ADC Prescaler Select Bits The prescaler (division factor between XTAL frequency and the ADC clock frequency) is determined by selecting the proper combination from the following.

ADC Prescaler Selections Assuming XTAL frequency of 16MHz and the frequency range of 50kHz-200kHz, we choose a prescaler of 128. Thus, F_ADC = 16M/128 = 125kHz. Thus, we initialize ADCSRA as follows.
ADCSRA = (1<<ADEN)|(1<<ADPS2)|(1<<ADPS1)|(1<<ADPS0); // prescaler = 128

UMT

AVR-Microcontroller Workshop

SST

ADCL and ADCH ADC Data Registers


The result of the ADC conversion is stored here. Since the ADC has a resolution of 10 bits, it requires 10 bits to store the result. Hence one single 8 bit register is not sufficient. We need two registers ADCL and ADCH (ADC Low byte and ADC High byte) as follows. The two can be called together as ADC.

ADC Data Registers (ADLAR = 0)

ADC Data Registers (ADLAR = 1) You can very well see the the effect of ADLAR bit (in ADMUX register). Upon setting ADLAR = 1, the conversion result is left adjusted. ADC Initialization The following code segment initializes the ADC.
void adc_init() { // AREF = AVcc ADMUX = (1<<REFS0); // ADC Enable and prescaler of 128 // 16000000/128 = 125000 ADCSRA = (1<<ADEN)|(1<<ADPS2)|(1<<ADPS1)|(1<<ADPS0); } Temperature Sensor

UMT

AVR-Microcontroller Workshop

SST

A temperature sensor is probably the most primitive sensor built. Usually they are based on Semiconductors (NTC Thermistor), Composites (PTC Thermistor), Metals (PT100), Bimetals (Thermocouple) or radiation based (pyrometeric sensors). Theses sensors differ in the range of temperature they work, price and signal conditioning required. Using LM35 : National Semiconductor has developed a chip that has the signal conditioning circuitry and the temperature sensing element on a small TO92 package. The chip gives quite accurate temperature reading for 0-100C with an accuracy of 0.5C. A 10 bit ADC is sufficient to digitize the output produced by LM34 with 0.5C accuracy.

Circuit Diagram

Connect LM35 on the DEV Board. Make sure you never connect it in the wrong polarity or it will burn

AVR studio code:


/* * USART_TX_RX.c * * Created: 25-Dec-11 4:54:52 PM * Author: aqeel * This example shows the working of serial port on AVR. * */ #include <avr/io.h>

UMT

AVR-Microcontroller Workshop

SST

#include <avr/pgmspace.h> #include <string.h> #define F_CPU 8000000UL #include <util/delay.h> #include "lcd_lib.h" #define USART_BAUDRATE 9600 #define BAUD_PRESCALE (((F_CPU / (USART_BAUDRATE * 16UL))) - 1) void USART_init( unsigned int baudrate ) { UBRRH = (unsigned char) (baudrate>>8); UBRRL = (unsigned char) baudrate; UCSRB = ( 1 << RXEN ) | ( 1 << TXEN ); transmitter UCSRC = (1 << URSEL) | ( 1 << UCSZ1 ) | ( 1 << UCSZ0 ); more information //Setting baudrate //Setting baudrate //Enable receiver and //8N1...see Data sheet for

} void USART_Transmit( unsigned char data ) { /* Wait for empty transmit buffer */ while ( !( UCSRA & (1<<UDRE)) ); /* Put data into buffer, sends the data */ UDR = data; _delay_ms(10); //the Chinees S***Y cable needs this mush delay, } unsigned char USART_Receive( void ) { /* Wait for data to be received */ while ( !(UCSRA & (1<<RXC)) ); /* Get and return received data from buffer */ return UDR; } void COM_puts(unsigned char *str) { for( ;*str != '\0'; ) { USART_Transmit( *str++ ); } } // initialize adc void adc_init() { // AREF = AVcc ADMUX = (1<<REFS0); // ADC Enable and prescaler of 128 // 8000000/128 = 62.5 Khz ADCSRA = (1<<ADEN)|(1<<ADPS2)|(1<<ADPS1)|(1<<ADPS0); }

UMT

AVR-Microcontroller Workshop

SST

// read adc value uint16_t adc_read(uint8_t ch) { // select the corresponding channel 0~7 // ANDing with '7' will always keep the value // of 'ch' between 0 and 7 ch &= 0b00000111; // AND operation with 7 ADMUX = (ADMUX & 0xF8)|ch; // clears the bottom 3 bits before ORing // start single conversion // write '1' to ADSC ADCSRA |= (1<<ADSC); // wait for conversion to complete // ADSC becomes '0' again // till then, run loop continuously while(ADCSRA & (1<<ADSC)); return (ADC); } int main(void) { float tmp=0; char temp_string[6]; char string[12]; strcpy(string,"AVR WORKSHOP"); LCDinit();//init LCD bit, dual line, cursor right LCDclr();//clears LCD USART_init(BAUD_PRESCALE); adc_init(); DDRB=0XFF; //all pins as output; while(1)//loop demos { tmp=adc_read(0); tmp=((tmp/1023)*5); // Converts into Volts at the input . tmp=(tmp/0.01); //each Degree equals to 10mv dtostrf(tmp,4,2,temp_string); LCDclr();//clears LCD LCDstring("Hello World",11); LCDGotoXY(0,1); LCDstring(temp_string,6); COM_puts(temp_string); USART_Transmit(13); //COM_puts(13); _delay_ms(1000); PORTB=0xAA; _delay_ms(500); PORTB=0x55; } return 0;

Exercise 7. PWM on AVR:


Pulse-Width Modulation (PWM) also called pulse-duration modulation (PDM) is a method of converting analog information using digital communication techniques. In PWM a train of pulses is produced. The width (duration) of

UMT

AVR-Microcontroller Workshop

SST

each individual pulse varies according to the modulating analog signal. Normally, the pulse width increases as the instantaneous modulating-signal level increases (positive modulation). However, this can be reversed so that higher signal levels cause the pulse width to decrease (negative modulation). All Timers of ATMEGA 16 has capability to produce PWM signals. The Timers of ATMEGA 16 has different PWM Modes, namely Fast PWM Mode and Phase Correct PWM Mode. These modes are discussed below Fast PWM Mode The fast Pulse Width Modulation or fast PWM mode provides a high frequency PWM waveform generation option. The fast PWM differs from the other PWM option by its single-slope operation. The counter counts from BOTTOM to MAX then restarts from BOTTOM. In non-inverting Compare Output mode, the Output Compare (OCn) is cleared on the compare match between TCNTn and OCRn, and set at BOTTOM. In inverting Compare Output mode, the output is set on compare match and cleared at BOTTOM. Due to the single- slope operation, the operating frequency of the fast PWM mode can be twice as high as the phase correct PWM mode that uses dual slope operation. This high frequency makes the fast PWM mode well suited for power regulation, rectification, and DAC applications. High frequency allows physically small sized external components (coils, capacitors), and therefore reduces total system cost. In fast PWM mode, the counter is incremented until the counter value matches the MAX value. The counter is then cleared at the following timer clock cycle. The timing diagram for the fast PWM mode is shown in Figure VII-1. The TCNTn value is in the timing diagram shown as a histogram for illustrating the single-slope operation. The diagram includes non-inverted and inverted PWM outputs. The small horizontal line marks on the TCNT0 slopes represent compare matches between OCRn and TCNTn.

Phase Correct PWM Mode: The phase correct PWM mode (WGMn1:0 = 1) provides a high resolution phase correct PWM waveform generation option. The phase correct PWM mode is based on a dual slope operation. The counter counts repeatedly from BOTTOM to MAX and then from MAX to BOTTOM. In non-inverting Compare Output mode, the Output Compare (OCn) is cleared on the compare match between TCNTn and OCRn while up counting, and set on the compare match while down counting. In inverting Output Compare mode, the operation is inverted. The dual-

UMT

AVR-Microcontroller Workshop

SST

slope operation has lower maximum operation frequency than single slope operation. However, due to the symmetric feature of the dual-slope PWM modes, these modes are preferred for motor control applications. The PWM resolution for the phase correct PWM mode is fixed to eight bits. In phase correct PWM mode the counter is incremented until the counter value matches MAX. When the counter reaches MAX, it changes the count direction. The TCNTn value will be equal to MAX for one timer clock cycle. The timing diagram for the phase correct PWM mode is shown on Figure VII-2. The TCNTn value is in the timing diagram shown as a histogram for illustrating the dual-slope operation. The diagram includes non-inverted and inverted PWM outputs. The small horizontal line marks on the TCNTn slopes represent compare matches between OCRn and TCNTn.

PWM Circuit:

AVR STUDIO 5 CODE:


/* * PWM.c * * Created: 26-Dec-11 12:29:32 AM * Author: aqeel

UMT
*/ #include <avr/io.h>

AVR-Microcontroller Workshop

SST

#include<avr/io.h> #define F_CPU 8000000UL #include<util/delay.h> #include<stdio.h> #include"my_lcd.h" void pwm_start(unsigned char PULSE_WIDTH) { OCR1AL = PULSE_WIDTH; //Load Pulse width OCR1AH = 0; TCCR1A = 0x81; //8-bit, Non-Inverted PWM TCCR1B = 1; //Start PWM } int main () { unsigned char width=0; DDRA &=~((1<<PA1)|(1<<PA2)); DDRC = 0XFF; PORTA|=(1<<PA1)|(1<<PA2); OCR1AL OCR1AH TCCR1A TCCR1B while(1) { if(bit_is_clear(PINA,PA1)) { if(width==255) width=254; //stops overflow to zero = = = = 0; 0; 0x81; 1; //Load Pulse width //8-bit, Non-Inverted PWM //Start PWM

width++; // width increases _delay_ms(100); if(width==255) width=254; } if(bit_is_clear(PINA,PA2)) { if(width==0) //stops underflow to 255 width=1; width--; _delay_ms(100); } //OCR1AL=width; pwm_start(width); PORTB=width; } return 0; }

UMT

AVR-Microcontroller Workshop

SST

THINGS TO DO. 1. 2. 3. 4. RUN BAR LED IN CHASSER MODE. DISPLAY VALUES OF LM 35 TEMP ON BAR LED. SEND ADC VALUES AT SERIAL PORT. WRITE CODE FOR SERVO MOTOR.

UMT

AVR-Microcontroller Workshop

SST

Feed Back Form


Please write down your comments about this event, so we can make it better next time. _____________________________________________________________________________________ _____________________________________________________________________________________ _____________________________________________________________________________________ _____________________________________________________________________________________ _____________________________________________________________________________________ _____________________________________________________________________________________ What difficulties you faced regarding this event? _____________________________________________________________________________________ _____________________________________________________________________________________ _____________________________________________________________________________________ _____________________________________________________________________________________ _____________________________________________________________________________________ _____________________________________________________________________________________ What things you like about this event? _____________________________________________________________________________________ _____________________________________________________________________________________ _____________________________________________________________________________________ _____________________________________________________________________________________ _____________________________________________________________________________________ _____________________________________________________________________________________

You might also like