STM32F407 Cortex M4 şamataları

Başlatan bunalmis, 16 Ekim 2011, 17:14:50

cooldoubtless

#include "STM32F4xx.h"

void SystemInit()
{
unsigned int i;
     for (i=0;i<0x00100000;i++);     // OSC oturtma ve kurtarma rutini
     RCC->CFGR |= 0x00009400;        // AHB ve APB hizlarini max degerlere set edelim
     RCC->CR |= 0x00010000;          // HSE Xtal osc calismaya baslasin
     while (!(RCC->CR & 0x00020000));// Xtal osc stabil hale gelsin
     RCC->PLLCFGR = 0x07402A04;      // PLL katsayilarini M=4, N=168, P=2 ve Q=7 yapalim
     RCC->CR |= 0x01000000;          // PLL calismaya baslasin  (Rehber Sayfa 95)
     while(!(RCC->CR & 0x02000000)); // Pll hazir oluncaya kadar bekle
     FLASH->ACR = 0x00000605;        // Flash ROM icin 5 Wait state secelim ve ART yi aktif edelim (Rehber Sayfa 55)
     RCC->CFGR |= 0x00000002;        // Sistem Clk u PLL uzerinden besleyelim
     while ((RCC->CFGR & 0x0000000F) != 0x0000000A); // Besleninceye kadar bekle
     RCC->AHB1ENR |= 0x0000000F;     // GPIO A,B,C,D clock'u aktif edelim
     GPIOD->MODER  = 0x55550000;     // GPIOD nin 15, 14, 13, 12, 11, 10, 9, 8 pinleri cikis tanimlandi (LEDler icin)
	   GPIOE->MODER  = 0xAA0A0000;     // TIM1 CHANNEL1 kullanacagim için e portunu alternatif fonk.seçtim
     GPIOD->OSPEEDR= 0xFFFFFFFF;     // GPIOD nin tum cikislari en yuksek hizda kullanacagiz 
 
     RCC->APB2ENR|=0x00000001;         // Timer1 CLK'u aktif edelim (168 Mhz)
     
     TIM1->PSC =1679;                 // Prescaler degerimiz 1679, Count frekansimiz = fCK_PSC / (Yuklenen Deger + 1) 168E6 / (1680) = 100 KHz
     TIM1->ARR =1000;                 // Periyot 1000
	   TIM1->CCR1=100;                  // Duty cycle
     TIM1->DIER=0x0001;              // Update Int enable
     TIM1->CCMR1=0x0070;             // PWM Mode 2 yi seçtik bu yüzden '111' yazdik.
     TIM1->EGR=0x0001;               // UG biti 1 yaptk
		 TIM1->CR1=0x0081;               // Otomatik Reload VE SAYICIYI BASLAT
 
} 
 
 
int main()
{
  

    while(1);
}



arkadaşlar artık şu kitle bir bldc nin döndüğünü görmek istiyorum..ancak bir türlü beceremiyorum..system init fonksyonlarımda bir yanlış olduğunu düşünmüyorum..varsa beni uyarırmısınız? ayrıca şimdi bütün sayma işlemlerini karşılaştırma işlemlerini benim için bu registerlar yapıyorsa benim main fonksiyonuna başka ne yazmam gerekecek?

pisayisi

6 fetli sürücünün hangi çıkışı hangi porta bağlı, geribesleme hall sensorleri hangi pinlere bağlı şöyle bir şematik olsa daha anlaşılır olcak...
Murat

EMP_Otto

Klein hocam Keil in 4.22a versiyonunu kurdum göndermiş olduğunuz programı derledim kite yükledim ama yine bi atraksiyon olmadı :)Sonra tekrar 4.53 versiyonunu kurdum birde onda denedim yine olmadı.Derlemede ve kite yüklemede sorun yok.Daha sonra Keil ile birlikte gelen Blinky projesini derleyip kite yükledim çalıstı.
Bu işi bi türlü anlamadım yaaa herkeste çalışan kod bende çalışmıyor.Kitte sorun olsa Blinky projeside çalışmaması lazım diye düşünüyorum.

ARtık yuardım edin demekten utanır oldum  :'(
Bu işler zordur,özveri ister...

Klein

@EMP_Otto Hangi şehirdesin bilmiyorum. Eğer Ankara'da isen, gel bana birlikte halledelim.

cooldoubtless

Alıntı yapılan: pisayisi - 30 Ağustos 2012, 12:29:14
6 fetli sürücünün hangi çıkışı hangi porta bağlı, geribesleme hall sensorleri hangi pinlere bağlı şöyle bir şematik olsa daha anlaşılır olcak...

şemayı ekliyorum..fırçasız dc motor ile esc kullanıyorum..yani ayrıca sürücü kurmadım..motor kontrolünü geri beslemeli denetim yapmayacağım için ayrıca bir sensör kullanmıyorum sadece vereceğim pwm oranıyla motorun dönmesini istiyorum hepsi bu..TEK KANAL ÜZERİNDEN PWM GÖNDERİYORUM..bu bağlantı da esc nin beyaz kablosuyla gerçekleşiyor..yaklaşık %10 luk bir pwm programda da gördüğünüz gibi..programda ne gibi eklemeler olmalı acaba?

cooldoubtless



şema gözükmediği için tekrar yükledim :)

SERRO EFE

@cooldoubtless pwmi izleyebiliyomusun scop - logic analyzer varmı. Eğer pwm düzgün bir şekilde çıkıyorsa esc nin çalışması için önce pwm sinyalini 1 ms olarak uygulaman lazım esc hazır duruma geçsin sonra yavaş yavaş pwmi arttırmalısın.

pisayisi

TIMx Channel1 duty cycle = (TIMx_CCR1/ TIM3_ARR + 1)* 100

pwm duty oranın yüzde 10 gibi hesaplanıyor bu oranla çıkışta birşey süremezsin,

Prescaler = (TIMxCLK / TIMx counter clock) - 1

örneğin TIMxCLK=21 Mhz ise
PrescalerValue = (uint16_t) ((SystemCoreClock /2) / 21000000) - 1=3 olabilir;

prescalar hesabında yanlış gibi duruyor...

st firmware  ile yazılmış aşağıdaki örneği incelemeni ve parametreleri firmware kullanmasan bile aşağıdaki gibi belirlemeni öneririm...
/**
  ******************************************************************************
  * @file    TIM/PWM_Output/main.c 
  * @author  MCD Application Team
  * @version V1.0.1
  * @date    13-April-2012
  * @brief   Main program body
  ******************************************************************************
  * @attention
  *
  * <h2><center>&copy; COPYRIGHT 2012 STMicroelectronics</center></h2>
  *
  * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License");
  * You may not use this file except in compliance with the License.
  * You may obtain a copy of the License at:
  *
  *        http://www.st.com/software_license_agreement_liberty_v2
  *
  * Unless required by applicable law or agreed to in writing, software 
  * distributed under the License is distributed on an "AS IS" BASIS, 
  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  * See the License for the specific language governing permissions and
  * limitations under the License.
  *
  ******************************************************************************
  */

/* Includes ------------------------------------------------------------------*/
#include "stm32f4xx.h"

/** @addtogroup STM32F4xx_StdPeriph_Examples
  * @{
  */

/** @addtogroup TIM_PWM_Output
  * @{
  */ 

/* Private typedef -----------------------------------------------------------*/
/* Private define ------------------------------------------------------------*/
/* Private macro -------------------------------------------------------------*/
/* Private variables ---------------------------------------------------------*/
TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;
TIM_OCInitTypeDef  TIM_OCInitStructure;
uint16_t CCR1_Val = 333;
uint16_t CCR2_Val = 249;
uint16_t CCR3_Val = 166;
uint16_t CCR4_Val = 83;
uint16_t PrescalerValue = 0;

/* Private function prototypes -----------------------------------------------*/
void TIM_Config(void);

/* Private functions ---------------------------------------------------------*/

/**
  * @brief  Main program
  * @param  None
  * @retval None
  */
int main(void)
{
  /*!< At this stage the microcontroller clock setting is already configured, 
       this is done through SystemInit() function which is called from startup
       file (startup_stm32f4xx.s) before to branch to application main.
       To reconfigure the default setting of SystemInit() function, refer to
       system_stm32f4xx.c file
     */

  /* TIM Configuration */
  TIM_Config();
  
  /* -----------------------------------------------------------------------
    TIM3 Configuration: generate 4 PWM signals with 4 different duty cycles.
    
    In this example TIM3 input clock (TIM3CLK) is set to 2 * APB1 clock (PCLK1), 
    since APB1 prescaler is different from 1.   
      TIM3CLK = 2 * PCLK1  
      PCLK1 = HCLK / 4 
      => TIM3CLK = HCLK / 2 = SystemCoreClock /2
          
    To get TIM3 counter clock at 21 MHz, the prescaler is computed as follows:
       Prescaler = (TIM3CLK / TIM3 counter clock) - 1
       Prescaler = ((SystemCoreClock /2) /21 MHz) - 1
                                              
    To get TIM3 output clock at 30 KHz, the period (ARR)) is computed as follows:
       ARR = (TIM3 counter clock / TIM3 output clock) - 1
           = 665
                  
    TIM3 Channel1 duty cycle = (TIM3_CCR1/ TIM3_ARR)* 100 = 50%
    TIM3 Channel2 duty cycle = (TIM3_CCR2/ TIM3_ARR)* 100 = 37.5%
    TIM3 Channel3 duty cycle = (TIM3_CCR3/ TIM3_ARR)* 100 = 25%
    TIM3 Channel4 duty cycle = (TIM3_CCR4/ TIM3_ARR)* 100 = 12.5%

    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.    
  ----------------------------------------------------------------------- */   


  /* Compute the prescaler value */
  PrescalerValue = (uint16_t) ((SystemCoreClock /2) / 21000000) - 1;

  /* Time base configuration */
  TIM_TimeBaseStructure.TIM_Period = 665;
  TIM_TimeBaseStructure.TIM_Prescaler = PrescalerValue;
  TIM_TimeBaseStructure.TIM_ClockDivision = 0;
  TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;

  TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure);

  /* PWM1 Mode configuration: Channel1 */
  TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;
  TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
  TIM_OCInitStructure.TIM_Pulse = CCR1_Val;
  TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;

  TIM_OC1Init(TIM3, &TIM_OCInitStructure);

  TIM_OC1PreloadConfig(TIM3, TIM_OCPreload_Enable);

  /* PWM1 Mode configuration: Channel2 */
  TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
  TIM_OCInitStructure.TIM_Pulse = CCR2_Val;

  TIM_OC2Init(TIM3, &TIM_OCInitStructure);

  TIM_OC2PreloadConfig(TIM3, TIM_OCPreload_Enable);

  /* PWM1 Mode configuration: Channel3 */
  TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
  TIM_OCInitStructure.TIM_Pulse = CCR3_Val;

  TIM_OC3Init(TIM3, &TIM_OCInitStructure);

  TIM_OC3PreloadConfig(TIM3, TIM_OCPreload_Enable);

  /* PWM1 Mode configuration: Channel4 */
  TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
  TIM_OCInitStructure.TIM_Pulse = CCR4_Val;

  TIM_OC4Init(TIM3, &TIM_OCInitStructure);

  TIM_OC4PreloadConfig(TIM3, TIM_OCPreload_Enable);

  TIM_ARRPreloadConfig(TIM3, ENABLE);

  /* TIM3 enable counter */
  TIM_Cmd(TIM3, ENABLE);

  while (1)
  {}
}

/**
  * @brief  Configure the TIM3 Ouput Channels.
  * @param  None
  * @retval None
  */
void TIM_Config(void)
{
  GPIO_InitTypeDef GPIO_InitStructure;

  /* TIM3 clock enable */
  RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE);

  /* GPIOC clock enable */
  RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOC, ENABLE);
  
  /* GPIOC Configuration: TIM3 CH1 (PC6), TIM3 CH2 (PC7), TIM3 CH3 (PC8) and TIM3 CH4 (PC9) */
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6 | GPIO_Pin_7 | GPIO_Pin_8 | GPIO_Pin_9;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;
  GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
  GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP ;
  GPIO_Init(GPIOC, &GPIO_InitStructure); 

  /* Connect TIM3 pins to AF2 */  
  GPIO_PinAFConfig(GPIOC, GPIO_PinSource6, GPIO_AF_TIM3);
  GPIO_PinAFConfig(GPIOC, GPIO_PinSource7, GPIO_AF_TIM3); 
  GPIO_PinAFConfig(GPIOC, GPIO_PinSource8, GPIO_AF_TIM3);
  GPIO_PinAFConfig(GPIOC, GPIO_PinSource9, GPIO_AF_TIM3); 
}

#ifdef  USE_FULL_ASSERT

/**
  * @brief  Reports the name of the source file and the source line number
  *         where the assert_param error has occurred.
  * @param  file: pointer to the source file name
  * @param  line: assert_param error line source number
  * @retval None
  */
void assert_failed(uint8_t* file, uint32_t line)
{
  /* User can add his own implementation to report the file name and line number,
     ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */

  while (1)
  {}
}
#endif

/**
  * @}
  */ 

/**
  * @}
  */ 

/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
Murat

cooldoubtless

#1028
Alıntı yapılan: SERRO EFE - 31 Ağustos 2012, 09:20:59
@cooldoubtless pwmi izleyebiliyomusun scop - logic analyzer varmı. Eğer pwm düzgün bir şekilde çıkıyorsa esc nin çalışması için önce pwm sinyalini 1 ms olarak uygulaman lazım esc hazır duruma geçsin sonra yavaş yavaş pwmi arttırmalısın.

hayır ne yazıkki logic analyzer yok oyüzden çıkışı izleyemiyorum..

@pisayisi.. evt duty cycle %10 sölemiştim..bu oran yeterli değilse dediğin gibi bu oranı %50 ye çıkariyim..ama prescaler değeri doğru gibi duruyor..168mhz timer1 o yüzden..

mesaj birleştirme:: 31 Ağustos 2012, 22:13:55

esc ler genellikle en fazla 50 mhz ile çalışıyomuş o yüzden hemen düzelttim programı 100mhz den 10mhz e düşürdüm..ancak değişen bir şey yok..:) çok ilginç herkes rc sistemlerle takıp esc leri kumandayla sürmüş bununla ilgili bilgiler mevcut ancak bir mikrodenetleyici üzerinden pwm ile esc ye sinyal gönderip motoru döndüren bir kişi bulamadım..bilgi bulamadım..elbette yapan çok kişi vardır ama forumlardan uzaktır..eminim işi bilen için 10 dakika bile almaz ancak bizim gibi tecrübesizler böyle aylarca uğraşıyor..bu kadar zor olacağını beklemiyordum bir motor döndürmenin :D

SERRO EFE

Yanlış biliyorsunuz escler "50MHZ" değil 50-60  hz çalışır esc yi çalıştırabilmen için "RC SERVO" sinyali çıkarman lazım denetleyicinle.


cooldoubtless

hadi ya 50 hz miymiş aradaki fark milyonda bir :) teşekkür ederim bilgi için ama ben fırçasız doğru akım motoru süreceğim yani bu şekilde açı açı bilgi girmek zorunda değilim diye düşünüyorum..e sonuçta bu stm32f4 ü boşuna mı aldık okadar pwm çıkışı var onlardan biri bizim yerimize bunlarla uğraşmıyor mu? pwm pininin zaten amacı bu değil mi? "ben alternatif fonksiyonlardan pwm çıkışını bir timer a atıyorum..gerisini o hallediyor.."diyebilmeliydim..ama diyemiyorum :)  esc lerin başlangıçta belli bir süre high belli bir süre de low sinyal verilerek dönüşe hazır hale getirilmesi gerektiğini biliyodum..ancak rehber'i neredeyse tamamen hatmettim ama böyle bir bilgi yok..pwm çıkışı almak için de böyle bir not düşülmemiş ben de heralde gerek yok diye düşündüm..zaten bana 20 ns logic 0 ver desen veremem ki bunla..pic değil ki bu..gecikme fonksiyonuyla da birşey yapamıyorsun yine bir sayıcı kullanmam gerekir heralde..nebilim saç baş yolduracak cinsten bir işlemci..her noktası sırlar odası..adam gibi rehber de yok..

fatih6761

Gecikme fonksiyonları için bir SysTick olayı var zaten. kolaylıkla istediğiniz aralığa ayarlıyabilirsiniz. Bu gecikme olayının hazır bir kütüphanede bulunması çok kolaylık olurdu. Birde standart karakter LCD için bir kütüphanesi olsa iyi olurdu vs.vs. Rehber zaten berbat durumda, işlemciyi beğendim ama dökümantasyon ve yardım berbat durumda. Umarım ST buna bir çözüm bulur.

cooldoubtless

Alıntı yapılan: fatih6761 - 01 Eylül 2012, 19:53:04
Gecikme fonksiyonları için bir SysTick olayı var zaten. kolaylıkla istediğiniz aralığa ayarlıyabilirsiniz. Bu gecikme olayının hazır bir kütüphanede bulunması çok kolaylık olurdu. Birde standart karakter LCD için bir kütüphanesi olsa iyi olurdu vs.vs. Rehber zaten berbat durumda, işlemciyi beğendim ama dökümantasyon ve yardım berbat durumda. Umarım ST buna bir çözüm bulur.


hocam bu SysTick ile istediğimiz aralığı ayarlayabildiğimizi söylemişsiniz..forumda herhangi bir sayfada açıklaması varsa gösterirseniz çok memnun olurum hemen uygulamak isterim..

fatih6761

ST nin kendi Peripheral Examples projelerinde SysTick adlı bir proje olacaktı. Orada herşeyi anlatılmış. Diğer örneklerde de zaten görürsünüz Delay kullanan bütün projelerde var.
Basitçe ST kütüphanesinden SysTick_Config(SystemCoreClock / 1000) ile her 1 milisaniyede bir interrupt oluşturabilirsiniz. Bu kesmeleri SysTickHandler(?) ile yakalarsınız. Zaten kesme stm32f4xx_it.c dosyasında (adından emin değilim ama sonu _it.c ile bitiyor ) rutini bulursunuz.

cooldoubtless

Alıntı yapılan: fatih6761 - 01 Eylül 2012, 20:41:39
ST nin kendi Peripheral Examples projelerinde SysTick adlı bir proje olacaktı. Orada herşeyi anlatılmış. Diğer örneklerde de zaten görürsünüz Delay kullanan bütün projelerde var.
Basitçe ST kütüphanesinden SysTick_Config(SystemCoreClock / 1000) ile her 1 milisaniyede bir interrupt oluşturabilirsiniz. Bu kesmeleri SysTickHandler(?) ile yakalarsınız. Zaten kesme stm32f4xx_it.c dosyasında (adından emin değilim ama sonu _it.c ile bitiyor ) rutini bulursunuz.

çok teşekkür ederim hocam..hemen bakiyim ben..