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.

Status
Not open for further replies.

graciouspace

Newbie level 4
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<<REFS0; //voltage reference taken from AREF pin

sei(); //enable global interrupts

while(1)
{}
}
{ //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;
}
}

Last edited by a moderator:

alexan_e

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

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

is that a -5v ?
a negative voltage?

alexan_e

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

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

graciouspace

Points: 2

graciouspace

Newbie level 4
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
External Interrupts on an ATmega168

Hope this helps.
Tahmid.

Thank u dude

Status
Not open for further replies.