In this project the light on the LCD makes a LED light brighter or dimmer, while the program makes use of a software PWM.

/*
program name: M328 led pwm
date: 11-04-2015
author: www.avrprojects.net
version: 1.0
purpose: reads the value of an LDR and adjust a leds brightness depending on the amount of light on the LDR
target device: M328
*/

#include <avr/io.h>
#include <util/delay.h>
#include <avr/interrupt.h>

#define F_CPU 16000000UL

// globals
unsigned char adc_data,level;
volatile unsigned char e ;
volatile unsigned char pwm;

void abc(unsigned char a,unsigned char status)
{
if ((status==a))
{
PORTB&= ~(1<<0);
}
}


//overflow isr timer0
ISR(TIMER0_OVF_vect)
{
if (e==255)
{e=0;
PORTB |= (1<<0);
}

abc(pwm,e);
e++;
}

// this function read the value of ADC channel 0
unsigned char read_adc(void)
{
ADCSRA |= 1<<ADSC; //start conversion;
while (ADCSRA&(1<<ADSC)); //wait conversion end
return ADCH;
}


// main program
int main (void)
{
//Timer Initialisation
TCCR0A = 0x00;
TCCR0B = 0x01;//No Prescaling
TIMSK0=0x01;// unmask Timer 0 overflow interrupt
sei();//Global Interrupts Enabled

//adc init
ADMUX = 0b00100000; // set ADC0
ADCSRA = 0b10000111; //set ADEN, precale by 128
DDRB = 0xFF; //portb for output

while(1)
{
adc_data = read_adc();
level = adc_data;
if (level <(1*255)/5) {
pwm = 255;
} else {if (level <(2*255)/5) {
pwm = 200;
} else {if (level <(3*255)/5) {
pwm = 150;
} else {if (level <(4*255)/5) {
pwm = 100;
} else {if (level <(5*255)/5) {
pwm = 0;
} else {pwm = 0;
}
}
}
}
}
_delay_ms(100);
pwm = 0;
} // end while

} //END MAIN

 

Video

LDRLED from avrprojects.net on Vimeo.