roboforum.ru

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


STM32F4 + MG995 = как подобрать ШИМ?

ARM7, ARM9, ARM11 etc.

Re: STM32F4 + MG995 = как подобрать ШИМ?

Сообщение dccharacter » 05 мар 2013, 19:45

Жди неделю или ветку перечитывай до просветления. Представляй себе робинзона, делающего зарубки на столбе. Как часто он делает зарубки, откуда он знает, что пора зарубку сделать, на сколько зарубок столба хватит, что будет, когда столб кончится
Мой волшебник это я сам. Всю архитектуру программы придумал лично, а ребята помогли воплотить её. Я бы и сам мог написать, но лень учить язык и его конструкции.
Аватара пользователя
dccharacter
 
Сообщения: 4995
Зарегистрирован: 10 дек 2010, 13:16
Откуда: Красногорск МО
прог. языки: C, Python, wiring/processing
ФИО: Андрей

Re: STM32F4 + MG995 = как подобрать ШИМ?

Сообщение Angel71 » 05 мар 2013, 20:41

сервоконтроллеру не имеет значения, к чему его подключают - плате с мегой, армом, компу или планшету. в этом ещё один плюс - начинаешь делать на компе, а допиливать можно на платке.
делал ssc32, хотя если бы сейчас делал, то наверно за основу взял бы местный or. в этот OR-AVR-M128-S вообще спокойно весь нужный код простенького хекса влезет. а что из покупного кроме or есть, понятия не имею.
Аватара пользователя
Angel71
 
Сообщения: 10598
Зарегистрирован: 18 апр 2009, 22:18
Предупреждения: -1

Re: STM32F4 + MG995 = как подобрать ШИМ?

Сообщение Askar » 07 мар 2013, 22:11

dccharacter
В общем я понял что значит этот пределитель и т. п.
Пределитель нужен в первую очередь для подстройки частоты таймера, что бы его заставить тикать в секунду в зависимости от этого предлителя.
На данный момент я сижу на таймере 4, который шарашет с частотой 84Mhz, т. е.
84000000 тиков в секунду. Я делю эти миллионы на 84000, тем самым говорю таймеру увеличевать свое значение каждую миллисекунду. Что бы не отлавливать пока таймер до тикает до 1000, я указываю в параметр период равным 1000, когда счетчик дотикает до 1000 (т.е. в секунду) у меня срабатывает прерывания, где и загорается деод.
Таким образом я заставил гореть деод раз в секунду.

Но как я правильно все рассказал? Если верить описанию, то я вроде правильно все понял.

А что дальше? Без осциллографа мне проблематично. Единственное надежда эта теория!

Angel71
У Нас в Алмате проблема с такими платами, можешь подсказать с eBay-я?



Нашел вот такую программку
http://www.st.com/st-web-ui/static/acti ... m32091.zip
И Описание к ней
http://www.st.com/st-web-ui/static/acti ... 039457.pdf
Главное в жизни человека моего склада заключается в том, что он думает и как думает, а не в том, что он делает или испытывает.
(с) Альберт Эйнштейн
Аватара пользователя
Askar
 
Сообщения: 92
Зарегистрирован: 31 янв 2013, 21:17

Re: STM32F4 + MG995 = как подобрать ШИМ?

Сообщение dccharacter » 08 мар 2013, 08:20

Вроде все правильно ты понял
меня только смущает число 84000. Это ты в теории или в программе так делаешь? Потому что если в программе, то странно, что у тебя все работает, потому что прескейлер вроде как 16-ти битный. А значит не может быть больше 65535. Пойду посмотрю...

Добавлено спустя 10 минут 10 секунд:
http://www.st.com/st-web-ui/static/acti ... 031020.pdf
стр 422

16-bit programmable prescaler used to divide (also “on the fly”) the counter clock
frequency by any factor between 1 and 65536

Добавлено спустя 1 час 40 минут 55 секунд:
Код: Выделить всёРазвернуть
#include <stdio.h>
#include <stm32f4xx.h>
#include <stm32f4xx_gpio.h>
#include <stm32f4xx_rcc.h>
#include <stm32f4xx_tim.h>

#include <stm32f4xx_exti.h>
#include <misc.h>
#include <stm32f4xx_syscfg.h>


//__IO uint16_t SERVO_0 = 1000;      // 1000 us = 1 ms
//__IO uint16_t SERVO_180 = 2000;      // 2000 us = 2 ms
#define SERVO_180 3*2200l
#define SERVO_0 3*800l

// Функция устанавливает позицию вала (в градусах)
void set_pos(uint8_t pos)
{
  uint16_t tmp= (uint16_t)((SERVO_180 - SERVO_0) * pos / 180l) ;
  uint16_t ServoPulse = SERVO_0 + tmp;
  TIM_SetCompare1(TIM4, ServoPulse );
}

// Функция задержки
void delay(void)
{
  volatile uint32_t i;
  for (i=1; i != 0xFFFF; i++)
    ;
}


int main(void)
{
  SystemInit();

  // Инициализация портов вводов/вывода
  RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOD, ENABLE);
  GPIO_InitTypeDef GPIO_InitStructure;
  GPIO_StructInit(&GPIO_InitStructure);
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12; // Ножка PD12
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
  GPIO_Init(GPIOD, &GPIO_InitStructure);


  //------------------------------------------------------------------------------------------
  // Инициализируем таймер 4
  RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM4, ENABLE);

#define sPeriod 20000l //20ms = 20000 us
#define tClock (SystemCoreClock/8) //21MHz
#define maxCount 60000l

  uint16_t Prescaler =  8; // PCLK1 = 168MHz/8 ~= 21MHz
  uint16_t Period = 60000; // 20000; // 20 ms

  TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
  TIM_TimeBaseStructInit (&TIM_TimeBaseStructure);
  TIM_TimeBaseStructure.TIM_ClockDivision = 0;
  TIM_TimeBaseStructure.TIM_RepetitionCounter = 0;
  TIM_TimeBaseStructure.TIM_Prescaler = Prescaler;
  TIM_TimeBaseStructure.TIM_Period = Period;
  TIM_TimeBaseInit(TIM4, &TIM_TimeBaseStructure);

  // Разрешаем таймеру обращаться к выходу PD12
  GPIO_PinAFConfig(GPIOD, GPIO_PinSource12, GPIO_AF_TIM4);
  //------------------------------------------------------------------------------------------
  // Инициализируем ШИМ
  TIM_OCInitTypeDef TIM_OCInitStructure;
  TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;
  TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
  TIM_OCInitStructure.TIM_Pulse = 20000;
  TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;
  TIM_OC1Init(TIM4, &TIM_OCInitStructure);
  TIM_Cmd(TIM4, ENABLE);



  //delay();
  //TIM_SetCompare1(TIM4, 460); // 90
  //delay();
  //TIM_SetCompare1(TIM4, 760 ); // 180



  //Начинаем крутить сервой от 0 до 180 градусов.

  uint8_t i;
  while(1)
  {
    for (i=0;i<=180;i++)
    {
      delay();
      set_pos(i);
    }
    for (i=180;i>0;i--)
    {
      delay();
      set_pos(i);
    }
  }
}

Серва крутится туда-сюда, импульс меняется от 800 до 2200 мкс.
Единственная ошибка в моих объяснениях была в том, что к рассчетному прескейлеру надо единицу добавлять. Чо-то спросоня не пойму почему, но с единицей тайминги правильные.

Камень работает на 168МГц
Таймер на частоте PCLK1, т.е. 168/8 = 21МГц
С прескейлером 8 получается частота 3МГц.
Поэтому SERVO0 и SERVO180 = это утроенное количество микросекунд, т.е. 3*800 и 3*2200
Мой волшебник это я сам. Всю архитектуру программы придумал лично, а ребята помогли воплотить её. Я бы и сам мог написать, но лень учить язык и его конструкции.
Аватара пользователя
dccharacter
 
Сообщения: 4995
Зарегистрирован: 10 дек 2010, 13:16
Откуда: Красногорск МО
прог. языки: C, Python, wiring/processing
ФИО: Андрей

Re: STM32F4 + MG995 = как подобрать ШИМ?

Сообщение Askar » 08 мар 2013, 09:01

Вот код который работает... один раз моргает в секунду деод.
Странно почему у тебя на таймере 4, камень шарашет на 168Mhz? У меня на 84MHz
Может настройки мне поменять где то?
В даташите на странице 104 указано, что шина 1 работает на частоте 84Mhz, и таймеры перечислены... TIM2,TIM3,TIM4,TIM5,...


Код: Выделить всёРазвернуть
#include <stm32f4xx.h>
#include <stm32f4xx_gpio.h>
#include <stm32f4xx_rcc.h>
#include <stm32f4xx_tim.h>

//#include <stm32f4xx_exti.h>
#include <misc.h>
//#include <stm32f4xx_syscfg.h>

#undef HSE_VALUE
#define HSE_VALUE    ((uint32_t)8000000)

__IO uint16_t SERVO_0 = 570;      // 1000 us = 1 ms 570
__IO uint16_t SERVO_90 = 1000;      // 1000 us = 1 ms 1140
__IO uint16_t SERVO_180 = 2000;      // 2000 us = 2 ms
//#define SERVO_180 1200
//#define SERVO_0 200


// Функция устанавливает позицию вала (в градусах)
void set_pos(uint8_t pos)
{
  uint32_t tmp=(SERVO_180 - SERVO_0) / 180 ;
  uint16_t ServoPulse = SERVO_0 + tmp * pos;
  TIM_SetCompare1(TIM1, ServoPulse );
  //TIM2->CCR2 = SERVO_0 + tmp * pos;
}

// Функция задержки
void delay(void)
{
  volatile uint32_t i;
  for (i=1; i != 0xFFFF; i++)
    ;
}

void delayMS(uint32_t ms)
{
    ms *= 3360;
    while(ms--) {  __NOP(); }
}

int main(void)
{
  SystemInit();

  // Инициализация портов вводов/вывода
  RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOD, ENABLE);
  GPIO_InitTypeDef GPIO_InitStructure;
  GPIO_StructInit(&GPIO_InitStructure);
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12; // Ножка PD12
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
  GPIO_Init(GPIOD, &GPIO_InitStructure);


  //------------------------------------------------------------------------------------------
  // Инициализируем таймер 4
  RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM4, ENABLE);

  uint16_t Prescaler =  ( (SystemCoreClock / 2) / 1000000) - 1; // 1hz
  uint16_t Period = 20000; // 20000; // 20 ms

  TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
  TIM_TimeBaseStructInit (&TIM_TimeBaseStructure);
  //TIM_TimeBaseStructure.TIM_Prescaler = Prescaler;
  //TIM_TimeBaseStructure.TIM_Period = Period;
  TIM_TimeBaseStructure.TIM_Prescaler = 84000 -1;
  TIM_TimeBaseStructure.TIM_Period = 1000;
  TIM_TimeBaseInit(TIM4, &TIM_TimeBaseStructure);

  // Разрешаем таймеру обращаться к выходу PD12
  GPIO_PinAFConfig(GPIOD, GPIO_PinSource12, GPIO_AF_TIM4);
  //------------------------------------------------------------------------------------------
  // Инициализируем ШИМ
  TIM_OCInitTypeDef TIM_OCInitStructure;
  TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;
  TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
//  TIM_OCInitStructure.TIM_Pulse = 0;
//490 + ((1000-490) / 90) * 45; // 0=490, 45=690, 90=940
//200 + ((1140-200) / 180) * 90; // 200=0,
  TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;
  TIM_OC1Init(TIM4, &TIM_OCInitStructure);

  TIM_ITConfig(TIM4, TIM_IT_Update | TIM_IT_CC1, ENABLE);

  TIM_Cmd(TIM4, ENABLE);

  NVIC_EnableIRQ(TIM4_IRQn);

  //delayMS(20);
  //TIM_SetCompare1(TIM4, 1000); // 90
  //delayMS(20);
  //TIM_SetCompare1(TIM4, 1500); // 90
  //delayMS(20);
  //TIM_SetCompare1(TIM4, SERVO_180 ); // 180
  //delayMS(20);


   while (1);
}





volatile uint8_t servo_angle = 0;

void TIM4_IRQHandler(void)
{
     /* Если счётчик переполнился, можно смело закидывать
        в регистр сравнения новое значение. */
     if (TIM_GetITStatus(TIM4, TIM_IT_Update) != RESET)
     {
       TIM_ClearITPendingBit(TIM4, TIM_IT_Update);
       TIM_SetCompare1(TIM4, 500);
     }
}
Главное в жизни человека моего склада заключается в том, что он думает и как думает, а не в том, что он делает или испытывает.
(с) Альберт Эйнштейн
Аватара пользователя
Askar
 
Сообщения: 92
Зарегистрирован: 31 янв 2013, 21:17

Re: STM32F4 + MG995 = как подобрать ШИМ?

Сообщение dccharacter » 08 мар 2013, 10:24

Возьми мой код сначала и попробуй

Добавлено спустя 21 минуту 58 секунд:
Клоки задаются функцией SetSysClock(void)
Это в файле system_stm32f4xx.c (библиотека CMSIS)

Вот регистры:
/* HCLK = SYSCLK / 1*/
RCC->CFGR |= RCC_CFGR_HPRE_DIV1;

/* PCLK2 = HCLK / 2*/
RCC->CFGR |= RCC_CFGR_PPRE2_DIV2;

/* PCLK1 = HCLK / 4*/
RCC->CFGR |= RCC_CFGR_PPRE1_DIV4;

Что странно, потому что таймеры сидят на PCLK1, дивайдер 4, т.е. должно быть 42МHz: 168/4
Т.е. еще где-то сидит дивайдер 1/2
Пока не нашел его

Добавлено спустя 2 минуты 3 секунды:
http://www.st.com/web/en/catalog/tools/PF257927
STSW-STM32091 Clock configuration tool for STM32F40x/41x microcontrollers

Добавлено спустя 14 минут 17 секунд:
Картинка называется "взорви себе мозг"
Вложения
STM32F4clocks.png
STM32F4clocks.png (16.27 КиБ) Просмотров: 1730
Мой волшебник это я сам. Всю архитектуру программы придумал лично, а ребята помогли воплотить её. Я бы и сам мог написать, но лень учить язык и его конструкции.
Аватара пользователя
dccharacter
 
Сообщения: 4995
Зарегистрирован: 10 дек 2010, 13:16
Откуда: Красногорск МО
прог. языки: C, Python, wiring/processing
ФИО: Андрей

Re: STM32F4 + MG995 = как подобрать ШИМ?

Сообщение Askar » 08 мар 2013, 11:09

Страно но твой код постоянно возвращает ошибку
все закоментировал, компилиться нормально. Иначе нет.

[cc]
[cc] collect2.exe: error: ld returned 1 exit status
BUILD FAILED
Главное в жизни человека моего склада заключается в том, что он думает и как думает, а не в том, что он делает или испытывает.
(с) Альберт Эйнштейн
Аватара пользователя
Askar
 
Сообщения: 92
Зарегистрирован: 31 янв 2013, 21:17

Re: STM32F4 + MG995 = как подобрать ШИМ?

Сообщение dccharacter » 08 мар 2013, 11:20

Мой код - это модификация трех строчек твоего кода. Посмотри, что изменилось, поправь у себя, и вперед.
Мой волшебник это я сам. Всю архитектуру программы придумал лично, а ребята помогли воплотить её. Я бы и сам мог написать, но лень учить язык и его конструкции.
Аватара пользователя
dccharacter
 
Сообщения: 4995
Зарегистрирован: 10 дек 2010, 13:16
Откуда: Красногорск МО
прог. языки: C, Python, wiring/processing
ФИО: Андрей

Re: STM32F4 + MG995 = как подобрать ШИМ?

Сообщение Askar » 08 мар 2013, 11:26

Обновил проект, вроде все заработало
Решение проблемы здесь
http://forum.easyelectronics.ru/viewtop ... 35&t=11896
Главное в жизни человека моего склада заключается в том, что он думает и как думает, а не в том, что он делает или испытывает.
(с) Альберт Эйнштейн
Аватара пользователя
Askar
 
Сообщения: 92
Зарегистрирован: 31 янв 2013, 21:17

Re: STM32F4 + MG995 = как подобрать ШИМ?

Сообщение dccharacter » 08 мар 2013, 11:27

Ну а что "все"-то заработало? Серва крутится?
Мой волшебник это я сам. Всю архитектуру программы придумал лично, а ребята помогли воплотить её. Я бы и сам мог написать, но лень учить язык и его конструкции.
Аватара пользователя
dccharacter
 
Сообщения: 4995
Зарегистрирован: 10 дек 2010, 13:16
Откуда: Красногорск МО
прог. языки: C, Python, wiring/processing
ФИО: Андрей

Re: STM32F4 + MG995 = как подобрать ШИМ?

Сообщение Askar » 08 мар 2013, 11:41

Работает классно, но крутится только на 100 градусов
Хотя серва позволяет крутится от ~-30 до 200 градусов
А как эти сервы калибрировать?

Добавлено спустя 11 минут 5 секунд:
Взял вот такой тестер
http://rcshop.kz/product/2996/
Но крутит только на 90 градусов. Думаю им калибрировать.
Главное в жизни человека моего склада заключается в том, что он думает и как думает, а не в том, что он делает или испытывает.
(с) Альберт Эйнштейн
Аватара пользователя
Askar
 
Сообщения: 92
Зарегистрирован: 31 янв 2013, 21:17

Re: STM32F4 + MG995 = как подобрать ШИМ?

Сообщение dccharacter » 08 мар 2013, 12:00

Ну ты можешь поиграться с таймингами, т.е. с 800 и с 2200. Меняй только потихоньку, не давай серве в клин на краю уходить. МГ мож и выдержит, а маленькая пластмассовая серва порвется мгновенно, не успеешь даже напругу с нее снять.
Калибровку можно делать по транспартиру, не нужен для этого тестер за 810 таньге :-))))
Мой волшебник это я сам. Всю архитектуру программы придумал лично, а ребята помогли воплотить её. Я бы и сам мог написать, но лень учить язык и его конструкции.
Аватара пользователя
dccharacter
 
Сообщения: 4995
Зарегистрирован: 10 дек 2010, 13:16
Откуда: Красногорск МО
прог. языки: C, Python, wiring/processing
ФИО: Андрей

Re: STM32F4 + MG995 = как подобрать ШИМ?

Сообщение Askar » 08 мар 2013, 12:06

Неее я не про это, я вот использую этот серво тестер, он крутит с 30 если регулировку поставить на 0. Но до левого края ещё есть 30 градусов. Вот как это понимать?

Конечно тебе отдельное спасибо! Конечно мне нужно ещё подумать над твоими изменениями.
Главное в жизни человека моего склада заключается в том, что он думает и как думает, а не в том, что он делает или испытывает.
(с) Альберт Эйнштейн
Аватара пользователя
Askar
 
Сообщения: 92
Зарегистрирован: 31 янв 2013, 21:17

Re: STM32F4 + MG995 = как подобрать ШИМ?

Сообщение Duhas » 08 мар 2013, 16:39

свободный ход сервы обычно больше управляемого хода.
«Как сердцу выразить себя? … Мысль изреченная есть ложь!»
В этом мире меня подводит доброта и порядочность...
"двое смотрят в лужу, один видит лужу, другой отраженные в ней звезды"
Аватара пользователя
Duhas
 
Сообщения: 6338
Зарегистрирован: 15 сен 2007, 13:03
Откуда: Красноярск
прог. языки: ASM(МК), C(PC)
ФИО: Гагарский Андрей Александрович

Re: STM32F4 + MG995 = как подобрать ШИМ?

Сообщение Askar » 08 мар 2013, 17:02

Я так понимаю под каждую серву придется отдельно ввести подачу импульсов?
Главное в жизни человека моего склада заключается в том, что он думает и как думает, а не в том, что он делает или испытывает.
(с) Альберт Эйнштейн
Аватара пользователя
Askar
 
Сообщения: 92
Зарегистрирован: 31 янв 2013, 21:17

Пред.След.

Вернуться в ARM

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 3

Mail.ru counter