0% found this document useful (0 votes)
39 views6 pages

Solution of ES Sheet - 5

The document provides a micro-C program for controlling the speed of a DC motor using PWM signals on an ATMega16 microcontroller. It includes code for reading motor speed from an optical shaft encoder, calculating the required duty cycle, and adjusting the PWM signal to maintain a constant speed of 100 RPM. The program also features interrupt service routines for handling timer events and ensuring accurate speed control.

Uploaded by

david1milad1982
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
39 views6 pages

Solution of ES Sheet - 5

The document provides a micro-C program for controlling the speed of a DC motor using PWM signals on an ATMega16 microcontroller. It includes code for reading motor speed from an optical shaft encoder, calculating the required duty cycle, and adjusting the PWM signal to maintain a constant speed of 100 RPM. The program also features interrupt service routines for handling timer events and ensuring accurate speed control.

Uploaded by

david1milad1982
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 6

ES Sheet - 5

Tuesday, December 3, 2024 10:47 AM


void main() {
unsigned int digital_reading;
unsigned short speed, required_speed = 100;
short delta_speed;
float delta_output, output = 2.5, duty_cycle;

DDRD = 0xFF;

TCCR1A = ;
TCCR1B = ;

ICR1 = 25000;
OCR1A = 12500;

ADMUX = 0x40;
ADCSRA = 0x84;

while(1) {
ADCSRA |= (1<<ADSC);
while(ADCSRA & (1<<ADIF) == 0);
ADCSRA |= (1<<ADIF);

digital_reading = (ADCH<<8) | ADCL;


speed = digital_reading*0.19;

delta_speed = required_speed - speed;


delta_output = delta_speed / 40.0;
output += delta_output;
duty_cycle = output/5.0;

OCR1A = (1 - duty_cycle) * ICR1;


}

}
Lecture Problem: The speed of a DC motor is to be controlled using a
PWM signal. The motor is required to drive a load at a constant speed of
100 RPM. The motor speed will be monitored using an optical shaft
encoder. The motor has sensitivity of 40 RPM/V. The optical shaft encoder
gives one pulse per turn. Write a micro-C program for the ATMega16 MC to
control the speed of the motor using a PWM signal with a frequency of
about 30 Hz. Assume the MC is running at 1MHz.
Solution:

unsigned short run, speed, delta_speed, required_speed, delta_output,


output, sensitivity, duty_cycle;
unsigned int freq, start_count, end_count, delta_count, pulse_count;
unsigned long freq_timer1;

// Interrupt Service Routine for the Input Capture Interrupt Signal


void TIMER1_ICP_ISR () org 0x00A {
// As long as the timer is running increment the pulse_count and get the
start_count and end_count values from the input capture register
if (run == 1) {
if (pulse_count == 0) {
start_count = ICR1;
} else {
end_count = ICR1;
}
pulse_count++;
}
}

// Interrupt Service Routine for the Overflow Interrupt Signal


void TIMER1_OVF_ISR () org 0x010 {
// Indicate that the timer has reached over flow by setting run variable to
0
run = 0;
}

void main () {
// The next two lines of code are used to disable JTAG interface to be
able to use PORT C
MCUCSR |= 0x80;
MCUCSR |= 0x80;

// Configure Port B as O/P


DDRB = 0xFF;

// Configure Port D as I/P to receive the input square wave


DDRD = 0x00;

// Enable the Global Interrupt Flag in Status Register


SREG |= 0x80;

// Choose the Normal mode of operation and the prescaler of 64


// Make sure that the frequency of the timer is greater than 10 times of
the frequency to be measured (100rpm/60)
TCCR1A = 0x00;
TCCR1B = 0x03;

// Enable the Overflow and Input Capture Interrupt Flags


TIMSK = 0x24;

// Set the timer0 mode (PWM Phase Correct mode), its output mode
(set in up count, clear in down count) and the prescaler (64) to
generate a 30 Hz signal
TCCR0 = 0x73;
// Set the OCR0 level to be 0.5 of its maximum value to generate a signal
with 50% Duty Cycle and Average volt 2.5v
OCR0 = 128;

while (1) {
// Reset all the count variables
start_count = end_count = pulse_count = 0;
// Start the calculation process
run = 1;

// Wait until the timer reaches overflow


while (run == 1);

// Calculate the signal frequency


delta_count = end_count – start_count;
freq_timer1 = 1000000;
freq = (freq_timer1 * pulse_count) / delta_count;

// Calculate Speed in minutes


speed = freq * 60;

required_speed = 100;
delta_speed = required_speed – speed;

sensitivity = 40;
delta_output = delta_speed/sensitivity;

output += delta_output;
duty_cycle = output/5;

// Update the OCR0 level to change the duty cycle and control the
motor speed
OCR0 = (1 – duty_cycle) * 255;
}
}

You might also like