Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: ШИМ для сервомашинки на attiny13
Форум разработчиков электроники ELECTRONIX.ru > Сайт и форум > В помощь начинающему > MCS51, AVR, PIC, STM8, 8bit
evgenui
Здравствуйте, при выполнении дипломной работы(макет комнаты) столкнулся с проблемой создания ШИМ для управления сервомашинкой. Имею в наличии МК attiny13. пробывал программировать сам не вышло. в связи с этим прошу помощи в програмировании. Нажмите для просмотра прикрепленного файла
работать должно так при нажатии кнопки на серво должены постоянно поступать импульсы в 1 мс с интервалом в 20мс. при размыкании кнопки импульсы в 2 мс. с интервалом в 20мс.
писать нужно на си или ассемблере. заранее благодарю.
kovigor
Цитата(evgenui @ May 24 2013, 17:05) *
работать должно так при нажатии кнопки на серво должены постоянно поступать импульсы в 1 мс с интервалом в 20мс. при размыкании кнопки импульсы в 2 мс. с интервалом в 20мс.

Вот, проще не придумаете:
Код
while (1){
if (!PINB.0){ //Button pressed
  PORTB.1 = 1;
  delay_ms(1);
  PORTB.1 = 0;
  delay_ms(19);
             }
else{ //Button released
  PORTB.1 = 1;
  delay_ms(2);
  PORTB.1 = 0;
  delay_ms(18);
      }
          };

http://zalil.ru/34528816

Компилятор - CodeVision ...

P.S. Схема подключения кнопки у вас просто страшная ...
evgenui
Цитата(kovigor @ May 24 2013, 17:46) *
Вот, проще не придумаете:

http://zalil.ru/34528816

Компилятор - CodeVision ...

P.S. Схема подключения кнопки у вас просто страшная ...


спасибо, а инициализацию , настройку портов и подключение необходимых библитек не напишите, а то не по моей специальности вопрос((?

спасибо, это я писал сам(почти так но с помощью счетчика задержки ), у меня проблема в другом, как я понял, настройка портов и инициализация.
а подключение кнопки на самом деле не такое вместо кнопки я беру сигнал с контроллера фирмы johnsons control, ну и питание не кое конечно, это так для наглядности и симуляции.
если поможете в остальном буду очень признателен


спасибо, это я писал сам(почти так но с помощью счетчика задержки ), у меня проблема в другом, как я понял, настройка портов и инициализация.
а подключение кнопки на самом деле не такое вместо кнопки я беру сигнал с контроллера фирмы johnsons control, ну и питание не кое конечно, это так для наглядности и симуляции.
если поможете в остальном буду очень признателен


глюк какой то 1-м сообщением 1 раз отправил не в той последовательности)))
kovigor
Цитата(evgenui @ May 24 2013, 18:55) *
спасибо, это я писал сам(почти так но с помощью счетчика задержки ), у меня проблема в другом, как я понял, настройка портов и инициализация.

Так я ведь полный проект для CodeVision приложил, там и инициализация есть ...
badik
ШИМ это много проще. Делаете в начале инициализацию к примеру Timer 1.

DDRD= 0xFF; // ПОРТ D как выход, выход Timer 1.
PORTD= 0x00;
ICR1= <20мс>;
Timer1_INIT(); // PWM

и сама прога

while (1){
if (!PINB.0) OCR1A = <1мс>;
//Button pressed
else OCR1A = <2мс>;
//Button released
}

<20мс>, ... это константы, зависят от тактовой частоты.
Можно инициализацию Timer взять готовую, интернет завален.
Так делать лучше, меньше грузить проц.
evgenui
спасибо большое!!! щас попробую
badik
Прошу извинить про ШИМ.
ATtiny13 имеет только Timer 0. Сверх компактный.
Но по работе все так же.
ПРИ инициализации PORTD заменить на PORTB, выход Timer 0 - PB0.
В работе OCR1A на OC0A.
evgenui
доброго времени суток, помогите еще раз, задача все таже, но серва быстрая слишком, не может кто-нибудь изменить исходный код(который мне собственно написал kovigor,спасибо ему)так, чтобы при нажатии и отжатии кнопки импульсы изменялись плавно(за 3-5 сек).
http://zalil.ru/34528816
kovigor
Цитата(evgenui @ May 29 2013, 13:06) *
не может кто-нибудь изменить исходный код(который мне собственно написал kovigor,спасибо ему)

Сейчас попробую ...

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

Я не понимаю задачи. Допустим, кнопка была нажата и на машинку шли импульсы длительностью в 1 мС. Затем кнопку отпустили, но длительность импульса (при той же частоте следования импульсов) должна возрасти до 2-х мС не скачком, а плавно. Так ?
evgenui
условно говоря так чтобы сигнал изменялся и процесс изменения чтобы занял 3 сек или 5
http://www.fayloobmennik.net/2893724
kovigor
Цитата(evgenui @ May 29 2013, 14:09) *
условно говоря так чтобы сигнал изменялся и процесс изменения чтобы занял 3 сек или 5

Понял, сейчас подумаю ...
Как остановить машинку ? Как запустить ее в ход ? Или остановка не предусмотрена (включили прибор, и она сразу вертится, причем скорость верчения зависит от того, нажата или не нажата кнопка, и меняется только по нажатию/отпусканию) ? Поверьте, я не экстрасенс ...
evgenui
запускать не нужно, нужно выполнение вышеперечисленых условий:
1) работает сразу, включать не нужно
2) кнопка нажата- импульсы 2 мс, не нажата 1 мс.
3) при нажатии на кнопку, или ее отжатии импульс от 1 до 2-х мс (и в обратном порядке) изменялся постепенно( удлинялся или сокращался, в зависимости от того нажата кнопка или нет) в течении 3-5с. примерно как на моем рисунке
kovigor
Цитата(evgenui @ May 29 2013, 14:46) *
запускать не нужно ...

Понял ...
evgenui
т.е требуется замедлить процесс поворота сервы. а для этого необходимо плавное нарастание длинны импульса, или его плавное сокращение
kovigor
Цитата(evgenui @ May 29 2013, 14:50) *
т.е требуется замедлить процесс поворота сервы. а для этого необходимо плавное нарастание длинны импульса, или его плавное сокращение

Пробуйте:
http://zalil.ru/34540707

Не забудьте сообщить о результате, мне интересно ...
evgenui
не работает, поворачивается в одно положение только. вот такой выход нашли:
while (1){
if (!PINB.0){ //Кнопка нажата

if (delay>1000) delay-=10;
PORTB.1 = 1;
delay_us(delay);
PORTB.1 = 0;
delay_us(20000-delay);
}
else{ //Кнопка отпущена
if (delay<2000) delay+=10;
PORTB.1 = 1;
delay_ms(delay);
PORTB.1 = 0;
delay_ms(20000-delay);
}
};
}
kovigor
Цитата(evgenui @ May 29 2013, 16:47) *
поворачивается в одно положение только

Ни о каких "положениях" вы до этого не писали. Для меня это просто мотор, который просто вертится с разной скоростью, в зависимости от того, нажата кнопка или нет. Короче, без предоставления с вашей стороны подробного описания макета я вас больше консультировать не берусь, ибо не умею (и не хочу) читать мысли ...
evgenui
спасибо, промаделировал все нормально спаял схему, прошили мне МК. подключаю, не пашет. просто 1 выдает и не реагирует, в чем может быть дело? настройки при заливки не верны не верны ? если так то не мог бы подсказать фьюзы как правильно настроить?
скинул фото схемки, фаил с протеуса, и вот то что в мк залили


#include <tiny13.h>
#include <delay.h>

// Declare your global variables here

void main(void)
{
// Declare your local variables here

// Crystal Oscillator division factor: 1
#pragma optsize-
CLKPR=0x80;
CLKPR=0x00;
#ifdef _OPTIMIZE_SIZE_
#pragma optsize+
#endif

// Input/Output Ports initialization
// Port B initialization
// Func5=Out Func4=Out Func3=Out Func2=Out Func1=Out Func0=In
// State5=0 State4=0 State3=0 State2=0 State1=0 State0=P
PORTB=0x01;
DDRB=0x3E;

// Timer/Counter 0 initialization
// Clock source: System Clock
// Clock value: Timer 0 Stopped
// Mode: Normal top=FFh
// OC0A output: Disconnected
// OC0B output: Disconnected
TCCR0A=0x00;
TCCR0B=0x00;
TCNT0=0x00;
OCR0A=0x00;
OCR0B=0x00;

// External Interrupt(s) initialization
// INT0: Off
// Interrupt on any change on pins PCINT0-5: Off
GIMSK=0x00;
MCUCR=0x00;

// Timer/Counter 0 Interrupt(s) initialization
TIMSK0=0x00;

// Analog Comparator initialization
// Analog Comparator: Off
ACSR=0x80;
ADCSRB=0x00;

int delay=1500;

while (1){
if (!PINB.0){ //Кнопка нажата

if (delay>1000) delay-=10;
PORTB.1 = 1;
delay_us(delay);
PORTB.1 = 0;
delay_us(20000-delay);
}
else{ //Кнопка отпущена
if (delay<2000) delay+=10;
PORTB.1 = 1;
delay_ms(delay);
PORTB.1 = 0;
delay_ms(20000-delay);
}
};
}

http://www.fayloobmennik.net/2901046
kovigor
Цитата(evgenui @ May 31 2013, 19:33) *
если так то не мог бы подсказать фьюзы как правильно настроить?

А мне расхотелось вам помогать, простите. Вы, мало того что ввели меня в заблуждение, так еще и не хотите элементарно открыть даташит на МК и разобраться с фьюзами. А такой подход к работе лично на меня действует, как красная тряпка на быка ...
Вообще, задача ваша - из разряда простейших. Вместо того, чтобы писать вопросы в форум, вы бы уже тысячу раз переписали бы не подошедший вам мой проект или написали бы свой. Но вы ленитесь. А посему помогать вам у меня нет ни малейшего желания ...
Xenia
Скажите, какую частоту надо заказывать PWM для шагового дивигателя? С программированием мне всё ясно, но непонятно, из каких соображений выбирать частоту.

Метод тыка показывает, что на самой медленной частоте (31 Гц), на которую мне хватает делителя, шаговый двигтель крутится, а на 10 КГц стоит, хотя на выходе МК то же самое среднее напряжение (если мерить обычным тестером). Видимо частота 10 КГц великовата для драйвера (L293D), а может быть и двигателя. А сколько ему/им надо, про то в даташите не написано.
evgenui
kovigor извините, но я впервые сталкиваюсь с этими вопросами, при самостоятельном изучении не вышло ничего хорошего, а сроки поджимают. Вот и спрашиваю у знающих людей в чем моя ошибка?

Xenia, я собираюсь управлять сервомашинкой, необходимо 2 положения крайнее левое и крайнее правое. для этого на управляющий вывод необходимо подавать импульс 1 или 2 мс. через каждые 20мс. программно выставлены задержки на эти величины, так что думаю что для сервы все равно на какой частоте работает МК.
kovigor
Цитата(evgenui @ Jun 1 2013, 08:39) *
при самостоятельном изучении не вышло ничего хорошего, а сроки поджимают. Вот и спрашиваю у знающих людей в чем моя ошибка?

Конечно, потому и не вышло - вы не учитесь, а пишете сообзщения на форумы. Задача тривиальна, решается за день. Почему у всех "вышло", а у вас - нет ???
Плюс стиль сообщений - сообщения написаны безграмотно, крайне небрежно, по виду их можно судить о полном неуважении к тем, кому они предназначаются. Одно слово "промаделировал" как нельзя лучше говорит о том, сколько книг в своей жизни вы прочли (и не только по специальности). Поверьте, первое же подобное сообщение напрочь отбивает охоту вам помогать. Так что мой вам совет - откройте, наконец, книжку и даташит, выясните, как решается ваша задача, и решите ее сами. Помочь вам я бы мог, но не сделаю этого ради вас же, ибо такая помощь не будет для вас полезной. Учитесь работать самостоятельно ...
Andrikll
Здравствуйте! Нашел эту тему и решил не заводить свою. Задача котторую я хотел решить схожая, но я хотел ее решить непременно в прерываниях для того чтобы был точнее счет...
Подробнее.
Микросхема атмега48, таймер который использую т2 (1байтный) режим таймера нормал (обычный счет без обнуления по достижении ОСР) но при этом я использую прерывание по ОСР0А. Частоту для светодиода задал 976 Гц ОСР2А задаю регулятором (инкрементным энкодером) общая частота 3.8 Гц (976/256=3,81).
В полной программе с функцией обработки энкодера и 2-мя прерываниями, диод помаргивает неравномерно, при этом я ничего не трогаю (энкодер). Для того чтобы понятно было как это выглядит привожу видео. Если делаю программу только прерывания, то никаких помаргиваний, равномерно дрожит своими 3.8 герцами, но "чистая" программа без основной части то мне не нужна! Прошу помощи.
В основной части программы вызов функции изменения reg и отображение значений старших бит (вывод на светодиоды, 5 старших бит). в данном листинге нет присвоения ОСР2А каких либо значений но и в этом случае свечение не равномерное!
На другом форуме задавал этот вопрос, предложили сменить переменную (энкодера) на volatile, немного меньше стали подергивания (или мне показалось) но полностью не решилась проблемма

Код
char serv_num=1, count, old_reg, new_reg;

volatile char reg=0x0f;
  void regul (void)
    {
  if (old_reg==0) {if(new_reg == 2) reg++;  if(new_reg == 1) reg--; }
     }
        interrupt [TIM2_OVF] void timer2_ovf_isr(void)
        {
        PORTB.0 = 1;
         }

// Timer 2 output compare interrupt service routine
interrupt [TIM2_COMPA] void timer2_compa_isr(void)
{
PORTB.0 = 0;  
}

void main(void)
{
// Crystal Oscillator division factor: 1
#pragma optsize-
CLKPR=0x80;
CLKPR=0x00;
#ifdef _OPTIMIZE_SIZE_
#pragma optsize+

#endif

PORTB=0x00;
DDRB=0xFF;

PORTC=0x00;
DDRC=0x00;

PORTD=0xC0;
DDRD=0x3F;

// Timer/Counter 0 initialization
// Clock source: System Clock
// Clock value: 976 Hz
// Mode: normal
// OC0A output: Disconnected
// OC0B output: Disconnected

TCCR0A=0x00;
TCCR0B=0x05;
TCNT0=0x00;
OCR0A=0x00;
OCR0B=0x00;

// Timer/Counter 2 initialization
// Clock source: System Clock
// Clock value: 976 Hz
// Mode: normal
// OC2A output: Disconnected
// OC2B output: Disconnected

ASSR=0x00;
TCCR2A=0x00;
TCCR2B=0x07;
TCNT2=0x00;
OCR2A=0x0f;
OCR2B=0x00;

// External Interrupt(s) initialization
// INT0: Off
// INT1: Off

EICRA=0x00;
EIMSK=0x00;
PCICR=0x00;

// Timer/Counter 0 Interrupt(s) initialization
TIMSK0=0x01;

// Timer/Counter 2 Interrupt(s) initialization
TIMSK2=0x03;

// Global enable interrupts

#asm("sei")

while (1)
      {
     new_reg = 2*!PIND.6+!PIND.7;    
     if (old_reg!=new_reg) regul();
     old_reg=new_reg;  

     PORTB.5 = (reg-reg%128)/128;  
     PORTB.4 = (reg-reg%64)/64;
     PORTB.3 = (reg-reg%32)/32;
     PORTB.2 = (reg-reg%16)/16;
     PORTB.1 = (reg-reg%8)/8;
     OCR2A = reg;

       };
}
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.