STM32F10X PWM+DMA ile Sinüs oluşturma (Örnek)

Başlatan Klein, 11 Mart 2013, 13:37:23

mir_as82

Hocam bu yazılan kodları ben farklı bir işlemciye nasıl uyarlarım bu noktada zorluk çekiyorum. Mesela siz stm32f10x ile yazmışsınız ben bu yapılan örneği stm32f4 ile nasıl yapabilirim? özellikle konfigürasyon ayarları sıkıntı oluyor.

61emre89

Klein hocam merhaba,
STM32F103r8t6 işlemci ile verdiğiniz kodu denedim(PB9 pini için-TIM4-CH4). Fakat sonuc olarak hep kare dalga elde ediyorum.

Sorun ne olabilir ,fikir verebilir misiniz?

Klein

Kare dalga elde etmeniz normal.  Osilaskopla baktığınızda duty oranı sürekli değişen kare dalga görürsünüz. Çıkışı seri direnten geçirip, diren ıkışından GND'ye bir kapasitör atarsanız, diren ve kapasitörün birleştiği noktada sinüs görürsünüz.

restore


61emre89

Hocam osiloskopta gözlemlediğim kadarıyla genişlik sabit olan bir kare dalga elde ediyorum. timer ve dma channel degiştirdigim icin dikkat etmem gereken parametreler var mı?


SpeedyX

Internal osc kullanıyorum ve PWM periodu örneğin 5ms olsun diye ayarlıyorum ama 4.96ms oluyor, bunu kalibre etmenin yada doğruluğunu arttırmanın kolay yolu var mı? (Kristal kullanmadan)

Klein

Alıntı yapılan: 61emre89 - 28 Mayıs 2014, 10:26:00
Hocam osiloskopta gözlemlediğim kadarıyla genişlik sabit olan bir kare dalga elde ediyorum. timer ve dma channel degiştirdigim icin dikkat etmem gereken parametreler var mı?


Kare dalgayı gördüğünüze göre timer çalışıyor. DMA çalışmıyor. Kodu yayınlarsanız bir bakarım.


Alıntı yapılan: SpeedyX - 28 Mayıs 2014, 11:22:34
Internal osc kullanıyorum ve PWM periodu örneğin 5ms olsun diye ayarlıyorum ama 4.96ms oluyor, bunu kalibre etmenin yada doğruluğunu arttırmanın kolay yolu var mı? (Kristal kullanmadan)

RCC_AdjustHSICalibrationValue(uint8_t HSICalibrationValue)

SpeedyX

Hocam RCC_AdjustHSICalibrationValue(uint8_t HSICalibrationValue) fonksiyonunu biliyorum tabii, yüzlerce cihazı kalibre etmek için trick gibi birşey sormuştum, yapan varsa eğer.

61emre89


void Timer_PWM_COnfiguration(void)
{
   TIM_TimeBaseInitTypeDef TIM_TBInitStruct;
   TIM_OCInitTypeDef TIM_OCInitStruct;


    TIM_TBInitStruct.TIM_Period =381;           //381
    TIM_TBInitStruct.TIM_Prescaler =6;
   TIM_TBInitStruct.TIM_ClockDivision = 0;
   TIM_TBInitStruct.TIM_CounterMode = TIM_CounterMode_Up;
   TIM_TimeBaseInit(TIM4, &TIM_TBInitStruct);


   TIM_OCInitStruct.TIM_OCMode = TIM_OCMode_PWM1;
    TIM_OCInitStruct.TIM_OCPolarity = TIM_OCPolarity_High;


      TIM_OCInitStruct.TIM_OutputState = TIM_OutputState_Enable;
    TIM_OCInitStruct.TIM_OCIdleState = TIM_OCIdleState_Set;
    TIM_OCInitStruct.TIM_Pulse =SineTable[0] ;
    TIM_OC4Init(TIM4, &TIM_OCInitStruct);


    TIM_DMACmd(TIM4,TIM_DMA_Update,ENABLE);
    TIM_Cmd(TIM4,ENABLE);
    TIM_CtrlPWMOutputs(TIM4,ENABLE);


}
/**************************************************************************************/
void Timer_DMA1_Configuration(void)
{
   DMA_InitTypeDef DMA_InitStructure1;


    DMA_DeInit ( DMA1_Channel4);
    DMA_Cmd(DMA1_Channel4,DISABLE);


    DMA_InitStructure1.DMA_PeripheralBaseAddr =0x40000840;
    DMA_InitStructure1.DMA_MemoryBaseAddr = (uint32_t)SineTable;
    DMA_InitStructure1.DMA_DIR = DMA_DIR_PeripheralDST;
    DMA_InitStructure1.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
    DMA_InitStructure1.DMA_MemoryInc = DMA_MemoryInc_Enable;
    DMA_InitStructure1.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord;
    DMA_InitStructure1.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord;
    DMA_InitStructure1.DMA_Mode = DMA_Mode_Circular;
    DMA_InitStructure1.DMA_Priority = DMA_Priority_Medium;
    DMA_InitStructure1.DMA_M2M = DMA_M2M_Disable;
    DMA_InitStructure1.DMA_BufferSize = 360;
    DMA_Init(DMA1_Channel4, &DMA_InitStructure1);


    DMA_Cmd(DMA1_Channel4,ENABLE);


}





Hocam kodu yukardaki gibi kucuk degişikler yaparak aynen uyguladım.

Klein

#39
DMA1 Kanal 4 kullanmışsınız.  Ancak kanal 4  TIM4 kanal4 'ten tetiklenmiyor. Hatta TIM4 Kanal4 için DMA1'de kanal yok.  DMA 1 Kanal 4 TIM4 Kanal 2 den tetikleme alabiliyor.
DMA 1 kanal listesi aşağıdaki gibi
https://www.dropbox.com/s/s05ylduij242eyq/Stm32F1_Dma.PNG

61emre89

Tasarımdan dolayı benim (PB9/TIM4-CH4) bacagından bu cıkısı almam gerekiyor. DMA1 listesinde bunun için bir Channel yok siz söyledikten sonra ben de listeyi yanlıs yorumladıgımı farkettim. Peki bu durumda alternatif olarak ne yapabilirim.?

Klein

Eğer Sinüs frekansınız yüksek değilse,  DMA yerine  interrupt içerisinde yükleme yapabilirsiniz.  Örnekle aynı sayfda  biir kaç başlık altında interrupt kullanımı da mevcut.

gokhannsahin

Eğer pwm ile 3 faz inverter yapmak istersek nasıl olacak benim aklımda şöyle bir çözüm var pwm tablosu diyelim ki 360 değerden oluşuyor, yanı her bir derece için bir değer. Fazlar arası 120 derece ise; R fazı tablonun 1'nci değerinden , S fazı tablosunun 121'nci değerinden ve son olarakda T fazı 241'nci değerden mi başlaması gerekiyor ?

Klein

Teorik olarak öyle.  Ama DMA'nın sadece base adresini verebiliyoruz. Eğer kanallardan birine adres olarak daha ilerideki bir adresi verirsek , taşacaktır.
Bu sebeple  tabloyu bir periyot yerine daha uzun hazırlarsanız taşmanın önüne geçebilirsiniz.

namso0632

DMA'yı DAC ile kullanmak için kodlar üzerinde nasıl bir değişiklik yapmamız gerekiyor acaba ?