Тема создана по мотивам переписки меня и denissyslo по электронной почте, которую принято решение перетащить сюда, чтобы осталось для следующих "поколений"
Добавлено спустя 3 минуты 40 секунд:
denissyslo писал(а):
Разбираюсь второй день - не могу сообразить как рулить сервами от портов, но которых нет аппаратного шима (наверное я тупой). Нашел только на 8 странице курса в примерах для меги 128, но там подключают их на ноги с аппаратным шимом...
Хотел просить тебя дать кусок кода от твоего касательно серв контроллера на изучение.
Добавлено спустя 31 секунду:
=DeaD= писал(а):
Попробую пояснить - я вешаю на прерывание по таймеру, которое срабатывает каждые 160 тактов (с частотой 100КГц), что даёт мне разрешение 10мкс, то есть учитывая, что я должен выдать на серву сигнал шириной 1000-2000мкс (1-2мс), я имею 100 позиций сервы. то есть шаг 1.8 градуса.
SIGNAL(SIG_OVERFLOW0){ TCNT0=0x5F; //0x5F=255-160 - to get this interrupt each 160/16'000'000=1/100'000 sec
//*************************************************************************************************** //Here is servo-controlling block //*************************************************************************************************** if(tmr<200){
uint8_t tmp=tmr; //Тут надо вычитать соответствующий отступ, а тут это ноль
if(types[0]==2){ //Тут у меня лежит тип выхода, 2 - выход на серву if(tmp==0){ outb(PORTA,inb(PORTA) | 0x01); }; //Set PA0 pin to 1 uint16_t xxx=value[0]; if(xxx>MAXSERVO){ xxx=MAXSERVO; }; if(xxx<MINSERVO){ xxx=MINSERVO; }; if(tmp==xxx){ outb(PORTA,inb(PORTA) & 0xFE); }; //Set PA0 pin to 0 }; if(types[1]==2){ if(tmp==0){ outb(PORTA,inb(PORTA) | 0x02); }; //Set PA1 pin to 1 uint8_t xxx=value[1]; if(xxx>MAXSERVO){ xxx=MAXSERVO; }; if(xxx<MINSERVO){ xxx=MINSERVO; }; if(tmp==xxx){ outb(PORTA,inb(PORTA) & 0xFD); }; //Set PA1 pin to 0 };
};
tmr++; if(tmr==2150){ tmr=0; };
};
ну и инициализация прерывания:
// Initiating Timer/Counter-0 Control Registers: // // TCCR0 = FOC0:WGM00:COM01:COM00:WGM01:CS02:CS01:CS00 // 0 0 0 0 0 0 0 1 // // COM1x1:COM1x0 = 0:0 => OC1x disconnected from output pin // FOC1A:FOC1B = 0:0 => Don't force output compare event // WGM13:WGM12:WGM11:WGM10 = 0:0:0:0 => Normal timer/counter operation // ICNC1 = 0 => Input Capture Noise Canceller disabled (because not needed) // ICES1 = 0 => Input Capture Edge Select set to "falling" mode (no matter) // CS12:CS11:CS10 = 0:0:1 => Timer "on", no prescaling (1 clock every cpu tact) // TCCR1A = 00000000 = 0x00 TCCR0=0x01;
TCNT0=0x69;
// Initiating internal program subcounter with zero tmr=0;
> Антон, привет! Начинаю раскидывать твой код: > Еще посылаю мой исходник. В нем пытаюсь рулить одной сервой на ПОРТА.1. > Посмотри пожалуйста. Компилятор коде визионАВР. Не могу там кое-что понять. > Ниже то как я разбирал твой код. > > > Попробую пояснить - я вешаю на прерывание по таймеру, которое срабатывает > каждые 160 тактов (с частотой 100КГц), что даёт мне разрешение 10мкс, то > есть учитывая, что я должен выдать на серву сигнал шириной 1000-2000мкс > (1-2мс), я имею 100 позиций сервы. то есть шаг 1.8 градуса. > > > SIGNAL(SIG_OVERFLOW0){ > TCNT0=0x5F; //0x5F=255-160 - to get this interrupt each > 160/16'000'000=1/100'000 sec !!! это пишем в блоке объявления > переменных!!!??? > > !!!т.к. у меня кварц 10Мгц, то будет так: > > Попробую пояснить - я вешаю на прерывание по таймеру, которое срабатывает > каждые 100 тактов (с частотой 100КГц), что даёт мне разрешение 10мкс, то > есть учитывая, что я должен выдать на серву сигнал шириной 1000-2000мкс > (1-2мс), я имею 100 позиций сервы. то есть шаг 1.8 градуса. > > TCNT0=0x9B; //0x9B=255-100 - to get this interrupt each > 100/10'000'000=1/100'000 sec > > Правильно? > > > //************************************************************************** > ************************* > //Here is servo-controlling block > > //************************************************************************** > ************************* > if(tmr<200){ !!!тут мы проверяем - накопилось ли 20мс. В начале > надо объявить tmr integer'ом???? > > uint8_t tmp=tmr; //Тут надо вычитать соответствующий отступ, а тут это > ноль !!!немного не понял - это чисто ФИЧА ТВОЙ программы. Точнее вообще не > понял. ????? > > if(types[0]==2){ //Тут у меня лежит тип выхода, 2 - выход на серву > !!!тут надо понимать тоже ПРИМОЧКА твоего контроллера!!!? > if(tmp==0){ outb(PORTA,inb(PORTA) | 0x01); }; //Set PA0 pin to 1 > !!!тут вроде ясно - если начало цикла то устанавливаем порт А.1 как выход!!! > > uint16_t xxx=value[0]; !!! вот тут немного не ясно ххх - это > задание угла сервы???? Т.е. это какая-то переменная? Т.е. мы должна в начале > программы ее объявить, например int? Если да, то в каком формате задавать > угол - ххх это количество тактов по 10мкс????? > > if(xxx>MAXSERVO){ xxx=MAXSERVO; }; !!! Тут понял - проверяем - не > уехали ли мы за предельное значение - что бы небыло зависания проги!!! > if(xxx<MINSERVO){ xxx=MINSERVO; }; !!! Аналогично проверка > минимального значения, все продумано Вначале программы необходимо > объявить MAXSERVO и MINSERVO типами int и присвоить значения, только тогда > КАКИЕ ЗНАЧЕНИЯ??? В тиках по 10мкс???? Т.е 21 и 9 соответственно??? !!! > > if(tmp==xxx){ outb(PORTA,inb(PORTA) & 0xFE); }; //Set PA0 pin to 0 > !!! тут вроде разобрался - все просто если текущее значение, того сколько > времени прошло по 10мкс (переменная tmp) равно установленному углу, то > поускаем на нашу ножку 0! Т.е. в начале надо объявить tmp int & tmp=0;??? > }; > > !!!Ну ниже я так понимаю все АБСОЛЮТНО так же только для следующей ножки. > Антон, такой вопрос: ххх естественно это другая переменная и вообще имя ххх > для читабельности лучше заменить на что-то типа servo_2 (хотя это конечно не > принципиально). А переменная tmp для всех ножек будет одна и таже???!!! > > if(types[1]==2){ !!! вот этот ИФ (и выше): if(types[1]==2){};Я могу > смело убрать? Оставивто что в скобках???!!! > > if(tmp==0){ outb(PORTA,inb(PORTA) | 0x02); }; //Set PA1 pin to 1 > uint8_t xxx=value[1]; > if(xxx>MAXSERVO){ xxx=MAXSERVO; }; > if(xxx<MINSERVO){ xxx=MINSERVO; }; > if(tmp==xxx){ outb(PORTA,inb(PORTA) & 0xFD); }; //Set PA1 pin to 0 > }; > > }; > > tmr++; !!! тут тоже вроде понял - следующий шаг - инкримент > > if(tmr==2150){ !!! а вот тут я действительно не понял...по идее тут могла > быть проверка на выполнения полного цикла, но цикл то у нас 200 раз по > 10мкс???? И вообще что за цифра в 2150 и откуда она...как говорил ДЖАМШУТ > ПонятнА....ннепонЯтА. > tmr=0; > }; > > }; > > > Вот этот блок с сервами я пишу в основном цикле программы (после вайл(1) > )????? А где обнуление переменной tmp ???? > > > > > ОГО...с этим будет трудно для меня... > Это где мы пишем?????? Это сделано генератором кода КВАРА???? Пойдет ли мне > этот прибамбас, если у меня кварц 10, а не 16? > > ну и инициализация прерывания: > > // Initiating Timer/Counter-0 Control Registers: > // > // TCCR0 = FOC0:WGM00:COM01:COM00:WGM01:CS02:CS01:CS00 > // 0 0 0 0 0 0 0 1 > // > // COM1x1:COM1x0 = 0:0 => OC1x disconnected from output pin > // FOC1A:FOC1B = 0:0 => Don't force output compare event > // WGM13:WGM12:WGM11:WGM10 = 0:0:0:0 => Normal timer/counter operation > // ICNC1 = 0 => Input Capture Noise Canceller disabled (because not > needed) > // ICES1 = 0 => Input Capture Edge Select set to "falling" mode (no > matter) > // CS12:CS11:CS10 = 0:0:1 => Timer "on", no prescaling (1 clock every cpu > tact) > // TCCR1A = 00000000 = 0x00 > TCCR0=0x01; > > TCNT0=0x69; > > > К этому куску аналогичные вопросы . > > // Initiating internal program subcounter with zero > tmr=0; > > // Initiating Timer/Counter Interrupt Mask register: > // > // TIMSK = OCIE2:TOIE2:TICIE1:OCIE1A:OCIE1B:TOIE1:OCIE0:TOIE0 > // 0 0 0 0 0 1 0 0 > // > // OCIE2 = 0 => Timer/Counter2 Output Compare Match Interrupt disabled > // TOIE2 = 0 => Timer/Counter2 Timer Overflow disabled > // TICIE1 = 0 => Timer/Counter1 Input Capture Interrupt disabled > // OCIE1x = 0 => Timer/Counter1 Output Compare Match Interrupt disabled > // TOIE1 = 0 => Timer/Counter1 Timer Overflow enabled > // OCIE0 = 0 => Timer/Counter0 Output Compare Match Interrupt disabled > // TOIE0 = 1 => Timer/Counter0 Timer Overflow disabled > TIMSK=0x01; > > И разрешение на работу прерываний: > > sei(); !!! В кваре, кажется пишется немного по-другому...
Добавлено спустя 33 секунды:
=DeaD= писал(а):
Итак по порядку:
1. Со средой CVAVR не знаком, могу только про WinAVR говорить, но регистры и порты все те же, если ты разбираешься с CVAVR - легко переделаешь под себя;
2. Переделка TCNT0 под кварц 10МГц правильная;
3. Нулевой отступ при расчете переменной tmp - это если мне надо будет рулить скажем 20-ю сервами, в этом случае мне нельзя будет сразу их все обрабатывать, потому что я тогда не уложусь скорее всего в 100 тактов которые проходят между прерываниями, поэтому я буду первые 2мс из 20мс обрабатывать первые несколько серв, потом следующие несколько и т.д. Я сейчас по 2-3 сервы обрабатываю за раз, чтобы успевать оставшееся время работать с UART'ом и движками. То есть если надо будет рулить 4 сервами, я их буду обрабатывать не в if(tmr<200), а в if(tmr>=200 && tmr<400) и там уже напишу tmp=tmr-200;
4. xxx=value[0] - это должно быть число от 100 до 199 означающее количество тактов прерывания (по 10мкс) которое будет длиться импульс для управления сервой;
5. MIN/MAXSERVO объявлять лучше через #define, а не переменными - не перегружаем программу лишними переменными;
6. Обнуление переменной tmp не нужно, поскольку она в каждом цикле заново инициализируется из tmr;
_________________ Проект [[Open Robotics]] - Универсальные модули для построения роботов
Да типа того... только у меня робот на CodeVisonAVR, а тут код для ВИНАВР. Думаю идея всем понятна... Сейчас необходимо этот код портировать на КВАР. параметры: АТМЕГА16 10Мгц Сервы на порте А первые 7 ножек. Очень жду помощи. Сам тоже буду выкладывать. вот мои творения - результат почти 0.
Заголовок сообщения: Re: Управление RC-Servo на AVR на прерываниях
Добавлено: 23 апр 2008, 14:08
Зарегистрирован: 06 окт 2004, 18:01 Сообщения: 24218 Откуда: Ебург
прог. языки: C++ / PHP / 1C
ФИО: Антон Ботов
А какой помощи ты ждешь?
Отлаживать твою прошивку врядли кто-то сможет, у нас же твоего робота с подцепленными устройствами нету.
Ситуация очень даже штатная. Как говориться - поздравляем вы дошли до уровня сложного проекта, и поскольку он собирается вами с нуля - вы остаётесь с ним почти один на один
_________________ Проект [[Open Robotics]] - Универсальные модули для построения роботов
Заголовок сообщения: Re: Управление RC-Servo на AVR на прерываниях
Добавлено: 23 апр 2008, 14:44
отсылающий читать курс
Зарегистрирован: 06 ноя 2005, 04:18 Сообщения: 14195 Откуда: Москва
Интересный топик.
Сергей писал(а):
Могу выложить старый проект управления сервами по i2c на ATmega8, нужно?
Нужно конечно - выложи. Только опиши что к чему.
http://OpenServo.org тоже по i2c управляется и вроде считавает положение сервы даже.
Добавлено спустя 8 минут 7 секунд:
denissyslo писал(а):
АТМЕГА16 - 10Мгц .
Я бы взял 14 "с копейками" - по даташиту из таблицы USART.
denissyslo писал(а):
servo Сервы на порте А первые 7 ножек.
Можно разбить управление 7 servo на 7 фаз. Один таймер прерывается каждые 2800 мкС и в прерывании включает очередную серву и отсчет ВТОРЫМ таймером длины импульса для нее. Когда второй таймер отсчитает сколько нужно он выключает импульм на серву.
Таким образом все сервы получают импульс раз в 19,6 мСек.
Да очень простой.... есть полно описание моего устройства: Атмега16 Кварц 10 Мгц Серва подключена на ножку ПортА.1 Требуется: взять мой код и поправить его как надо. Т.е. посмотреь мою программу и знаю основную идею Деада о управлении сервами по прерываниям. написать все ПРАВИЛЬНО подпраить - написаь
Цитата:
Отлаживать твою прошивку врядли кто-то сможет, у нас же твоего робота с подцепленными устройствами нету.
Да отлаживать то я и не прошу. На самом деле все СТАНДАРТНО и задачко-то почти стандартная - есть МК, известны параметры - кварц и нога МК, на эту ногу надо грамотно подать шим сигнал. ВСЕ.
Цитата:
Ситуация очень даже штатная. Как говориться - поздравляем вы дошли до уровня сложного проекта, и поскольку он собирается вами с нуля - вы остаётесь с ним почти один на один
В плане руления ервой по-грамотному - проект типовой...... Мечта идиота - примр такой программы от гуру.....
_________________ краткая биография: родился в роддоме - учился на учебе - служил на службе - работал на работе.....
Хех... а вы давайте железку разведите (к первому посту) да что бы повторяемость была.....разведете - респек и уважуха, а софт там давно уже отработан и велосипеды изобретать не стоит
Заголовок сообщения: Re: [FAQ] SERVO - как управлять на AVR в прерываниях
Добавлено: 05 авг 2008, 13:15
Зарегистрирован: 20 мар 2006, 00:53 Сообщения: 57 Откуда: ukraine
Зачем изобретать велосипед? Все уже есть, посмотрите руководство пользователя по контроллеру SSC32 http://www.lynxmotion.com/images/data/ssc-32.pdf с принципиальной схемой (копировать всю схему полностью не обязательно)
Зачем разводить плату? У SSC32 достаточно сложная схема. Плата двухсторонняя с маленькой шириной дорожек. Если очень припекло и нет возможности купить оригинал, то соберите макетку как сделал это я.
Если нужна помощь обращайтесь. Я собрал макет на ATMega8 в учебных целях. Мне удалось залить фирменную прошивку. Макет функционирует как ожидалось.
Когда то давно я нашел в интернете прошивку генерирующую программно PWM на мега8. Код на С для WinAVR без лишних заморочек с минимальным интерфейсом, коммуникация с PC по UART. Если интересно пишите, я дам исходники.
Заголовок сообщения: Re: [FAQ] SERVO - как управлять на AVR в прерываниях
Добавлено: 05 авг 2008, 13:49
Зарегистрирован: 29 дек 2004, 23:15 Сообщения: 3744 Откуда: Санкт-Петербург
прог. языки: C, C++, C#, Asm
ФИО: Кашликов Сергей
Никто велосипед не собирает, так сделано в образовательных целях. А так конечно выкладывай свои результаты! Оформи тему со схемами и соответствующими файлами
Заголовок сообщения: Re: [FAQ] SERVO - как управлять на AVR в прерываниях
Добавлено: 05 авг 2008, 15:24
Зарегистрирован: 20 мар 2006, 00:53 Сообщения: 57 Откуда: ukraine
Выложу обязательно и исходники и схему и все платы и механику с чертежами по моему проекту Bipedal robot. На video.mail.ru выложен промежуточный результат.
Зачем изобретать велосипед? Все уже есть, посмотрите руководство пользователя по контроллеру SSC32 http://www.lynxmotion.com/images/data/ssc-32.pdf с принципиальной схемой (копировать всю схему полностью не обязательно)
Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 0
Вы не можете начинать темы Вы не можете отвечать на сообщения Вы не можете редактировать свои сообщения Вы не можете удалять свои сообщения Вы не можете добавлять вложения