Professional Documents
Culture Documents
Manual
Muhammad Aqeel Arshad 12-Jan-12
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
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.
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.
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
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
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.
// PORTA is as Input 0000_0000 // enable internal pull on PORTA , all pins pulled up. // infinite loop
// to check if sw4 on pinA register //turn on the lower four bis //delay 100 mille sec.
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
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.
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
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.
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.
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 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.
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.
UMT
AVR-Microcontroller Workshop
SST
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
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
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;
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:
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