Hello all,
I am trying to set up a program that takes in an input from an ADC (potentiometer) and output it to an LED via PWM. I am doing this using the ATmega16 microcontroller. Also, I have set it up so that if switch 0 is pressed the output from the PWM is taken directly from the ADC. If switch 1 is pressed the output from the PWM is the full voltage if the ADC is greater than 128. I have gotten the ADC and PWM to work together with the LED, but when introducing the if statements for switch 0 and 1 it stops working.
If anyone could help me that would be great.
The code is below:
#include <avr/io.h>
#include <avr/interrupt.h>
#define F_CPU 3686400
#include <util/delay.h>
// Function Prototypes
void PWM_init(void);
void ADC_init(void);
void start_convert(void);
// Global variables
volatile unsigned char dim;
int main(void)
{
// initialize IO port, interrupt and PWM
// Set Port B as output port for the LEDs
DDRB = 0xFF;
PORTB = 0xFF;
// Set Port A as input ADC
DDRA = 0x00;
PORTA = 0xFF;
// Set Port C as switch input
DDRC = 0x00;
PORTC = 0xFF;
// enable global variable
sei();
// Initialize PWM
PWM_init();
// Initialize PWM
ADC_init();
while (1)
{
// keep looping the conversion process
start_convert();
// so the human eye can track bit changes
_delay_ms(40);
}
return 0;
}
// PWM Interrupt Service Routine
ISR(TIMER1_OVF_vect)
{
// If switch 0 is pressed then output through PWNM
if(PINC=0xFE)
{
// Update the register by the binary value presented
// at Port A
OCR1A = dim;
}
if(PINC=0xFE)
{
if(~ADCH > 128)
{
OCR1A = 0xFF;
}
}
}
// ADC Interrupt Service Routine
ISR(ADC_vect)
{
// Read from ADC data register (MSB)
dim = ~ADCH;
}
// Inialization of PWM
void PWM_init(void)
{
// Initialize OCIA as output port
DDRD |= (1 << PD5);
// Initialize Timer/Counter 1 overflow interrupt
TIMSK |= (1 << TOIE1);
// Program COM1A so that OCIA is set at TOP
TCCR1A |= (1 << COM1A1);
// Program WGM to Phase-correct, 8-bit mode
TCCR1A |= (1 << WGM10);
// Set Timer/Counter 1 prescalar to Clk/1
TCCR1B |= (1 << CS10);
}
// Inialization of ADC
void ADC_init(void)
{
// Enable ADC and ADC interrupt
ADCSRA |= 0x88; // or ADCSRA |= (1<<ADEN)|(1<<ADIE)
// Select ADC0 as single-ended analog input
ADMUX |= 0xE0; // Set lower 5 bits to 0
// Select the 2.56V internal voltage reference with external capacitor
// at the AREF pin
ADMUX |= (3<<REFS0);
// Left adjusted register (ADLAR = 1)
ADMUX |= (1<<ADLAR);
}
// Start conversion
void start_convert(void)
{
// Start Conversion
ADCSRA |= (1 << ADSC) | (1 << ADIE);
}
I am trying to set up a program that takes in an input from an ADC (potentiometer) and output it to an LED via PWM. I am doing this using the ATmega16 microcontroller. Also, I have set it up so that if switch 0 is pressed the output from the PWM is taken directly from the ADC. If switch 1 is pressed the output from the PWM is the full voltage if the ADC is greater than 128. I have gotten the ADC and PWM to work together with the LED, but when introducing the if statements for switch 0 and 1 it stops working.
If anyone could help me that would be great.
The code is below:
#include <avr/io.h>
#include <avr/interrupt.h>
#define F_CPU 3686400
#include <util/delay.h>
// Function Prototypes
void PWM_init(void);
void ADC_init(void);
void start_convert(void);
// Global variables
volatile unsigned char dim;
int main(void)
{
// initialize IO port, interrupt and PWM
// Set Port B as output port for the LEDs
DDRB = 0xFF;
PORTB = 0xFF;
// Set Port A as input ADC
DDRA = 0x00;
PORTA = 0xFF;
// Set Port C as switch input
DDRC = 0x00;
PORTC = 0xFF;
// enable global variable
sei();
// Initialize PWM
PWM_init();
// Initialize PWM
ADC_init();
while (1)
{
// keep looping the conversion process
start_convert();
// so the human eye can track bit changes
_delay_ms(40);
}
return 0;
}
// PWM Interrupt Service Routine
ISR(TIMER1_OVF_vect)
{
// If switch 0 is pressed then output through PWNM
if(PINC=0xFE)
{
// Update the register by the binary value presented
// at Port A
OCR1A = dim;
}
if(PINC=0xFE)
{
if(~ADCH > 128)
{
OCR1A = 0xFF;
}
}
}
// ADC Interrupt Service Routine
ISR(ADC_vect)
{
// Read from ADC data register (MSB)
dim = ~ADCH;
}
// Inialization of PWM
void PWM_init(void)
{
// Initialize OCIA as output port
DDRD |= (1 << PD5);
// Initialize Timer/Counter 1 overflow interrupt
TIMSK |= (1 << TOIE1);
// Program COM1A so that OCIA is set at TOP
TCCR1A |= (1 << COM1A1);
// Program WGM to Phase-correct, 8-bit mode
TCCR1A |= (1 << WGM10);
// Set Timer/Counter 1 prescalar to Clk/1
TCCR1B |= (1 << CS10);
}
// Inialization of ADC
void ADC_init(void)
{
// Enable ADC and ADC interrupt
ADCSRA |= 0x88; // or ADCSRA |= (1<<ADEN)|(1<<ADIE)
// Select ADC0 as single-ended analog input
ADMUX |= 0xE0; // Set lower 5 bits to 0
// Select the 2.56V internal voltage reference with external capacitor
// at the AREF pin
ADMUX |= (3<<REFS0);
// Left adjusted register (ADLAR = 1)
ADMUX |= (1<<ADLAR);
}
// Start conversion
void start_convert(void)
{
// Start Conversion
ADCSRA |= (1 << ADSC) | (1 << ADIE);
}