Welcome to EDAboard.com

Welcome to our site! EDAboard.com is an international Electronics Discussion Forum focused on EDA software, circuits, schematics, books, theory, papers, asic, pld, 8051, DSP, Network, RF, Analog Design, PCB, Service Manuals... and a whole lot more! To participate you need to register. Registration is free. Click here to register now.

ADC conversion using AVR

Status
Not open for further replies.

graciouspace

Newbie level 4
Joined
Mar 11, 2012
Messages
5
Helped
0
Reputation
0
Reaction score
0
Trophy points
1,281
Activity points
1,321
Hi i need to write an AVR code to program the Atmega 644. The input is an analogue signal(a continuous square wave) . I want an output which detects whether the input signal is high.
For this purpose I have written some code. I'm using an ADC to convert the analogue signal to a digital signal. Further I am using pin change interrupt to detect when the input signal is high. But my code is not working :sad::sad: . I'll be grateful if someone could help me with the correct code. thanks! I'm posting my code below:


Code C - [expand]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
#include <avr/io.h>
#include <avr/interrupt.h>
#include <util/delay.h>
#include <stdlib.h>
 
int main()
{
DDRC= 0b11111111; //PortC set as output port
ADMUX |= 1<<MUX0; //ADC input set to PA0
 
ADMUX |= 1<<REFS0; //voltage reference taken from AREF pin
 
ADMUX |=1<<ADLAR; //using 8 bit resolution
 
ADCSRA |= 1<<ADEN; //turns on ADC
 
ADCSRA |= 1<<ADPS1 | 1<<ADPS0; //Prescaler set at 16
 
ADCSRA |= 1<<ADIE; //ADC interrupt enable
 
sei(); //enable global interrupts
 
ADCSRA |= 1<<ADSC; //start AD conversion
while(1)
{}
}
ISR(ADC_vect) //interrupt service routine for ADC
{ //interrupts while loop when ADC conversion is finished
switch(ADMUX) //switches between the two analogue inputs and outputs a pulse on Channel A and B
{
case 1:   //That is, the output is high. This might have to be changed.
PORTC = 0b00000001; //If the whistle is detected, PC0 goes to 1 for 30 seconds 
_delay_ms(30000); //And then goes back 0
PORTC = 0b00000000;
break;
default:
PORTC= 0b00000000;
break;
}
ADCSRA |= 1<<ADSC; //starts next AD conversion
}

 
Last edited by a moderator:

alexan_e

Administrator
Joined
Mar 16, 2008
Messages
11,888
Helped
2,021
Reputation
4,158
Reaction score
2,030
Trophy points
1,393
Location
Greece
Activity points
64,371
What is the voltage and frequency of the input square wave?
Why don't you use an external interrupt input triggered with both rising and falling edges?

What do you have a 30 second delay inside the interrupt?
Code:
_delay_ms(30000); //And then goes back 0

What is
Code:
switch(ADMUX) //switches between the two analogue inputs and outputs a pulse on Channel A and B
{
case 1:   //That is, the output is high. This might have to be changed.
supposed to do?
ADMUX is a 8bit register that has several bits set in your code so how to you expect to ever get a 0b00000001 result?


Alex
 

graciouspace

Newbie level 4
Joined
Mar 11, 2012
Messages
5
Helped
0
Reputation
0
Reaction score
0
Trophy points
1,281
Activity points
1,321
What is the voltage and frequency of the input square wave?
Why don't you use an external interrupt input triggered with both rising and falling edges?

What do you have a 30 second delay inside the interrupt?
Code:
_delay_ms(30000); //And then goes back 0

What is
Code:
switch(ADMUX) //switches between the two analogue inputs and outputs a pulse on Channel A and B
{
case 1:   //That is, the output is high. This might have to be changed.
supposed to do?
ADMUX is a 8bit register that has several bits set in your code so how to you expect to ever get a 0b00000001 result?


Alex

Hey Alex! Thanks for your reply.

The input voltage is - 5V and the frequency is 2.3KHz.
Since I'm connecting an LED to the output , I want the LED to glow for 30s and then turn off detecting that the input is a high.

Yes, I'm pretty confused. It would be grateful if you could help me . Thanks.
 

alexan_e

Administrator
Joined
Mar 16, 2008
Messages
11,888
Helped
2,021
Reputation
4,158
Reaction score
2,030
Trophy points
1,393
Location
Greece
Activity points
64,371
OK , why don't you use the external interrupt instead?
Why is it important to use the ADC for that job?
 

graciouspace

Newbie level 4
Joined
Mar 11, 2012
Messages
5
Helped
0
Reputation
0
Reaction score
0
Trophy points
1,281
Activity points
1,321
OK , why don't you use the external interrupt instead?
Why is it important to use the ADC for that job?

Hey! Thanks. But I'm pretty new to AVR so I am confused. Is it possible to do it without ADC? Code you give me the code of doing it with external interrupts. Thank You so much!
 

alexan_e

Administrator
Joined
Mar 16, 2008
Messages
11,888
Helped
2,021
Reputation
4,158
Reaction score
2,030
Trophy points
1,393
Location
Greece
Activity points
64,371
Suppose that you want to use INT0 which is in PD2


Code C - [expand]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
int main(void)
{
    EICRA = (1 << ISC00); // set to trigger with level change (both rising and falling)
    EIMSK = (1 << INT0); // enable INT0
    EIFR = (1 << INTF0); // clear the interrupt flag
    sei();
 
    while(1);
}
 
//then the interrupt
ISR(INT0_vect) //interrupt service routine for ADC
{
    // do what you want here like toggle the led
 
    // you can also read the input pin if you want to check if the pulse is currently high or low
    if(PINB & 4)
    {
        // the pulse is high
    }
    else
    {
        // the pulse is low
    }
}



Alex
 

graciouspace

Newbie level 4
Joined
Mar 11, 2012
Messages
5
Helped
0
Reputation
0
Reaction score
0
Trophy points
1,281
Activity points
1,321
Suppose that you want to use INT0 which is in PD2


Code C - [expand]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
int main(void)
{
    EICRA = (1 << ISC00); // set to trigger with level change (both rising and falling)
    EIMSK = (1 << INT0); // enable INT0
    EIFR = (1 << INTF0); // clear the interrupt flag
    sei();
 
    while(1);
}
 
//then the interrupt
ISR(INT0_vect) //interrupt service routine for ADC
{
    // do what you want here like toggle the led
 
    // you can also read the input pin if you want to check if the pulse is currently high or low
    if(PINB & 4)
    {
        // the pulse is high
    }
    else
    {
        // the pulse is low
    }
}



Alex

Hey thanks a lotttt :). It helped me a lot !

---------- Post added at 02:49 ---------- Previous post was at 02:48 ----------

You can do some reading if you're confused about interrupts and external interrupt:

[TUT] Newbie's Guide to AVR Interrupts
**broken link removed**
External Interrupts on an ATmega168

Hope this helps.
Tahmid.

Thank u dude
 

Status
Not open for further replies.

Similar threads

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Top