Microcontroller Programming C - Programmers Heaven

Howdy, Stranger!

It looks like you're new here. If you want to get involved, click one of these buttons!


Welcome to the new platform of Programmer's Heaven! We apologize for the inconvenience caused, if you visited us from a broken link of the previous version. The main reason to move to a new platform is to provide more effective and collaborative experience to you all. Please feel free to experience the new platform and use its exciting features. Contact us for any issue that you need to get clarified. We are more than happy to help you.

Microcontroller Programming C

MopinionMopinion Posts: 1Member
Hello all,
Using AVR studio 4 and ATmega16 microcontroller
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:
#define F_CPU 3686400

// Function Prototypes
void PWM_init(void);
void ADC_init(void);
void start_convert(void);

// Global variables
volatile unsigned char dim;
volatile unsigned char x;

int main(void)
// initialize IO port, interrupt and PWM
// Set Port B as output port for the LEDs
DDRB = 0xFF;
// Set Port A as input ADC
DDRA = 0x00;
// Set Port C as switch input
DDRC = 0x00;

// enable global variable
// Initialize PWM
// Initialize PWM

while (1)
// keep looping the conversion process

// so the human eye can track bit changes
// If switch 0 is pressed then output through PWNM
// Update the register by the binary value presented
// at Port A
x = dim;

if(~ADCH > 128)
x = 0xFF;
return 0;

// PWM Interrupt Service Routine
OCR1A = x;

// ADC Interrupt Service Routine
// 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);

What happens now is that when I hold down switch 0 the PWM case kicks in, but when i hold down switch 1, the LED just switches off. So two problems:
1) If statement for the second switch (switch 1) does not work.
2) I have to hold down switch 0 or 1 in order for the case to work.

Sign In or Register to comment.