i am writing a program to dim a bulb using pwm. when the switch is turned on i want the bulb to come on(dim to bright and then stay on) and similarly when i switch off the light should dim out and stay off)
The switch is connected to portd.2 and ground. The thing is i cannot get the output to change inspite of whatever state is at portd.2. The pwm value remains constant. i have checked this on a oscilloscope.
im sure its a c code error. please advise. mcu is atmega32@1mhz
thanks Rodney
Code:
/*
* ----------------------------------------------------------------------------
* "THE BEER-WARE LICENSE" (Revision 42):
* <joerg@FreeBSD.ORG> wrote this file. As long as you retain this notice you
* can do whatever you want with this stuff. If we meet some day, and you think
* this stuff is worth it, you can buy me a beer in return. Joerg Wunsch
* ----------------------------------------------------------------------------
*
* Simple AVR demonstration. Controls a LED that can be directly
* connected from OC1/OC1A (this is PB5 on mega128) to GND. The brightness of the LED is
* controlled with the PWM. After each period of the PWM, the PWM
* value is either incremented or decremented, that's all.
*
* $Id: demo.c,v 1.6.2.3 2006/01/05 21:33:08 joerg_wunsch Exp $
*/
#include <inttypes.h>
#include <avr/io.h>
#include <avr/interrupt.h>
#include <avr/sleep.h>
char st = 0x00;// THIS IS A FLAG SO THAT PWM VALUE IS NOT REASSIGNED BEFORE BEING USED
int PWM = 0x0200;
ISR (TIMER1_OVF_vect) // timer1 overflow interrupt
{
/* on the atmega128, the clocksource for timer1 (TCCR1B) is set to use the full clock,
* in my case 16MHz. As a 10-bit timer, this interrupt should fire
* every (2^10) / 16000000 = 0.064 milliseconds (I think).
* Therefore, the LED should "ramp" from 0 to full in
* 0.064 * (2^10) = roughly 65.5 milliseconds.*/
OCR1A = PWM; //because this is an interrupt routine, it is safe to use 16-bit assignment.
st=0x00; // PWM VARIABLE CAN ACCEPT NEW VALUE
}
void ioinit (void) //initialize pwm and enable interrupts.
{
TCCR1B |= ((1 << CS10) | ( 0 <<CS11)); // full XTAL, no prescalar
TCCR1A |= ((1 << WGM10) | (1 << WGM11));
TCCR1A |= (1 << COM1A1); //Clear OC1A on compare match when up-counting, set OC1A on compare match when down-counting.
OCR1A = 0;
DDRD = _BV (PD5); //0x20
// Enable timer 1 overflow interrupt.
TIMSK = _BV (TOIE1);
//enable global interrupts
sei ();
}
int main (void)
{
DDRD |= (0<<DDD2); //prepare portD.2 for read with internal pull ups
PORTD |= (1<<PORTD2);
ioinit (); //set up pwm
// loop forever, the interrupts are doing the rest
while(1)
{
if (!(PIND & (1<<PD2))) //READ STATE ON PIND.2 CHECK FOR 0
{
if (st==0x00)
{
if (--PWM==0)
{
PWM=1;
}
st=0x01; // PREVENT PWM VARIABLE FROM CHANGING UNTILL OCR1A IS ASSINGED PWM
}
}
else
{
if (st==0x00)
{
if (++PWM==0X3FF)
{
PWM--;
}
st=0x01;
}
}
}
}
|