To forum jest dla wszystkich pasjonatów mikrokontrolerów AVR Atmela. Wymiana doświadczeń i pomoc dla początkujących w pisaniu programów zarówno w C, Asemblerze jak i BASCOM. Zapraszam znawców tematu, aby pomogli wszystkim początkującym!
-
Aro
- Użytkownik
- Posty: 677
- Rejestracja: 30 paź 2006, 18:49
- Lokalizacja: Świerczyniec | Wrocław
-
Kontakt:
Post
autor: Aro » 08 lip 2008, 20:06
Witam,
Śmieszny problem, no ale cóż

Mam problem z napisaniem programu obsługującego dwa kanały ADC. Praktycznie brak separacji kanałów, sygnał z jednago nachodzi na drugi i odwrotnie. Poniżej listing:
Kod: Zaznacz cały
int main(void)
{
TCCR0=_BV(CS00);
TIMSK=_BV(TOIE0);
ADMUX = _BV(REFS1) | _BV(REFS0); // wybierz kanał 0 przetwornika ADC
ADCSR = _BV(ADEN)|_BV(ADPS2); //ADC
DDR(T1)=_BV(T1pin);
DDR(T2)|=_BV(T2pin);
wdt_enable(WDTO_15MS);
while(1)
{
if(PIN(POWER)&_BV(POWERpin)) exitp=0;
else exitp=1;
PWM=150;
while(exitp)
{
PORT(T1)|=_BV(T1pin);
ADMUX = ( _BV(REFS1) | _BV(REFS0)); //kanał 0
_delay_loop_2(1000);
_delay_loop_1(50);
ADCSR|=_BV(ADSC);
_delay_loop_1(50);
uint16_t value=ADCW;
ADCSR|=_BV(ADSC);
_delay_loop_1(15);
value+=ADCW;
if(value>1610)PWM--;
if(value<1525)PWM++;
if(value>1700)PWM--;
if(value<1350)PWM++;
if(value>1730)PWM-=2;
if(value<1200)PWM++;
if(PWM>199)PWM=199;
if(PWM<2)PWM=2;
_delay_loop_2(1000);
ADMUX = ( _BV(MUX1) | _BV(REFS1) | _BV(REFS0)); //kanał 3
_delay_loop_2(1000);
ADCSR|=_BV(ADSC);
_delay_loop_1(50);
ADCSR&=~(_BV(ADIF)); //powinno byc raczej ADCSR|=_BV(ADIF);
value=ADCW;
//ADCSR|=_BV(ADSC);
_delay_loop_1(15);
value+=ADCW;
_delay_loop_1(50);
//if(value<1000)exitp=0;*/
for(uint16_t i=0; i<200; i++)
{
if(PWM>i) PORT(T1)|=_BV(T1pin);
else PORT(T1)&=~(_BV(T1pin));
_delay_loop_1(28);
}
PORT(T1)&=~(_BV(T1pin));
wdt_reset();
PORT(T2)|=_BV(T2pin);
ADMUX = ( _BV(REFS1) | _BV(REFS0)); //kanał 0
_delay_loop_2(1000);
ADCSR|=_BV(ADSC);
_delay_loop_1(50);
value=ADCW;
ADCSR|=_BV(ADSC);
_delay_loop_1(15);
value+=ADCW;
if(value>1660)PWM--;
if(value<1450)PWM++;
if(value>1800)PWM-=2;
if(value<1000)PWM+=2;
if(value<800)PWM+=3;
if(value<600)PWM+=4;
if(PWM>199)PWM=199;
if(PWM<2)PWM=2;
for(uint16_t i=0; i<200; i++)
{
if(PWM>i) PORT(T2)|=_BV(T2pin);
else PORT(T2)&=~(_BV(T2pin));
_delay_loop_1(28);
}
PORT(T2)&=~(_BV(T2pin));
wdt_reset();
if(PIN(POWER)&_BV(POWERpin)) exitp=0;
}
wdt_reset();
}
return 0;
}
-
Leszczu87
- -
- Posty: 7
- Rejestracja: 23 wrz 2005, 9:34
Post
autor: Leszczu87 » 29 sie 2008, 16:54
Miałem podobny problem chociaż program nie miał błędów - co sekunde miał dawac na zmiane wyniki z czujników, ale wszystko wariowało. W końcu uzyłem wyświetlania jednoczesnego na ekranie obu wyników w taki sposób i o dziwo działa(choć zasada działanie pozostała w zasadzie ta sama):
Kod: Zaznacz cały
SIGNAL(SIG_ADC) // przerwanie z przetwornika ADC
{
value1 = ADCW;
if(k==1)
{
wysw();
}
if(k==2)
{
wysw2();
k=0;
}
k=k+1;
}
void wysw(void)
{
uint16_t temp=0;
ADMUX = 1<<REFS0 | 1<<MUX0;
ADCSRA = 1<<ADSC | 1<<ADEN | 1<<ADIE | 1<<ADPS2 | 1<<ADPS1; //| 1<<ADFR;
LCDpsec();
temp=value1;
LCDcommand(LCDC_DDA|12);
LCDdec(temp);
value1 = 0;
LCDpsec();
}
void wysw2()
{
uint16_t temp=0;
ADMUX = 1<<REFS0;
ADCSRA = 1<<ADSC | 1<<ADEN | 1<<ADIE | 1<<ADPS2 | 1<<ADPS1; //| 1<<ADFR;
LCDpsec();
LCDcommand(LCDC_DDA|65);
temp=value1;
LCDdec(temp);
}
void LCDpsec(void)
{
_delay_ms(50);
}
int main(void)
{
DDRD = 1<<7 | 1<<6 | 1<<5 | 1<<3 | 1<<4;
DDRB = 1;
PORTD=1<<0 | 1<<1 | 1<<2;
TCCR1B = 1<<CS12;//1<<CS11 | 1<<CS10; //prescaler dla timer1 x64
ADMUX = 1<<REFS0; // wybierz kanał 0 przetwornika ADC i AREF zewnetrzne
ADCSRA = 1<<ADEN | 1<<ADIE | 1<<ADPS2 | 1<<ADPS1; //| 1<<ADFR;
// włącz przetwornik i uruchom generowanie przerwań
// częstotilwość taktowania F_ADC=F_CPU/64
// przy F_CPU=8MHz : F_ADC=125 kHz
LCDinit();
LCDcls();
LCDpsec();
LCDstr("2 czujniki");
//LCDcommand(LCDC_CGA|2);
LCDcommand(LCDC_DDA|40);
LCDstr("");
sei(); // włącz obsługę przerwań
ADCSRA = 1<<ADSC | 1<<ADEN | 1<<ADIE | 1<<ADPS2 | 1<<ADPS1;
}
Kod umieszcza się między znacznikami code. Następnym razem będzie ostrzeżenie. CSM
Ostatnio zmieniony 29 sie 2008, 16:55 przez
Leszczu87, łącznie zmieniany 1 raz.
-
Aro
- Użytkownik
- Posty: 677
- Rejestracja: 30 paź 2006, 18:49
- Lokalizacja: Świerczyniec | Wrocław
-
Kontakt:
Post
autor: Aro » 29 sie 2008, 21:11
Mój problem polegał na tym, że nie sprawdziłem dokładnie połączeń na płytce testowej, a powodem dziwnych wyników była duża rezystancja jednego z przewodów. Program jest dobry.