Un problema grave con 2 o más ADC de ATmega16

-2

He habilitado 2 ADC de mi microcontrolador pero hay mucho ruido. Quiero decir que cuando ADC (0) está habilitado, todo está bien, pero después de habilitar ADC (1) se activa el ruido.

Aquí está mi código:

Chip type : ATmega16
Program type : Application
AVR Core Clock frequency: 16/000000 MHz
Memory model : Small
External RAM size : 0
Data Stack size : 256
*****************************************************/

#include <mega16.h>

#include <delay.h>

#ifndef RXB8
#define RXB8 1
#endif

#ifndef TXB8
#define TXB8 0
#endif

#ifndef UPE
#define UPE 2
#endif

#ifndef DOR
#define DOR 3
#endif

#ifndef FE
#define FE 4
#endif

#ifndef UDRE
#define UDRE 5
#endif

#ifndef RXC
#define RXC 7
#endif

#define FRAMING_ERROR (1<<FE)
#define PARITY_ERROR (1<<UPE)
#define DATA_OVERRUN (1<<DOR)
#define DATA_REGISTER_EMPTY (1<<UDRE)
#define RX_COMPLETE (1<<RXC)

// Get a character from the USART Receiver
#ifndef _DEBUG_TERMINAL_IO_
#define _ALTERNATE_GETCHAR_
#pragma used+
char getchar(void)
{
char status,data;
while (1)
{
while (((status=UCSRA) & RX_COMPLETE)==0);
data=UDR;
if ((status & (FRAMING_ERROR | PARITY_ERROR | DATA_OVERRUN))==0)
return data;
}
}
#pragma used-
#endif

// Write a character to the USART Transmitter
#ifndef _DEBUG_TERMINAL_IO_
#define _ALTERNATE_PUTCHAR_
#pragma used+
void putchar(char c)
{
while ((UCSRA & DATA_REGISTER_EMPTY)==0);
UDR=c;
}
#pragma used-
#endif

// Standard Input/Output functions
#include <stdio.h>

unsigned int adc_data;
#define ADC_VREF_TYPE 0x40

// ADC interrupt service routine
interrupt [ADC_INT] void adc_isr(void)
{
// Read the AD conversion result
adc_data=ADCW;
}

// Read the AD conversion result
// with noise canceling
unsigned int read_adc(unsigned char adc_input)
{
ADMUX=adc_input | (ADC_VREF_TYPE & 0xff);
// Delay needed for the stabilization of the ADC input voltage
delay_us(10);
#asm
in r30,mcucr
cbr r30,__sm_mask
sbr r30,__se_bit | __sm_adc_noise_red
out mcucr,r30
sleep
cbr r30,__se_bit
out mcucr,r30
#endasm
return adc_data;
}

int knob1,knob2;
float y;


void main(void)
{
// Declare your local variables here

// Input/Output Ports initialization
// Port A initialization
// Func7=In Func6=In Func5=In Func4=In Func3=In Func2=In Func1=In Func0=In
// State7=T State6=T State5=T State4=T State3=T State2=T State1=T State0=T
PORTA=0x00;
DDRA=0x00;

// Port B initialization
// Func7=In Func6=In Func5=In Func4=In Func3=In Func2=Out Func1=Out Func0=Out
// State7=T State6=T State5=T State4=T State3=T State2=0 State1=0 State0=0
PORTB=0x00;
DDRB=0x07;

// Port C initialization
// Func7=In Func6=In Func5=In Func4=In Func3=In Func2=In Func1=In Func0=In
// State7=T State6=T State5=T State4=T State3=T State2=T State1=T State0=T
PORTC=0x00;
DDRC=0x00;

// Port D initialization
// Func7=In Func6=In Func5=In Func4=In Func3=In Func2=In Func1=In Func0=In
// State7=T State6=T State5=T State4=T State3=T State2=T State1=T State0=T
PORTD=0x00;
DDRD=0x00;

// Timer/Counter 0 initialization
// Clock source: System Clock
// Clock value: Timer 0 Stopped
// Mode: Normal top=0xFF
// OC0 output: Disconnected
TCCR0=0x00;
TCNT0=0x00;
OCR0=0x00;

// Timer/Counter 1 initialization
// Clock source: System Clock
// Clock value: Timer1 Stopped
// Mode: Normal top=0xFFFF
// OC1A output: Discon.
// OC1B output: Discon.
// Noise Canceler: Off
// Input Capture on Falling Edge
// Timer1 Overflow Interrupt: Off
// Input Capture Interrupt: Off
// Compare A Match Interrupt: Off
// Compare B Match Interrupt: Off
TCCR1A=0x00;
TCCR1B=0x00;
TCNT1H=0x00;
TCNT1L=0x00;
ICR1H=0x00;
ICR1L=0x00;
OCR1AH=0x00;
OCR1AL=0x00;
OCR1BH=0x00;
OCR1BL=0x00;

// Timer/Counter 2 initialization
// Clock source: System Clock
// Clock value: Timer2 Stopped
// Mode: Normal top=0xFF
// OC2 output: Disconnected
ASSR=0x00;
TCCR2=0x00;
TCNT2=0x00;
OCR2=0x00;

// External Interrupt(s) initialization
// INT0: Off
// INT1: Off
// INT2: Off
MCUCR=0x00;
MCUCSR=0x00;

// Timer(s)/Counter(s) Interrupt(s) initialization
TIMSK=0x00;

// USART initialization
// Communication Parameters: 8 Data, 1 Stop, Even Parity
// USART Receiver: On
// USART Transmitter: On
// USART Mode: Asynchronous
// USART Baud Rate: 9600
UCSRA=0x00;
UCSRB=0x18;
UCSRC=0xA6;
UBRRH=0x00;
UBRRL=0x67;

// Analog Comparator initialization
// Analog Comparator: Off
// Analog Comparator Input Capture by Timer/Counter 1: Off
ACSR=0x80;
SFIOR=0x00;

// ADC initialization
// ADC Clock frequency: 125/000 kHz
// ADC Voltage Reference: AVCC pin
// ADC Auto Trigger Source: ADC Stopped
ADMUX=ADC_VREF_TYPE & 0xff;
ADCSRA=0x8F;

// SPI initialization
// SPI disabled
SPCR=0x00;

// TWI initialization
// TWI disabled
TWCR=0x00;

// Global enable interrupts
#asm("sei")

while (1)
{
PORTB.0=0;
PORTB.1=0;
PORTB.2=0;
delay_ms(30);
y=read_adc(0);
knob1=(y/1023)*127;
printf(" knob1= ");
printf("%d",knob1);

PORTB.0=0;
PORTB.1=0;
PORTB.2=1;
delay_ms(30);
y=read_adc(0);
knob2=(y/1023)*127;
delay_ms(1000);
printf(" knob2= ");
printf("%d",knob2);
delay_ms(1000);
}
}

Y esta es la salida (ya puse las perillas en 127):

    
pregunta Hossein

2 respuestas

1

probablemente sea un problema de hardware, ¿hay un condensador en la entrada Vref, una resistencia desde Vcc a AVcc y un condensador desde AVCC a GND? ¿Están las entradas de ADC lejos de las señales ruidosas? Es mejor usar el evaluador interno de Vref que AVCC. intente conectar 2 entradas ADC juntas e intente convertir cada una, luego compare los resultados.

    
respondido por el ir.imad
0

Gracias por las respuestas

He hecho muchos cambios:

Puse el multiplexor y cambié completamente el código

  

¿Por qué crees que ayudaría ver el software? ¿Revisaste tus señales con un osciloscopio?

No reviso el circuito con el osciloscopio porque no tengo un osciloscopio acabo de comprobar con multímetro

  

probablemente sea un problema de hardware, ¿hay un condensador en la entrada Vref, una resistencia desde Vcc a AVcc y un condensador desde AVCC a GND? ¿Están las entradas de ADC lejos de las señales ruidosas? Es mejor usar el evaluador interno de Vref que AVCC. intente conectar 2 entradas ADC juntas e intente convertir cada una, luego compare los resultados.

Este es el circuito:

circuito

y este es el código:

//my global variables :  

int noisereduction(int ADC);
void send(int x);
int knob1,knob2,array[2],copyarray[2],c[2]={30,30},index=0,i;
while (1)
{
  knob1=noisereduction(0);
  array[0]=knob1; 
  knob2=noisereduction(1);
  array[1]=knob2;        
  for(i=0;i<2;i++)
  {
   if (array[i]!=copyarray[i])
   {
    c[index]=i;
    index++;
   } 
  }     
  for(i=0;i<2;i++)
  if(c[i]!=30)
  {
   index=c[i];
   switch (index)
   { 
     case 0:
     {
      delay_ms(50);
      printf(" knob1= ");
      printf("%d",array[index]);
     }
     case 1:
     { 
      delay_ms(50);
      printf(" knob2= ");
      printf("%d",array[index]);
   }
 }

}

index=0;    
for(i=0;i<2;i++)
{
 c[i]=30;
  copyarray[i]=array[i];
}   

}

int noisereduction(int ADC)
{
 int sum=0,x,reduction[4],i;
 float y;
 sum=0;
 for(i=0;i<4;i++)
 {
   delay_ms(30);
   y=read_adc(ADC);
   x=(y/1023)*127;
   reduction[i]=x;
   sum=sum+reduction[i];
 }
 return sum/=4;

}

void send(int x) { int y; y=UCSRA & 0b00100000; while(y != 0b00100000) { y=UCSRA & 0b00100000; } UDR=x; }

pero la salida:

cuando cambio el segundo potenciómetro (ADC (1) o mando 2) Lo erery es bueno

knob2

pero se escucha ruido: D cuando cambio el primer potenciómetro (ADC (0) o mando 1) por qué el mando 2 está cambiando cuando ni siquiera lo toco, me está volviendo loco: D

salida: knob1 = 1 knob2 = 1 knob1 = 5 knob2 = 5 knob1 = 8 knob2 = 8 knob1 = 10 knob2 = 10 ..etc

    
respondido por el Hossein

Lea otras preguntas en las etiquetas