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!

Categories

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:
-----------------------------------------------------------------------------------------------------------------------------------------
#include
#include
#define F_CPU 3686400
#include

// 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;
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);
// If switch 0 is pressed then output through PWNM
if((PINC&0x01)==0x00)
{
// Update the register by the binary value presented
// at Port A
x = dim;
}

if((PINC&0x02)==0x00)
{
if(~ADCH > 128)
{
x = 0xFF;
}
}
}
return 0;
}

// PWM Interrupt Service Routine
ISR(TIMER1_OVF_vect)
{
OCR1A = x;
}

// 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);
}

-----------------------------------------------------------------------------------------------------------------------------------------
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.