Professional Documents
Culture Documents
Experiment setup:
Which Registers you had used and Value of each register with short
explanation why you had set that value.
(this can be done as
comment in the source code)
Results
Problems you had faced in experiment and how you solved them.
(mail this report in pdf format to prabhat_ranjan@da-iict.org with subject line :
[ESP]{LABx] Group lm . Here replace x with the lab number nd lm with your group
number. Subject heading for lab 3 for group A would be [ESP]{LAB3] Group A. Keep
cases accurate otherwise my mail handler will not handle it correctly)
Task 1: Generate Pulse from Atmega32 using PWM
Concept:
PWM or Pulse Width Modulation refers to the concept of rapidly pulsing the
digital signal of a wire to simulate a varying voltage on the wire. This method is
commonly used for driving motors, heaters, or lights in varying intensities or speeds.
A few terms are associated with PWM:
Period: how long each complete pulse cycle takes
Frequency:how often the pulses are generated. This value is typically specified in
Hz (cycles per second).
Duty Cycle:refers to the amount of time in the period that the pulse is active or
high. Duty Cycle is typically specified as a percentage of the full period.
ATmega32 has three Timer/Counters- Timer 0, Timer 1, Timer 2. Out of these Timer 0
and Timer 2 are 8-bit timers and Timer 1 is a 16 bit timer. This means that it counts from
$0000 to $FFFF (0 65535). Timer 1 has a PWM mode that allows us to generate free
running Pulse Width Modulated signals on pins PD4 and PD5. Timer 1 can act as either 8bit/9-bit/10-bit Counter. Which one we want to use can be set by setting the lowest two bits
of the register TCCR1A.
PWM11 ( bit 1 )
PWM10 ( bit 0 )
Description
PWM disabled
8-bit PWM
9-bit PWM
1
Table 1: ATmega32 PWM Mode
10-bit PWM
The counter counts up to the maximum value and then starts counting down to 0 (see the
illustration below). When the value of the counter matches that in the compare register, it
affects PD4 and PD5. The behavior of the counter when it matches the value is decided by
setting the 7th (COM1A1) and 6th (COM1A0) bit in case of PD4 and 5th (COMR1B1) and
4th (COM1B0) bit in case of PD5.
COM1X1
COM1X0
Effect on OC1X
None
None
The bits 0-2 of the Register TCCR1B sets the pre-scaling source of Timer 1 as derived
from the system clock frequency.
Bit2
Bit1
Bit0
Description
0
T/C 1Stopped
CK
CK/8
CK/64
CK/256
CK/1024
1
1
Clocked by pin T1, rising edge
Table 3: Pre scaling source of Timer 1
Fig 1
[1] A working program for PWM is given in the assignment file. You have to connect
circuit given bellow and note down the experiment results.
5V
Input form
Microcontreoller
220
In4148
Fig 2
[2] Change the Duty cycle and see the effect of it on speed of motor.
the micro-controller. This sensor played a major role in ascending the light gradient.
LDRs or Light Dependent Resistors are very useful especially in light/dark sensor circuits.
Normally the resistance of an LDR is very high, sometimes as high as 1000 000 ohms, but
when they are illuminated with light resistance drops dramatically.
Fig 3
The animation opposite shows that when the torch is turned on, the resistance of the LDR
falls, allowing current to pass through it.
Circuit to connect LDR to Micro-Controller is given below.
Conversion to the byte output of ADC channels can be done by utilizing formula:
Byte = voltage*255/5.0
(where AVCC is assumed to be 5.0 V and ADC output is 8-bit)
[1] program for ADC is given in assignment, your job is to run this program, and display
the ADC value on LEDs
Fig 4
[2] Using UART programming transfer ADC reading of micro-controller to Linux system.
TASK 3: Mini project to control motor speed base on light intensity
In this mini project you will read light intensity using ADC and LDR, base on this light
intensity you will change the speed of motor by changing duty cycle with help of PWM.
ADC will give you reading in Byte ( Max 255), for simplicity divide this ADC data into
three level and for each level select different duty cycle, base on which change the speed
of motor.
For Example :
ADC value =
0 to 75
select duty cycle 50%,
75 to 150 select duty cycle 75%,
150
select duty cycle 100%
ProgramForSerialPortCommunication
#include<avr/io.h>
#include<avr/signal.h>
#include<avr/interrupt.h>
#include<inttypes.h>
#defineXTAL4000000
#defineBAUD9600
intUart_putchar(unsignedcharcharacter)
{
loop_until_bit_is_set(UCSRA,UDRE);
UDR=character;
return0;
}
SIGNAL(SIG_UART_RECV)
{
unsignedcharcharacter;
unsignedchardummy;
character=UDR;
PORTB=~character;
Uart_putchar(character);
while(UCSRA&(1<<RXC))dummy=UDR;
}
voidInit_USART(void)
{
//USARTMode:Asynchronous
UBRRH=0x00;//writehighbytefirst
UBRRL=((XTAL/16)/BAUD)1;//baudrate9600
UCSRA=0x00;
UCSRB|=(1<<3);//TXENON,TXON,xxxx1xxx
UCSRB|=(1<<4);//RXEN,RXON,xxx11xxx
UCSRB|=(1<<7);//RXIE,RXinterruptON,1xx11xxx
UCSRC=0x86;//8Data,1Stop,NoParity1xxxx11x
SREG=(1<<7);//globalinterruptON1xxxxxxx
}
intmain(void)
{
inti,j;
unsignedinta;
DDRB=0xFF;
PORTB=0x00;
Init_USART();
sei();
while(1);
return0;
}
ProgramToControlMotorWithPWM
#include<inttypes.h>
#include<avr/io.h>
#include<avr/interrupt.h>
#include<avr/signal.h>
#definekPinInitCompleteLEDPA0
#definekDelay10000
#definekReverseDelay300000
#definekLowerLimit500
#definekUpperLimit5000
#definelight_low
500
#definelight_mediam1000
#definelight_high3000
intmain()
{
volatilelongd;
shortdir=1;
//SetLEDoutputpins
DDRA=_BV(kPinInitCompleteLED);
DDRB=0;//PortBinputs
//SetupOCRpins(PD4,PD5)asoutputs(00110000)
DDRD=_BV(PD4)|_BV(PD5);
//SetupTimer1.Timer1shouldresetwhen
//itreachesTOP=ICR1(WGM13:0=1110b).On
//comparematchclearoutput,atTOPset(COM1A1:0=10b).
TCCR1A=_BV(COM1A1)|_BV(COM1A0)//BothPWMoutputssetatTOP,
|_BV(COM1B1)|!_BV(COM1B0)//clearoncomparematch
|!_BV(FOC1A)|!_BV(FOC1B)//PWMmode,can'tforceoutput
|_BV(WGM11)|!_BV(WGM10);//FastPWM,TOP=ICR1
TCCR1B=!_BV(ICNC1)|!_BV(ICES1)//Disableinputcapturenoisecanceler,
//edgeselecttonegative.
|_BV(WGM13)|_BV(WGM12)//FastPWM,TOP=ICR1
|!_BV(CS12)|_BV(CS11)|_BV(CS10);//clk(i/o)/1024
//PWMdutycycle
OCR1A=kLowerLimit;
OCR1B=kLowerLimit;
//PWMperiod
ICR1=12500;
//Showinitializationcomplete
PORTA=_BV(kPinInitCompleteLED);
//Loopforeversteeringlefttorighttoleft
OCR1A=kLowerLimit;
while(1)
{
d=kDelay;
while(d);
OCR1A+=dir;
if(OCR1A<kLowerLimit)
{
OCR1A=kLowerLimit;
dir=1;
d=kReverseDelay;
while(d);
}
if(OCR1A>kUpperLimit)
{
OCR1A=kUpperLimit;
dir=1;
d=kReverseDelay;
while(d);
}
}
return0;
}
ProgramFORADC
#include<avr/interrupt.h>
#include<avr/signal.h>
#include<avr/delay.h>
#include<inttypes.h>
#include<avr/io.h>
#include<inttypes.h>//uint8_t==unsignedchar
#defineXTAL4000000
#defineBAUD9600
uint8_tlo_val,hi_val;
uint8_tDEBUG=0;
#defineTHRESHOLD_VALUE240
#defineTOL3
#defineDETECT_STEPS72
#defineCW0
#defineCCW1
#defineCW_OUT0x09
#defineCCW_OUT0x06
#defineCH1
SIGNAL(SIG_ADC)
{
lo_val=inp(ADCL);
hi_val=inp(ADCH);
}
voidInit_USART(void);
intmain(void)
{
DDRB=0xFF;
DDRA=0x00;
outp(0x00,PORTB);
Init_USART();
readadc(CH);
while(1)
{
readadc(CH);
delay(100);
PORTB=hi_val;
outp(0x00,ADCSRA);
}
}
uint8_treadadc(uint8_tch)
{
ADMUX=0x20|0x01;//ch;
outp((1<<ADEN)|(1<<ADSC)|(1<<ADIE)|1,ADCSRA);
sei();
while(bit_is_set(ADCSRA,ADSC));
returnhi_val;
}