roboforum.ru

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

Вопросы по программированию STM32Fxxx

Вопросы по программированию STM32Fxxx

GlassEagle » 11 дек 2012, 00:04

Есть предложение складывать сюда вопросы (и ответы :)) конкретно по программированию для STM32 (F4xx и похожих).

1й (в этой ветке) вопрос - конфигурирую таймеры TIM3 и TIM4 для режима ШИМ (пишу в CooCox-e).
Ну и, в-общем, ШИМ-то идёт, но частота получается раз в ~5 МЕНЬШЕ заявленной (а период, соответственно, больше). Вместо импульса длиной 1,5 мс получается ~8 мс.

Код: Выделить всёРазвернуть
GPIO_InitTypeDef LED,servo;

TIM_TimeBaseInitTypeDef timer3,timer4;
TIM_OCInitTypeDef timer3_oc_init,timer4_oc_init;

  TIM_TimeBaseStructInit(&timer3);  // Инициализация структуры TIM_TimeBaseInitTypeDef
  timer3.TIM_Prescaler=83;  // 1000000 Hz
  timer3.TIM_Period=19999;  // 50 Hz (для серво)
  timer3.TIM_ClockDivision=0;
  timer3.TIM_CounterMode=TIM_CounterMode_Up;
  TIM_TimeBaseInit(TIM3,&timer3);

  TIM_OCStructInit(&timer3_oc_init);  // Инициализация структуры TIM_OCInitTypeDef
  timer3_oc_init.TIM_OCMode = TIM_OCMode_PWM1;   // работаем в режиме ШИМ (PWM)
  timer3_oc_init.TIM_OutputState = TIM_OutputState_Enable;
  timer3_oc_init.TIM_Pulse = 1500;  // Коэф. заполнения?
  timer3_oc_init.TIM_OCPolarity = TIM_OCPolarity_High;  // положительная полярность
  TIM_OC1Init(TIM3,&timer3_oc_init);  /// заносим данные в первый канал
  TIM_OC1PreloadConfig(TIM3,TIM_OCPreload_Enable);

  TIM_ARRPreloadConfig(TIM3,ENABLE);
  TIM_Cmd(TIM3,ENABLE);  // запускаем счёт
  TIM_CtrlPWMOutputs(TIM3,ENABLE); //Пуск PWM выходов

Конфигурирование GPIO для ноги, сидящей на TIM3:
  RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA,ENABLE);
  RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3,ENABLE);  // Timer3
  servo.GPIO_Pin=GPIO_Pin_6;
  servo.GPIO_Mode=GPIO_Mode_AF;
  servo.GPIO_OType=GPIO_OType_PP;
  servo.GPIO_Speed=GPIO_Speed_100MHz;
  servo.GPIO_PuPd=GPIO_PuPd_UP;
  GPIO_Init(GPIOA,&servo);
  GPIO_PinAFConfig(GPIOA,GPIO_PinSource6,GPIO_AF_TIM3);

На TIM4 родные (для STM32F4DISCOVERY) светодиоды посажены, штоб моргали раз в секунду - моргают раз в ~5 секунд.
Его настройки:
Код: Выделить всёРазвернуть
  RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOD,ENABLE);
  RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM4,ENABLE);  // Timer4
  LED.GPIO_Pin=GPIO_Pin_12 | GPIO_Pin_13;  // Только два светодиода - зелёный и оранж.
  LED.GPIO_Speed=GPIO_Speed_100MHz;
  LED.GPIO_Mode=GPIO_Mode_AF;
  LED.GPIO_OType=GPIO_OType_PP;
  GPIO_Init(GPIOD,&LED);
  GPIO_PinAFConfig(GPIOD,GPIO_PinSource12,GPIO_AF_TIM4);
  GPIO_PinAFConfig(GPIOD,GPIO_PinSource13,GPIO_AF_TIM4);

  TIM_TimeBaseStructInit(&timer4);  // Инициализация структуры TIM_TimeBaseInitTypeDef
  timer4.TIM_Prescaler=8399;  // 10000 Hz
  timer4.TIM_Period=9999;  // 1 Hz
  timer4.TIM_ClockDivision=0;
  timer4.TIM_CounterMode=TIM_CounterMode_Up;
  TIM_TimeBaseInit(TIM4,&timer4);

  TIM_OCStructInit(&timer4_oc_init);  // Инициализация структуры TIM_OCInitTypeDef
  timer4_oc_init.TIM_OCMode = TIM_OCMode_PWM1;  // работаем в режиме ШИМ
  timer4_oc_init.TIM_OutputState = TIM_OutputState_Enable;
  timer4_oc_init.TIM_Pulse = 5000;  // частота ШИМ??? (Коэф. заполнения?)
  timer4_oc_init.TIM_OCPolarity = TIM_OCPolarity_High;  // положительная полярность
  TIM_OC1Init(TIM4,&timer4_oc_init);  /// заносим данные в первый канал - порт D12
  TIM_OC1PreloadConfig(TIM4,TIM_OCPreload_Enable);

  timer4_oc_init.TIM_Pulse = 2500;
  TIM_OC2Init(TIM4,&timer4_oc_init);
  TIM_OC2PreloadConfig(TIM4,TIM_OCPreload_Enable);

  TIM_ARRPreloadConfig(TIM4,ENABLE);
  TIM_Cmd(TIM4,ENABLE);  // запускаем счёт
  TIM_CtrlPWMOutputs(TIM4,ENABLE); //Пуск PWM выходов

Все настройки взяты из примеров для STM32F4_DISCOVERY, (Demonstration):
Код: Выделить всёРазвернуть
    /* -----------------------------------------------------------------------
    TIM4 Configuration: Output Compare Timing Mode:
   
    In this example TIM4 input clock (TIM4CLK) is set to 2 * APB1 clock (PCLK1),
    since APB1 prescaler is different from 1 (APB1 Prescaler = 4, see system_stm32f4xx.c file).
      TIM4CLK = 2 * PCLK1 
      PCLK1 = HCLK / 4
      => TIM4CLK = 2*(HCLK / 4) = HCLK/2 = SystemCoreClock/2
         
    To get TIM4 counter clock at 2 KHz, the prescaler is computed as follows:
       Prescaler = (TIM4CLK / TIM1 counter clock) - 1
       Prescaler = (168 MHz/(2 * 2 KHz)) - 1 = 41999
                                       
    To get TIM4 output clock at 1 Hz, the period (ARR)) is computed as follows:
       ARR = (TIM4 counter clock / TIM4 output clock) - 1
           = 1999
                   
    TIM4 Channel1 duty cycle = (TIM4_CCR1/ TIM4_ARR)* 100 = 50%
    TIM4 Channel2 duty cycle = (TIM4_CCR2/ TIM4_ARR)* 100 = 50%
    TIM4 Channel3 duty cycle = (TIM4_CCR3/ TIM4_ARR)* 100 = 50%
    TIM4 Channel4 duty cycle = (TIM4_CCR4/ TIM4_ARR)* 100 = 50%
   
    ==> TIM4_CCRx = TIM4_ARR/2 = 1000  (where x = 1, 2, 3 and 4).
 
    Note:
     SystemCoreClock variable holds HCLK frequency and is defined in system_stm32f4xx.c file.
     Each time the core clock (HCLK) changes, user had to call SystemCoreClockUpdate()
     function to update SystemCoreClock variable value. Otherwise, any configuration
     based on this variable will be incorrect.   
  ----------------------------------------------------------------------- */

Что я делаю не так? (УжЕ весь моск сломал.) Может, какой-нить PCLK1 неправильно установлен?
Даташиты читал, и отдельный про таймеры тоже (ничё там толком конкретно по проблеме не вЫчитал).

Насколько я понял, функция TIM_CtrlPWMOutputs() - необязательна (в примерах её нигде нет, это я её в инете нарыл, но тот код вроде как был для STM32F10x). Что без неё неправильно работает, что с ней.
Про TIM1 будет отдельная пестня.

Re: Вопросы по программированию STM32Fxxx

elmot » 11 дек 2012, 00:11

Есть версия, что просто не с того тактирования заведено.
Код ниже для f3, но мысль та же.
RCC_PLLConfig(RCC_PLLSource_HSI_Div2,RCC_PLLMul_16);
RCC_PLLCmd(ENABLE);
RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK);

А вообще да, стмские таймера такие, перелом моска получить - не вопрос.

Re: Вопросы по программированию STM32Fxxx

dccharacter » 12 дек 2012, 15:42

Да нет там перелома мозга
1. Не вижу, на какой частоте работает камень
2. Используй clock configuration tool (скачай, например, тут: http://www.st.com/internet/mcu/product/245079.jsp, поиском по странице "clock configuration" - там пдф-аппноут и зип с самим эксель файлом
3. timer3_oc_init.TIM_Pulse = 1500; // Коэф. заполнения? <- Это собственно активная часть периода (т.е. сам пульс без паузы).

Алгоритм такой:
1. Выясняешь, на какой частоте ядро, допустим 24МГц.
2. Устанавливаешь делители шин, например 4 (итого на таймере будет 6МГц)
3. Устанавливашь прескейлер, допустим 6 (итого таймер будет тикать на 1МГц, или 1мкс/тик)
4. Ставишь период. Допустим, тебе надо 1мс. Т.е. ставишь период 1000.
5. Ставишь пульс. Нужен 167мкс - ставишь его в 167.

будет у тебя шим с периодом в 1мс и дьюти сайклом 16,7%

Re: Вопросы по программированию STM32Fxxx

elmot » 12 дек 2012, 16:48

Примерно это я и хотел сказать. Только не выяснять частоту, а тупо в максимум выставить.

Re: Вопросы по программированию STM32Fxxx

Drunya » 26 дек 2012, 15:13

Здравствуйте.
У меня след. вопрос по ST-Link'у. Имеется девайс на STM32F103RBT6, программирую в Keil, прошивка и дебаг - встроенным st-link'ом на STM32VLDiscovery и STM32F4Discovery по SWD. На 32VL, как известно, установлен ST-Link V1, а на F4 - V2, оба обновлены до последних на сей день версий.
Так вот, при дебаге через STM32VLDiscovery нормально ходит по строкам как в дизасме, так и по С-файлу, но при EXTI прерывании дебаг перманентно вылетает, а проц ресетится.
Через F4 вообще отладка запускается с самого начала и шагает только по дизасму, в С вообще нет курсора, даже при установленной галке 'Run to main()'.
Чем это может быть вызвано и если кто сталкивался - где искать ответ? Ссылки там, или в доках каких описано.
Спасибо.

Re: Вопросы по программированию STM32Fxxx

zuluss008 » 07 янв 2013, 01:01

Подскажите, возможно ли к STM32VL Discovery подключить дисплей 3.2inch 320x240 Touch LCD (B) (FSMC + SPI) на контроллере ssd1289?
Фото дисплея вот тут (только в составе другой discovery)
http://baraholka.onliner.by/viewtopic.php?t=4815515
Искал в интернете инфу, но везде,в основном, эти дисплеи подключаются к STM32F4xxxxxx...

Re: Вопросы по программированию STM32Fxxx

elmot » 07 янв 2013, 01:28

Вроде ничего не мешает. F407, конечно, помощнее мозгами, но f100 что-нибудь да нарисует.

Re: Вопросы по программированию STM32Fxxx

Angel71 » 07 янв 2013, 03:12

1289 и к мегам подключают. так что если без фанатизма, то с stm32vl вполне сносно будет.

Re: Вопросы по программированию STM32Fxxx

Drunya » 14 янв 2013, 00:21

Сам подключал к STM32VLDiscovery дисплей HY32D (только не по FSMC, а через GPIO). Исходники брал тут: http://unidk.com/zagruzki/udk-32f107v-zagruzki/biblioteki и допиливал под STM32F100. Если надо - проект скину.
_P1130306.jpg
STM32VLDiscovery + HY32D

Re: Вопросы по программированию STM32Fxxx

zuluss008 » 20 янв 2013, 03:03

Drunya писал(а):Сам подключал к STM32VLDiscovery дисплей HY32D (только не по FSMC, а через GPIO). Исходники брал тут: http://unidk.com/zagruzki/udk-32f107v-zagruzki/biblioteki и допиливал под STM32F100. Если надо - проект скину.

Скинь пожалуйста.
Я кое-как прикрутил дисплей к stm32f4discovery в IAR,
использовал код отсюда
http://www.element14.com/community/groups/development-tools/blog/tags/hy32d
но получились грабли- на дисплее всегда остается мусор от предыдущей картинки,
никакие LCD_clear(),LCD_init_() не работают, хотя функции в библиотеке корректно обьявлены и прописаны.
Не знаю, как очистить внутреннюю память дисплея.
С цветами проблемы.Такое чувство, будто там не SSD1289, а что-то иное.
Схему подключения перепроверял, может в сторону настроек компилятора надо копать?
Причем на атмеге 2560 всё работает отлично с помощью библиотеки UTFT.

Re: Вопросы по программированию STM32Fxxx

elmot » 21 янв 2013, 01:53

может проц слишком быстрый? скинь частоту, попробуй еще раз

Re: Вопросы по программированию STM32Fxxx

Drunya » 21 янв 2013, 15:17

Проект под Кейл.
Keil_F1_Discovery.rar
(515.21 КиБ) Скачиваний: 0

Re: Вопросы по программированию STM32Fxxx

zuluss008 » 22 янв 2013, 03:19

в вашем проекте начал искать схему подключения платы к TFT,
нашел вот это в SSD1289.h:

#define LCD_BACKLIGHT_PIN GPIO_Pin_5 // PC.5
#define LCD_BACKLIGHT_GPIO_PORT GPIOC // GPIOC
#define LCD_BACKLIGHT_GPIO_CLK RCC_APB2Periph_GPIOC

#define LCD_CS_PIN GPIO_Pin_9 // PC.9
#define LCD_CS_GPIO_PORT GPIOC // GPIOC
#define LCD_CS_GPIO_CLK RCC_APB2Periph_GPIOC

#define LCD_WR_PIN GPIO_Pin_7 // PC.7
#define LCD_WR_GPIO_PORT GPIOC // GPIOC
#define LCD_WR_GPIO_CLK RCC_APB2Periph_GPIOC

#define LCD_RS_PIN GPIO_Pin_8 // PC.8
#define LCD_RS_GPIO_PORT GPIOC // GPIOC
#define LCD_RS_GPIO_CLK RCC_APB2Periph_GPIOC

#define LCD_RD_PIN GPIO_Pin_6 // PC.6
#define LCD_RD_GPIO_PORT GPIOC // GPIOC
#define LCD_RD_GPIO_CLK RCC_APB2Periph_GPIOC

#define LCD_DATA_PIN GPIO_Pin_All // PB
#define LCD_DATA_GPIO_PORT GPIOB // GPIOB
#define LCD_DATA_GPIO_CLK RCC_APB2Periph_GPIOB

//-----------------------------------------------------------------------------

Куда вешать шину D0-D15 дисплея? На порт B?
Так там же выводов не хватает. B0-B9. Нид хэлп!

Добавлено спустя 17 минут 50 секунд:
Что-то мне подсказывает, что рановато браться за TFT-touchscreen сразу после светодиодов :oops: .
Хотя без FSMC это по сути - то же банальное ногодрыганье...

Re: Вопросы по программированию STM32Fxxx

Drunya » 22 янв 2013, 12:07

Внизу платы PB10-PB15.

Re: Вопросы по программированию STM32Fxxx

elmot » 22 янв 2013, 12:17

Не нада бояться. Я тож сразу после машинки на l293 начал систему с дисплеем городить(правда с черно-белым). И ничо, заработало все.


cron
Rambler\'s Top100 Mail.ru counter