roboforum.ru

Технический форум по робототехнике.

Управление Сервами в WinAvr

Ответить

aesok » 14 авг 2006, 21:42

Lirzman писал(а):
Код: Выделить всёРазвернуть
//****************ИНИЦИАЛИЗАЦИЯ ТАЙМЕРА***************************
void timer1_init(long int time)
{
TCCR1B = 0x00; //stop timer
TCNT1 = time; //записать в регистр таймера число 3686400/1/x

TIMSK SET_B(TOIE1);//Разрешение прерывания по переполнению таймера 1
SREG SET_B(7);//Бит i в регистре SREG включен(разрешить глобальные прерывания)
TCCR1B =0x01; //Старт таймера при делителе = 0
//Биты CS10 CS11 CS12
}
//**************ПРОЦЕДУРА ПЕРЕПОЛНЕНИЯ ТАЙМЕРА***********************
SIGNAL(SIG_OVERFLOW1)
{
PORTB CLR_B(gservo);//В ПРОТЕУСЕ загорелся соответствующий пин!!!!
}


Как видите коэффициент деления равен единице, тоесть таймер работает на частоте ЦП(3.6864MHz) :shock:



Попробуй теперь сделать как я писал, чтобы длительность 0 и 1 была разной. В твоем симуляторе есть чтото типа осцилографа, чтобы ты мог видеть какой сигнал формируеться на пине?

Анатолий.

PS: Всетаки используй sei(); вместо SREG SET_B(7); это красивее и понятние всем.

Lirzman » 14 авг 2006, 22:02

aesok писал(а):В твоем симуляторе есть чтото типа осцилографа, чтобы ты мог видеть какой сигнал формируеться на пине?

Да, оссцилограф есть, но я им пока не пользуюсь т.к в симуляторе показывается градус поворота сервы с точностью - 2 зтака после запятой
:D  я по ним и настраиваю задержки что-б тютелька в тютельку было :D

aesok писал(а):Всетаки используй sei(); вместо SREG SET_B(7); это красивее и понятние всем.


А что тут непонятного?
SREG - регистр
SET_B(x) - установить бит(номер x)
Вместо SREG можно PORTD поставить например,
так что тоже очень универсально.
Тем более я ф-ции эти с сайта avr123.nm.ru взял, так что все претензии к автору. :D  :D  :D
Последний раз редактировалось Lirzman 14 авг 2006, 22:38, всего редактировалось 1 раз.

Lirzman » 14 авг 2006, 22:38

Возникла проблема требующая нетривиального решения.

Как известно на серву сначала надо подать управляющий импульс
а потом импульс длительностью 20мс.
Насколько я знаю 20мс импульс нужен для того что-бы отделять умравляющие импульсы друг от друга.

У меня такой код:

Код: Выделить всёРазвернуть
/**************ПРОЦЕДУРА ПЕРЕПОЛНЕНИЯ ТАЙМЕРА***********************
SIGNAL(SIG_OVERFLOW1)
{
PORTB CLR_B(gservo);//спад импульса в 1.5мс
}

//************ПРОЦЕДУРА ПОЗИЦИОНИРОВАНИЯ СЕРВЫ********************
void Pos(char servo,long int angle)
{

PORTB SET_B(servo);
gservo=servo;
timer1_init(angle);

}


Куда мне вставлять задержку в 20мс???

После строчки timer1_init(angle); я это сделать не могу т.к к этому моменту таймер еще не успеет отсчитать свои 1.5мс.

А в функцию прерывания вставлять задержку - смерти подобно, получится бесконечный цикл.

Существует ли такая ф-ция которая бы ПЕРЕХВАТЫВАЛА прерывание и выполняла код сразу ПОСЛЕ него???
Знаю что на компе есть такая штука, зовется она CATCH(какое нибудь событие).
На счет МК - с таким зверем я еще не сталкивался.

Может я что-то путаю???

aesok » 14 авг 2006, 22:51

Lirzman писал(а):
aesok писал(а):В твоем симуляторе есть чтото типа осцилографа, чтобы ты мог видеть какой сигнал формируеться на пине?

Да, оссцилограф есть, но я им пока не пользуюсь т.к в симуляторе показывается градус поворота сервы с точностью - 2 зтака после запятой
:D  я по ним и настраиваю задержки что-б тютелька в тютельку было :D

aesok писал(а):Всетаки используй sei(); вместо SREG SET_B(7); это красивее и понятние всем.


А что тут непонятного?
SREG - регистр
SET_B(x) - установить бит(номер x)
Вместо SREG можно PORTD поставить например,
так что тоже очень универсально.
Тем более я ф-ции эти с сайта avr123.nm.ru взял, так что все претенции к автору. :D  :D  :D


Так пишет только 123. Не учись плохому. В С принято "чему присваиваеш" "=" "что присваиваеш", или МАКРО(1параметр, 2, ...). А два макроса без разделителей не принято. Тебя за это будут сильно
пинать. Из  avr-libc выкинули даже более Сишные макросы outp(port, val) и sbi(port, bit). Если очень хочется используй лучше их.

Если тебя интерисует мое мнение: мне это очень, очень не нравиться.  Пиши как принято в С.

Анатолий.

aesok » 14 авг 2006, 23:00

Lirzman писал(а):Возникла проблема требующая нетривиального решения.

Как известно на серву сначала надо подать управляющий импульс
а потом импульс длительностью 20мс.
Насколько я знаю 20мс импульс нужен для того что-бы отделять умравляющие импульсы друг от друга.

У меня такой код:

Код: Выделить всёРазвернуть
/**************ПРОЦЕДУРА ПЕРЕПОЛНЕНИЯ ТАЙМЕРА***********************
SIGNAL(SIG_OVERFLOW1)
{
PORTB CLR_B(gservo);//спад импульса в 1.5мс
}

//************ПРОЦЕДУРА ПОЗИЦИОНИРОВАНИЯ СЕРВЫ********************
void Pos(char servo,long int angle)
{

PORTB SET_B(servo);
gservo=servo;
timer1_init(angle);

}


Куда мне вставлять задержку в 20мс???

После строчки timer1_init(angle); я это сделать не могу т.к к этому моменту таймер еще не успеет отсчитать свои 1.5мс.

А в функцию прерывания вставлять задержку - смерти подобно, получится бесконечный цикл.

Существует ли такая ф-ция которая бы ПЕРЕХВАТЫВАЛА прерывание и выполняла код сразу ПОСЛЕ него???
Знаю что на компе есть такая штука, зовется она CATCH(какое нибудь событие).
На счет МК - с таким зверем я еще не сталкивался.

Может я что-то путаю???


Я же тебе уже писал алгоритм, посмотри на предыдущей странице.

Анатолий.
Последний раз редактировалось aesok 14 авг 2006, 23:15, всего редактировалось 1 раз.

avr123.nm.ru » 14 авг 2006, 23:12

aesok писал(а):Так пишет только 123. Не учись плохому.


вы сами видели что я пишу ?

aesok » 14 авг 2006, 23:14

avr123.nm.ru писал(а):
aesok писал(а):Так пишет только 123. Не учись плохому.


вы сами видели что я пишу ?


Я видел ЭТО на вашем сайте. И ЭТОМУ людей учите ВЫ.

Анатолий.

avr123.nm.ru » 14 авг 2006, 23:24

вы напишите что ЭТО конкретно и не правильно - я исправлю чтоб люди не повторяли ошибок. 

я ж говорил я не занимаюсь WinAVR и курс у меня соответственно по CVAVR и немного ICC.

aesok » 14 авг 2006, 23:27

avr123.nm.ru писал(а):вы напишите что ЭТО конкретно и не правильно - я исправлю чтоб люди не повторяли ошибок. 

я ж говорил я не занимаюсь WinAVR и курс у меня соответственно по CVAVR и немного ICC.


ЭТО НЕ С:
#define SET_B(x) |= (1<<x) //Спасибо AVR123 :)
#define CLR_B(x)  &=~(1<<x) //Спасибо AVR123 :)

Анатолий.

avr123.nm.ru » 14 авг 2006, 23:27

вот это ?   http://avr123.nm.ru/z1.htm

1) мой вариант для любого компилятора:

// объявление:

#define SET_B(x) |= (1<<x)
#define CLR_B(x) &=~(1<<x)
#define INV_B(x) ^=(1<<x)

// x - номер бита в регистре

// использование:

PORTB SET_B(5);  // "установить"  бит5

PORTB CLR_B(2);  // "очистить"  бит2

PORTB INV_B(6);  // инвертировать бит6

============

или что ?

avr123.nm.ru » 14 авг 2006, 23:30

aesok писал(а):ЭТО НЕ С:

#define SET_B(x) |= (1<<x) //Спасибо AVR123 :)
#define CLR_B(x)  &=~(1<<x) //Спасибо AVR123 :)

Анатолий.


а что тут не правильного ?

aesok » 14 авг 2006, 23:36

[quote="avr123.nm.ru"][/quote]

Ваяснять с Вами отношения я не буду.

Я дал совет человеку (Lirzman) и пивел ему свои аргументы. Он сам примет свое решение. И будет писать как ему нраватися.

ВЫ меня не интерисуете.

Анатолий.

Сергей » 14 авг 2006, 23:48

Да ладно ребят выяснять что правильно а что нет) Ну хотябы по личке обсудилибы, а то помойму оффтопите. Лирзман сам поймет как ему лучше прописывать и потом поймет как нада правильно писать. Вы лучшеб помогли человеку код сделать, он всетаки просит помочь.

Lirzman » 15 авг 2006, 01:30

aesok писал(а):ЭТО НЕ С:
#define SET_B(x) |= (1<<x) //Спасибо AVR123 Smile
#define CLR_B(x)  &=~(1<<x) //Спасибо AVR123 Smile

Тут все зависит от того как кого учили, поэтому спор бессмысленный.

Я научился пользоваться оссцилографом!!!
При подаче управляющего сигнала возникает фронт  :D

2aesok: Я сделал все как вы сказали но эффекта - 0
Странно, по идее после первого-же управляющего сигнала, линию(сигнал) на осциллографе должно страшно колбасить с периодом в 20мс.
Хммм...
Ладно, утро вечера мудренее, завтра закончу.

avr123.nm.ru » 15 авг 2006, 12:13

вы сформулируйте ТЗ для вашего устройства и опубликуйте.


Rambler\'s Top100 Mail.ru counter