28.02.2013, 16:20 | #1 (permalink) |
Member
Регистрация: 23.02.2013
Сообщений: 1,353
Сказал(а) спасибо: 4
Поблагодарили 5 раз(а) в 2 сообщениях
Репутация: 5285
|
Нужна подсказка по программе к ШИМ для 2 серво. Язык С, ATtiny13A
Код:
#define F_CPU 9600000UL // Частота МК 9,6 MHz #include <avr/io.h> // Библиотека ввода-вывода "io.h" #include <util/delay.h> // Библиотека задержек "delay.h" int t1, t2, t; //Тайминг первого и второго выхода, задержка int main(void) // начало основой программы { /*Настраиваем ШИМ на микроконтроллере. Страницы 69-73 в даташите на ATtiny13. COM0A1-Fast PWM Mode - Сброс ОС0А в момент совпадения, установка ОС0А при достижении счетчиком значения ТОР COM0B1-Fast PWM Mode - Сброс ОС0B в момент совпадения, установка ОС0B при достижении счетчиком значения ТОР WGM01 - Включаем Fast PWM Mode 3 WGM00 - Включаем Fast PWM Mode 3 CS02 - Устанавливаем делитель 256*/ TCCR0A|=(1 << COM0A1)|(1 << COM0B1)|(1 << WGM01)|(1 << WGM00); //Можно вместо этого еще так TCCR0A=A3; TCCR0B|=(1 << CS02); //Можно вместо этого еще так TCCR0B=04; DDRB = 0x03; // выводы PB1,PB0 порта B сконфигурировать как выходы, // остальные как входы while (1) { // Бесконечный цикл OCR0A=t1; //Обрабатываем первый выход OCR0B=t1; //Обрабатываем второй выход //Обработка входов if ((PINB & (1 << PB2)) == 1) //Фиксирует 1 на входе 1 { _delay_ms(30); //Устранение "дребезга клавиш" if ((PINB & (1 << PB2)) == 1) //Проверяем { t1 += t; //Увеличиваем задержку входа 1 } } if ((PINB & (1 << PB3)) == 1) //Фиксирует 1 на входе 2 { _delay_ms(30); //Устранение "дребезга клавиш" if ((PINB & (1 << PB3)) == 1) //Проверяем { t1 -= t; //Уменьшаем задержку входа 1 } } if ((PINB & (1 << PB4)) == 1) //Фиксирует 1 на входе 3 { _delay_ms(30); //Устранение "дребезга клавиш" if ((PINB & (1 << PB4)) == 1) //Проверяем { t2 += t; //Увеличиваем задержку входа 2 } } if ((PINB & (1 << PB5)) == 1) //Фиксирует 1 на входе 4 { _delay_ms(30); //Устранение "дребезга клавиш" if ((PINB & (1 << PB5)) == 1) //Проверяем { t2 -= t; //Уменьшаем задержку входа 2 } } } // закрывающая скобка бесконечного цикла } // закрывающая скобка основной программы Кстати, я еще не дописал защиту для крайнего левого и правого положения, но это уже мелочи. PS: Тинек много, можно экспериментировать до посинения. Последний раз редактировалось Suharev; 28.02.2013 в 16:25 |
28.02.2013, 16:20 | |
Helpmaster
Member
Регистрация: 08.03.2016
Сообщений: 0
|
Аналогичные проблемы уже обсуждались ранее Очень нужна подсказка по блоку питания Рекурсия, язык с++ Язык программирования F# Функции, язык Си |
28.02.2013, 16:32 | #2 (permalink) |
Member
Регистрация: 23.02.2013
Сообщений: 1,353
Сказал(а) спасибо: 4
Поблагодарили 5 раз(а) в 2 сообщениях
Репутация: 5285
|
Да, забыл еще притянуть порты к земле перед циклом.
Почти итоговый вариант: Код:
#define F_CPU 9600000UL // Частота МК 9,6 MHz #include <avr/io.h> // Библиотека ввода-вывода "io.h" #include <util/delay.h> // Библиотека задержек "delay.h" int t1, t2, t, tmax, tmin; //Тайминг первого и второго выхода, задержка //максимальное и минимальное значение int main(void) // начало основой программы { /*Настраиваем ШИМ на микроконтроллере. Страницы 69-73 в даташите на ATtiny13 COM0A1-Fast PWM Mode - Сброс ОС0А в момент совпадения, установка ОС0А при достижении счетчиком значения ТОР COM0B1-Fast PWM Mode - Сброс ОС0B в момент совпадения, установка ОС0B при достижении счетчиком значения ТОР WGM01 - Включаем Fast PWM Mode 3 WGM00 - Включаем Fast PWM Mode 3 CS02 - Устанавливаем делитель 256*/ TCCR0A|=(1 << COM0A1)|(1 << COM0B1)|(1 << WGM01)|(1 << WGM00); //Можно вместо этого еще так TCCR0A=A3; TCCR0B|=(1 << CS02); //Можно вместо этого еще так TCCR0B=04; DDRB = 0x03; // выводы PB1,PB0 порта B сконфигурировать как выходы, остальные как входы PORTB &= ~_BV(PB2); //Притянули порт 2 к земле PORTB &= ~_BV(PB3); //Притянули порт 3 к земле PORTB &= ~_BV(PB4); //Притянули порт 4 к земле PORTB &= ~_BV(PB5); //Притянули порт 5 к земле while (1) { // Бесконечный цикл OCR0A=t1; //Обрабатываем первый выход OCR0B=t1; //Обрабатываем второй выход //Обработка входов if ((PINB & (1 << PB2)) == 1) //Фиксирует 1 на входе 1 { _delay_ms(30); //Устранение "дребезга клавиш" if ((PINB & (1 << PB2)) == 1) //Проверяем { if (t1 < tmax){ //Проверяем на корректность t1 += t;} //Увеличиваем задержку входа 1 } } if ((PINB & (1 << PB3)) == 1) //Фиксирует 1 на входе 2 { _delay_ms(30); //Устранение "дребезга клавиш" if ((PINB & (1 << PB3)) == 1) //Проверяем { if (t1 > tmin){ t1 -= t;} //Уменьшаем задержку входа 1 } } if ((PINB & (1 << PB4)) == 1) //Фиксирует 1 на входе 3 { _delay_ms(30); //Устранение "дребезга клавиш" if ((PINB & (1 << PB4)) == 1) //Проверяем { if (t2 < tmax){ t2 += t;} //Увеличиваем задержку входа 2 } } if ((PINB & (1 << PB5)) == 1) //Фиксирует 1 на входе 4 { _delay_ms(30); //Устранение "дребезга клавиш" if ((PINB & (1 << PB5)) == 1) //Проверяем { if (t2 > tmin){ t2 -= t;} //Уменьшаем задержку входа 2 } } } // закрывающая скобка бесконечного цикла } // закрывающая скобка основной программы Последний раз редактировалось Suharev; 28.02.2013 в 16:42 |
03.03.2013, 04:18 | #5 (permalink) |
Member
Регистрация: 23.02.2013
Сообщений: 1,353
Сказал(а) спасибо: 4
Поблагодарили 5 раз(а) в 2 сообщениях
Репутация: 5285
|
Опыты дали на выходе хрень и один сожженный серво.
Попытки разобраться в расчетах опять завели меня в тупик, так как нихрена не ясно что откуда берется. Ответом так никто и не удосужился. Одно из двух, либо никто сам ничего не знает и не понимает и пользуется чужими наработками, либо птицы слишком высокого полета. Будьте так любезны приземлиться и объяснить как нужно рассчитывать программный ШИМ, что откуда брать и как это калькулировать, например тот же Fast PWM, либо прикройте тему. |
Ads | |
Member
Регистрация: 31.10.2006
Сообщений: 40200
Записей в дневнике: 0
Сказал(а) спасибо: 0
Поблагодарили 0 раз(а) в 0 сообщениях
Репутация: 55070
|
03.03.2013, 20:11 | #6 (permalink) |
Member
Регистрация: 13.05.2011
Сообщений: 401
Сказал(а) спасибо: 0
Поблагодарили 0 раз(а) в 0 сообщениях
Репутация: 274
|
Вопрос задан не корректно, непонятно что вам объяснять, с чего начинать, как глубоки ваши познания в данном вопросе. Именно по этому и на радиокоте вам никто и не ответил.
Исходя из вопроса ваши познания практически равны 0. Сожженный сервак тому подтверждение. Я не представляю как его можно спалить даже подав на него постоянку он должен работать без каких либо проблем. И неужели вместо сервака нельзя было подключить лампочку и шимить ее. Даже в даташите на мк, довольно подробно описан режим работы шима. "Рассчитать задержку" - непонятно о чем вы? |
03.03.2013, 21:17 | #7 (permalink) |
Member
Регистрация: 23.02.2013
Сообщений: 1,353
Сказал(а) спасибо: 4
Поблагодарили 5 раз(а) в 2 сообщениях
Репутация: 5285
|
Если бы были я бы не спрашивал, а значит ноль.
Нет, серв не жалко, а мне нужно видеть наглядно угол отклонения, методом подбора цифр смог добиться +-1,2 градуса в нулевом положении. Хорошо, напишу что я смог вычитать из даташитов и, как я думаю, понять: - мне нужен режим Fast PWM. - разрядность 256. - в этом режиме в начале цикла ставит на указанный выход "0" пока не отсчитает заранее заданное количество тактов из 255 и устанавливает на выход "1" до конца отсчета. - мне нужно будет инвертировать этот выход. Мне нужна частота сигнала 50Гц. Задержка (или ширина импульса) от 0,8мс до 2,2мс (центр 1,5мс) Т.е. от 4% до 11% от ширины сигнала. Вопрос: как исходя из тактовой частоты процессора и всех этих данных просчитать и сформировать сигнал на определенном выходе используя средства ATtiny13A (внешний кварц не поставить) и язык C (AVR Studio 4)? В принципе нужный сигнал можно сформировать 555 таймером, что я и делал, и управлять резистором, но это уже садомазо когда это можно решить проще. Последний раз редактировалось Suharev; 03.03.2013 в 21:26 |
04.03.2013, 00:16 | #8 (permalink) |
Member
Регистрация: 13.05.2011
Сообщений: 401
Сказал(а) спасибо: 0
Поблагодарили 0 раз(а) в 0 сообщениях
Репутация: 274
|
Если использовать железный ШИМ, то само ближе к вашей частоте вы получите 73.242Гц (тактовая 4,8МГц, делитель 256) или 36Гц (тактовая 9,6МГц, делитель 1024).
Ну, а программным можно получить и ровно 50Гц. Дальше считаете 0,8мс: 1/73=0,0137С - период ШИМ, 0,0137/0,0008=256/Х => X=15 - число записанное в компаратор . Аналогично для 2,2мс: 1/73=0,0137С - период ШИМ, 0,0137/0,0022=256/Х => X=41 - число записанное в компаратор. А если нужно получить в процентах то уж пересчитайте временные интервалы под 73Гц. Обоснуйте выбор тактовой. И обновлять компараторы лучше в прерывании. |
04.03.2013, 00:49 | #9 (permalink) |
Member
Регистрация: 13.05.2011
Сообщений: 401
Сказал(а) спасибо: 0
Поблагодарили 0 раз(а) в 0 сообщениях
Репутация: 274
|
Не нашел описание вашего сервы, но наше подобный. Понял откуда тактовая. Вобщем сформировать такую частоту можно только программным ШИМом (или ставит внешний генератор/кварц). Можно запустить таймер допустим с прерываниями каждые 0,1мС, а уже в обработчике, сравнивая счетчик прерываний (доп. переменная) и переменную длинны импульса, выводить в порт лог 1 или 0.
|
04.03.2013, 09:03 | #10 (permalink) | ||
Member
Регистрация: 23.02.2013
Сообщений: 1,353
Сказал(а) спасибо: 4
Поблагодарили 5 раз(а) в 2 сообщениях
Репутация: 5285
|
Цитата:
Цитата:
Но тогда получается нужно будет поправку на выполняемые такты основной программы, иначе импульс просто "поведет". |
||
Ads | |
Member
Регистрация: 31.10.2006
Сообщений: 40200
Записей в дневнике: 0
Сказал(а) спасибо: 0
Поблагодарили 0 раз(а) в 0 сообщениях
Репутация: 55070
|
|
|