roboforum.ru

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

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

Ответить

Lirzman » 14 авг 2006, 19:00

aesok писал(а):Используйте 16-битный таймер, с 8 битным будет очень маленькая точность.

Как раз наоборот!!!!!!!!!!!

У меня тоже была такая идея!!!!
Но она оказалась в корне неправильной!!!
Поясню почему:
Частота таймера высчитывается по формуле:
Частота внешнего кварца / коэффициент делителя(биты CS00,CS01,CS02)\число которое надо отсчитать

Так вот, в нашем случае используется 8-битный таймер(0..255)

Считаем:
3 686 400/8/255=~1807.05HZ
Т.К Чем польше герц тем БОЛЬШЕ частота,тем меньше промежуток в мс.

Попробуем сделать это как вы говорите:
3 686 400/8/35536=~12.9Hz
Так что для того что-бы увеличить частоту(точность позиционирования сервы) надо или УМЕНЬШАТЬ разрядность таймера(куда уж меньше:D ) или УМЕНЬШАТЬ коэффициент делителя или УВЕЛИЧИВАТЬ частоту внешнего кварца.

Вот так вот :shock:  :shock:  :shock:
Последний раз редактировалось Lirzman 14 авг 2006, 19:12, всего редактировалось 4 раз(а).

Lirzman » 14 авг 2006, 19:03

aesok писал(а):Используйте макросы _delay_us и _delay_ms. Но в качестве параметра им можно передовать только константу!!!!

Так для этого я и пользуюсь функцией delaysa, потому что мне нужна ПЕРЕМЕННАЯ а не константа.

aesok » 14 авг 2006, 19:17

Lirzman писал(а):
aesok писал(а):Используйте 16-битный таймер, с 8 битным будет очень маленькая точность.

Как раз наоборот!!!!!!!!!!!

У меня тоже была такая идея!!!!
Но она оказалась в корне неправильной!!!
Поясню почему:
Частота таймера высчитывается по формуле:
Частота внешнего кварца / коэффициент делителя(биты CS00,CS01,CS02)\число которое надо отсчитать

Так вот, в нашем случае используется 8-битный таймер(0..255)

Считаем:
3 686 400/8/255=~1807.05HZ
Т.К Чем польше герц тем БОЛЬШЕ частота,тем меньше промежуток в мс.

Попробуем сделать это как вы говорите:
3 686 400/8/35536=12Hz
Так что для того что-бы повысить точность надо или УМЕНЬШАТЬ разрядность таймера(куда уж меньше:D ) или УВЕЛИЧИВАТЬ частоту внешнего кварца.

Вот так вот :shock:  :shock:  :shock:


Вы путаете минимальную частоту которую можно дибиться с помощью таймера с точностью. С помощю 8 битного таймера вы можете разделить на 256 интервалов, а с помощью 16- битного на 65 тысяч.

Частота у вас задано 50 гц (20 мс).  При использовании 8-битного таймера можно устанавливать длительность импульса с точностью 0,08 мс (20/256), а с помощью 16-битного 0.0003мс (20/65000).


Анатолий.

Lirzman » 14 авг 2006, 19:26

aesok писал(а):а с помощью 16-битного 0.0003мс (20/65000).

Хммм...
Попробую реализовать.
В любом случае спасибо. :D

aesok » 14 авг 2006, 19:32

Lirzman писал(а):
aesok писал(а):Используйте макросы _delay_us и _delay_ms. Но в качестве параметра им можно передовать только константу!!!!

Так для этого я и пользуюсь функцией delaysa, потому что мне нужна ПЕРЕМЕННАЯ а не константа.


...тогда _delay_loop_1 и _delay_loop_2 из delay.h они конечно для внутреннего пользования, но зато они написаны на ассемблере и оптимизатор не будет над ними издеваться.

Анатолий.

avr123.nm.ru » 14 авг 2006, 19:58

Lirzman писал(а):Люди!
Я чего-то запутался, в курсе /03.htm  говорится:

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


Управление сервами подразумевает сплошные задержки :?, что мне делать???

Если нельзя делать паузы в прерываниях, то как вообще сервами управлять то??????  


1. ОЧЕВИДНЫЙ ответ описаный на стр 1 курса:

ПОСМОТРИТЕ КАК ЭТО СДЕЛАНО ДРУГИМИ ЛЮДЬМИ !

2. "все прерывания..."  т.е. речь идет о том когда у вас несколько источников прерываний!

Если же у вас 1 прерывание то сидите в обработчике хоть до посинения.

вопрос только ЗАЧЕМ ?   ведь ту паузу что вы делаете в конце обработчика можно отработать таймером.

avr123.nm.ru » 14 авг 2006, 20:00

Lirzman писал(а):Так что надо искать выход из данной ситуации!!!!


Ну конечно ИСКАТЬ !  

===============  google.com  и уже былона этом форуме !


SERVO 32 штуки на CVAVR Lynxmotion Robot Kits
http://www.lynxmotion.com/

видите там прекрасных роботов
http://www.lynxmotion.com/Category.aspx?CategoryID=65

заходите на страничку серво контроллера
SSC-32 Servo Controller
http://www.lynxmotion.com/Product.aspx? ... egoryID=52

в разделе  Downloads  есть терминал lzk ПК для управления SERVO

инструкция   ssc-32v2.pdf  - в ней есть управление серво и протокол для управления с ПК.


и ГЛАВНОЕ !!!  есть исходники

"This servo controller is Open Source."
http://www.lynxmotion.com/images/html/proj078.htm

там мы видим исходник управления 32 !!! servo  на ATmega8

"This is the complete SSC-32 source code"

Скачиваем и учимся.

Там еще и бутлодер для меги8.

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

Как сделать шестиногую шагающую платформу !!!  подробности и VIDEO
http://www.lynxmotion.com/images/html/build074.htm

есть исходник автономного режима с двумя датчиками Sharp GP2D12 !

==================
там же куча инструкций по компонентам робототехники !
http://www.lynxmotion.com/ViewPage.aspx ... ID=70#serv

ЧИТАЙТЕ !!!

УЧИТЕСЬ !!!

ДЕЛАЙТЕ ЛУЧШЕ !!!

avr123.nm.ru » 14 авг 2006, 20:02

aesok писал(а):С помощю 8 битного таймера вы можете разделить на 256 интервалов, а с помощью 16- битного на 65 тысяч


я думаю интервалы разбиения зависят от предделителя тактирования таймера.

а 256 и 65тыс это наверно возможное число отсчетов.

Lirzman » 14 авг 2006, 20:24

avr123.nm.ru писал(а):ГЛАВНОЕ !!!  есть исходники

Что толку от исходников на "С" если подпрограмма управления 16-ти битным таймером написана на ASM :?:  :?:  :?:
==============================================

Переделал под 16-ти битный таймер, только прерывания не происходит, в чем дело???

Регистр TCCR1A я не трогал всё остальное переделал из ДШ.
Вот код:

Код: Выделить всёРазвернуть
//****************ИНИЦИАЛИЗАЦИЯ ТАЙМЕРА***************************
void timer1_init(void)
{
TCCR1B = 0x00; //stop timer
TCNT1 = 120; //записать в регистр таймера число 3686400/1024/120(x)
TIMSK SET_B(TOIE1);//Разрешение прерывания по переполнению таймера 1
SREG SET_B(7);//Бит i в регистре SREG включен(разрешить глобальные прерывания)
TCCR1B =0x05; //Старт таймера при делителе = 1024
//Биты CS10 CS11 CS12
}
//**************ПРОЦЕДУРА ПЕРЕПОЛНЕНИЯ ТАЙМЕРА***********************
SIGNAL(SIG_OVERFLOW1)
{

PORTB CLR_B(gservo);
//delaysa(period);//Задержка в 20мс, ПОКА использую силы CPU
}

aesok » 14 авг 2006, 20:57

TCNT1 = 120; //записать в регистр таймера число 3686400/1024/120(x)

Как я понял таймер инкрементирует значение счетчика тоесть 121,122.. и это очень долго. Что показывает симулятор? Может правильно -120.

TIMSK SET_B(TOIE1);//Разрешение прерывания по переполнению таймера 1
SREG SET_B(7);//Бит i в регистре SREG включен(разрешить

В avr-libc для разрешения запрещения прерываний служат sei()/cli().

Анатолий.

Lirzman » 14 авг 2006, 21:03

aesok писал(а):Как я понял таймер инкрементирует значение счетчика тоесть 121,122.. и это очень долго

Вот я остолоп, таймер то 16-ти битный. :D  :D  :D
Стоило изменить коэффициент деления с 1024 до 0 как все заработало. :D

avr123.nm.ru » 14 авг 2006, 21:07

Lirzman писал(а):
avr123.nm.ru писал(а):ГЛАВНОЕ !!!  есть исходники

Что толку от исходников на "С" если подпрограмма управления 16-ти битным таймером написана на ASM :?:  :?:  :?:


ну дак там не 120 инструкций АСМа наверно ! и не на японском языке же.

Алгоритм то понятен ?  И вам же не нужно 32 сервы.

Lirzman » 14 авг 2006, 21:22

СПАСИБО что подсказали про 16-ти битный таймер.
:!:Всё работает и точность на уровне!!!:!:
Самое приятное что функцию радержки и на 1.5мс и на 20мс можно теперь можно реализовать всего одной процедурой!!!  
То есть точно так-же как со старой функцией delaysa(int mks);
только теперь на аппаратном таймере без загрузки ЦП!!!
Так что код получился весьма универсальным, на одном таймере можно и сервами управлять и часы для детонатора замутить. :D  :D  :D

aesok » 14 авг 2006, 21:26

Lirzman писал(а):СПАСИБО что подсказали про 16-ти битный таймер.
:!:Всё работает и точность на уровне!!!:!:
Самое приятное что функцию радержки и на 1.5мс и на 20мс можно теперь можно реализовать всего одной процедурой!!!  
То есть точно так-же как со старой функцией delaysa(int mks);
только теперь на аппаратном таймере без загрузки ЦП!!!
Так что код получился весьма утиверсальным, на одном таймере можно и сервами управлять и часы для детонатора замутить. :D  :D  :D


Шли код, еще поругаю. :)

Анатолий.

Lirzman » 14 авг 2006, 21:30

Код: Выделить всёРазвернуть
//****************ИНИЦИАЛИЗАЦИЯ ТАЙМЕРА***************************
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:


Rambler\'s Top100 Mail.ru counter