Технический форум по робототехнике.
valba10 » 26 фев 2011, 17:53
Доброго времени суток!
Я новичок в этом деле, так что не пинайте если что!
При написании программы для GP2D120 возникла проблема!
Сервопривод остается в одном положении и не реагирует на изменения в АЦП.
Может подскажите в чем проблема?
- Код: Выделить всё • Развернуть
#include <avr/io.h>
#include <util/delay.h>
unsigned int getADC(void) //Считывание АЦП
{ unsigned int v;
ADCSRA|=(1<<ADEN)|(1<<ADSC)|(1<<ADFR); //Начать преобразование
while ((ADCSRA&_BV(ADIF))==0x00) //Дождатся окончания преобразования
;
v=(ADCL|ADCH<<8);
return v;
}
void Servo (void)
{
OCR1A=200;
return;
}
void Serv (void)
{
OCR1A=400;
return;
}
int main(void)
{
unsigned int u;
ADCSRA=(1<<ADPS2)|(1<<ADPS1)|(1<<ADPS0);
ADMUX=(0<<REFS1)|(1<<REFS0)|(0<<MUX0)|(0<<MUX1)|(0<<MUX2)|(0<<MUX3);
TCCR1A|=(1<<COM1A1)|(1<<COM1B1)|(1<<WGM11); //NON Inverted PWM
TCCR1B|=(1<<WGM13)|(1<<WGM12)|(1<<CS11)|(1<<CS10); //PRESCALER=64 MODE 14(FAST PWM)
TCCR1B|=(1<<COM1A1)|(1<<COM1B1)|(1<<WGM11);
ICR1=4999; //fPWM=50Hz (Period = 20ms Standard).
DDRB|=(1<<PB2)|(1<<PB1); //PWM Pins as Ou
while(1)
{
u = getADC();
if (u>400) Serv();
if (u<184) Servo();
return u;
};
return 1;
}
Заранее огромное всем спасибо!

- Вложения
-
Proteus.rar
- (20.68 КиБ) Скачиваний: 0
Myp » 26 фев 2011, 22:33
ты бы ещё сказал что по тоему мнению эта программа должна была делать

дабы мы знали, чего именно она не делает))
valba10 » 27 фев 2011, 01:46
Ой извиняюсь!
В зависимости от расстояния от преграды до дальномера, сервопривод должен менять угол поворота.
В Протеусе сервопривод занимает определённый угол, но при изменении напряжения с дальномера, сервопривод остается в том же положении.
Что может быть не так с программой, или это лаги Протеуса?
=DeaD= » 27 фев 2011, 11:01
while(1)
{
u = getADC();
if (u>400) Serv();
if (u<184) Servo();
return u;
};
Нафиг сюда "return u" вставлено?
И почему не обрабатывается u в промежутке 184-400 ?
И что у вас должно писаться в OCR1A? в зависимости от требуемого кол-ва мкс?
valba10 » 27 фев 2011, 14:23
RETURN здесь не нужен?
В промежутке 184-400 пустота, я пробовал делать 395-400 - результат тот же.
OCR1A - это для управления сервой ))))
=DeaD= » 27 фев 2011, 14:33
Я знаю, что для управления сервой, я спрашиваю что туда выдать надо, чтобы серва встала, скажем, в положение соответствующее ширине импульса 1500мкс?
valba10 » 27 фев 2011, 14:57
Есть формула, я её на каком то сайте нарыл, но забыл на каком.
Вот я немного подправил программу, все работает, спасибо тем, кто сюда заглянул.))))))
- Код: Выделить всё • Развернуть
#include <avr/io.h>
#include <util/delay.h>
unsigned int getADC(void) //Считывание АЦП
{ unsigned int v;
ADCSRA|=(1<<ADSC)|(1<<ADFR); //Начать преобразование
while ((ADCSRA&_BV(ADIF))==0x00);
v=(ADCL|ADCH<<8);
return v;
}
int main(void)
{
unsigned int u=0;
ADCSRA=(1<<ADEN)|(1<<ADPS2)|(1<<ADPS1)|(1<<ADPS0);
ADMUX=(1<<REFS1)|(1<<REFS0)|(0<<MUX0)|(0<<MUX1)|(0<<MUX2)|(0<<MUX3);
TCCR1A|=(1<<COM1A1)|(1<<COM1B1)|(1<<WGM11); //NON Inverted PWM
TCCR1B|=(1<<WGM13)|(1<<WGM12)|(1<<CS11)|(1<<CS10); //PRESCALER=64 MODE 14(FAST PWM)
TCCR1B|=(1<<COM1A1)|(1<<COM1B1)|(1<<WGM11);
ICR1=4999; //fPWM=50Hz (Period = 20ms Standard).
DDRB|=(1<<PB2)|(1<<PB1); //PWM Pins as Ou
while(1)
{
u = getADC();
if (u<380) OCR1A=200;
u = getADC();
if (u>379) OCR1A=400;
};
return 1;
}