Технический форум
Вернуться   Технический форум > Электроника, самоделки и техника > Форум по электронике > Микропроцессоры


Ответ
 
Опции темы Опции просмотра
Старый 28.02.2013, 16:20   #1 (permalink)
Suharev
Member
 
Регистрация: 23.02.2013
Сообщений: 1,353
Сказал(а) спасибо: 4
Поблагодарили 5 раз(а) в 2 сообщениях
Репутация: 5285
По умолчанию Нужна подсказка по программе к ШИМ для 2 серво. Язык С, ATtiny13A

Перейдем от болтовни к реальном примерам. Есть ATtiny13A, есть две сервы HXT900, есть пример использования ШИМ в тиньке. Исходя из этого написал следующее:

Код:
#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
Suharev вне форума   Ответить с цитированием

Старый 28.02.2013, 16:20
Helpmaster
Member
 
Аватар для Helpmaster
 
Регистрация: 08.03.2016
Сообщений: 0

Аналогичные проблемы уже обсуждались ранее

Очень нужна подсказка по блоку питания
Рекурсия, язык с++
Язык программирования F#
Функции, язык Си

Старый 28.02.2013, 16:32   #2 (permalink)
Suharev
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
            }
        }  

        } // закрывающая скобка бесконечного цикла

   } // закрывающая скобка основной программы
По сути осталось просчитать tmax, tmin, и усредненное состояние.

Последний раз редактировалось Suharev; 28.02.2013 в 16:42
Suharev вне форума   Ответить с цитированием
Старый 28.02.2013, 19:59   #3 (permalink)
korsaj
Member
 
Регистрация: 13.05.2011
Сообщений: 401
Сказал(а) спасибо: 0
Поблагодарили 0 раз(а) в 0 сообщениях
Репутация: 274
По умолчанию

Еще надо t инициализировать.
korsaj вне форума   Ответить с цитированием
Старый 28.02.2013, 22:27   #4 (permalink)
Suharev
Member
 
Регистрация: 23.02.2013
Сообщений: 1,353
Сказал(а) спасибо: 4
Поблагодарили 5 раз(а) в 2 сообщениях
Репутация: 5285
По умолчанию

Цитата:
Сообщение от korsaj Посмотреть сообщение
Еще надо t инициализировать.
Вопрос то не в этом, мне нужно чтоб кто-нибудь знающий объяснил на пальцах как делаются расчеты для этих переменных.
Suharev вне форума   Ответить с цитированием
Старый 03.03.2013, 04:18   #5 (permalink)
Suharev
Member
 
Регистрация: 23.02.2013
Сообщений: 1,353
Сказал(а) спасибо: 4
Поблагодарили 5 раз(а) в 2 сообщениях
Репутация: 5285
По умолчанию

Опыты дали на выходе хрень и один сожженный серво.
Попытки разобраться в расчетах опять завели меня в тупик, так как нихрена не ясно что откуда берется.
Ответом так никто и не удосужился. Одно из двух, либо никто сам ничего не знает и не понимает и пользуется чужими наработками, либо птицы слишком высокого полета.

Будьте так любезны приземлиться и объяснить как нужно рассчитывать программный ШИМ, что откуда брать и как это калькулировать, например тот же Fast PWM, либо прикройте тему.
Suharev вне форума   Ответить с цитированием
Ads

Яндекс

Member
 
Регистрация: 31.10.2006
Сообщений: 40200
Записей в дневнике: 0
Сказал(а) спасибо: 0
Поблагодарили 0 раз(а) в 0 сообщениях
Репутация: 55070
Старый 03.03.2013, 20:11   #6 (permalink)
korsaj
Member
 
Регистрация: 13.05.2011
Сообщений: 401
Сказал(а) спасибо: 0
Поблагодарили 0 раз(а) в 0 сообщениях
Репутация: 274
По умолчанию

Вопрос задан не корректно, непонятно что вам объяснять, с чего начинать, как глубоки ваши познания в данном вопросе. Именно по этому и на радиокоте вам никто и не ответил.

Исходя из вопроса ваши познания практически равны 0. Сожженный сервак тому подтверждение. Я не представляю как его можно спалить даже подав на него постоянку он должен работать без каких либо проблем. И неужели вместо сервака нельзя было подключить лампочку и шимить ее.

Даже в даташите на мк, довольно подробно описан режим работы шима.

"Рассчитать задержку" - непонятно о чем вы?
korsaj вне форума   Ответить с цитированием
Старый 03.03.2013, 21:17   #7 (permalink)
Suharev
Member
 
Регистрация: 23.02.2013
Сообщений: 1,353
Сказал(а) спасибо: 4
Поблагодарили 5 раз(а) в 2 сообщениях
Репутация: 5285
По умолчанию

Цитата:
Сообщение от korsaj Посмотреть сообщение
как глубоки ваши познания в данном вопросе
Если бы были я бы не спрашивал, а значит ноль.
Цитата:
Сообщение от korsaj Посмотреть сообщение
И неужели вместо сервака нельзя было подключить лампочку и шимить ее.
Нет, серв не жалко, а мне нужно видеть наглядно угол отклонения, методом подбора цифр смог добиться +-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
Suharev вне форума   Ответить с цитированием
Старый 04.03.2013, 00:16   #8 (permalink)
korsaj
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Гц.
Обоснуйте выбор тактовой.
И обновлять компараторы лучше в прерывании.
korsaj вне форума   Ответить с цитированием
Старый 04.03.2013, 00:49   #9 (permalink)
korsaj
Member
 
Регистрация: 13.05.2011
Сообщений: 401
Сказал(а) спасибо: 0
Поблагодарили 0 раз(а) в 0 сообщениях
Репутация: 274
По умолчанию

Не нашел описание вашего сервы, но наше подобный. Понял откуда тактовая. Вобщем сформировать такую частоту можно только программным ШИМом (или ставит внешний генератор/кварц). Можно запустить таймер допустим с прерываниями каждые 0,1мС, а уже в обработчике, сравнивая счетчик прерываний (доп. переменная) и переменную длинны импульса, выводить в порт лог 1 или 0.
korsaj вне форума   Ответить с цитированием
Старый 04.03.2013, 09:03   #10 (permalink)
Suharev
Member
 
Регистрация: 23.02.2013
Сообщений: 1,353
Сказал(а) спасибо: 4
Поблагодарили 5 раз(а) в 2 сообщениях
Репутация: 5285
По умолчанию

Цитата:
Сообщение от korsaj Посмотреть сообщение
0,8мс: 1/73=0,0137С - период ШИМ, 0,0137/0,0008=256/Х => X=15 - число записанное в компаратор .
Т.е. все расчеты нужно вести в секундах.

Цитата:
Сообщение от korsaj Посмотреть сообщение
Если использовать железный ШИМ, то само ближе к вашей частоте вы получите 73.242Гц (тактовая 4,8МГц, делитель 256) или 36Гц (тактовая 9,6МГц, делитель 1024).
А эти цифры откуда взяты?

Цитата:
Сообщение от korsaj Посмотреть сообщение
уже в обработчике, сравнивая счетчик прерываний (доп. переменная) и переменную длинны импульса,
Но тогда получается нужно будет поправку на выполняемые такты основной программы, иначе импульс просто "поведет".
Suharev вне форума   Ответить с цитированием
Ads

Яндекс

Member
 
Регистрация: 31.10.2006
Сообщений: 40200
Записей в дневнике: 0
Сказал(а) спасибо: 0
Поблагодарили 0 раз(а) в 0 сообщениях
Репутация: 55070
Ответ


Ваши права в разделе
Вы не можете создавать новые темы
Вы не можете отвечать в темах
Вы не можете прикреплять вложения
Вы не можете редактировать свои сообщения

BB коды Вкл.
Смайлы Вкл.
[IMG] код Выкл.
HTML код Выкл.
Trackbacks are Вкл.
Pingbacks are Вкл.
Refbacks are Выкл.




Часовой пояс GMT +4, время: 05:28.

Powered by vBulletin® Version 6.2.5.
Copyright ©2000 - 2014, Jelsoft Enterprises Ltd.