Bir proje için PWM, RTC, ADC ve DAC sistemini kullanmam gerek. Bir seçim aşamasındayken PIC mi yoksa ARM mı kullanayım derken ARM ı öğrenmem için bir fırsat olarak değerlendirdim. Artık ARM kullanacağım bu projede.
Pwmiçin kullanacağım Cortex M3 mimariye sahip STM32F100RB işlemcisine sahip STM32VLDISCOVERYnkartını kullandım.
Komutlara ayrıca değinmiyorum keza assembly den kalma bir alışkanlık olsa gerek açıklamaları herzaman yazarım.
Kartın üzerinde olan iki adet led pwm sinyaline göre ışık verecektir. siz ayrıca görmek isterseniz PC8 ve PC9 uçlarından osilaskop a yada lojik analizöre bağlayabilirsiniz.
Ayrıca sistem saat sinyalinin düzenli olup olmadığını MCO çıkışı olarak ayarlamış olduğum PA8 de 12MHz lik sinyal görmeniz gerekir.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 |
#include <stm32f10x.h> //duty cycle = (TIM3_CCR1/ TIM3_ARR)* 100 int flag; void SystemInit(void) { RCC->CR |= 0x00010000;//HSEON=1 while(!(RCC->CR & 0x00020000));//Harici osilatörün stabil olmasi için bekleniliyor(6 komut çevrimi) // Asagidaki komutlar HSE OSC nin probminde HSI OSC yi devreye sokar.******************** RCC->CIR |= 0x00080000;//HSERDYC: HSE ready interrupt cleared RCC->CR |= 0x00080000;//Clock security system Enabled. RCC->CIR |= 0x00800000;//CSSC: Clock security system interrupt cleared. //************************************************************************************* RCC->CR |= 0x00040000;//HSE bypassed. RCC->CFGR |= 0x00000080;//AHB configuration 2 ye bölme RCC->CFGR |= 0x00002000;//APB2 configuration 2 ye bölme RCC->CFGR |=0x07000000;//MCO PLL/2 YAPILDI (GPIOA.8 MCO çikis olarak ayarlandi) RCC->CFGR |=0x00010000;//PLL girisi PLLDIV olarak ayarlandi (PLL OFF iken ayarlanmali) RCC->CFGR |=0x00280000;//PLL CARPMA ORANI 3 RCC->CFGR2 =0x00000003;// cfgr2 ile plldiv ayarlan1yor bu ayar ile osc yi önbölme yapiliyor. RCC->CR |=0x01000000;//PLL ON while(!(RCC->CR & 0x02000000));//PLL stabil oldu mu ? RCC->CFGR |=0x0000000A;//system clock ayari rehber 79 RCC->APB2ENR |=0x0000001C;//PORT C,A,B Clock Enabled. GPIOA->CRH &=0x00000000; GPIOA->CRH |=0x00000009;//A PORTU MAX P_UP CIKIS , MCO çikis için GPIOA.8 ALTERNATE FUNCTION GPIOC->CRL &= 0x00000000;//C portu Max hizda çikis olarak ayarlandi GPIOC->CRH &= 0x00000000; GPIOC->CRL |= 0x00000000;//C portu Max hizda çikis olarak ayarlandi GPIOC->CRH |= 0x00000099; //TIM3 INIT****************************************duty cycle = (TIM3_CCR1/ TIM3_ARR)* 100*************** // RCC->APB1ENR|=0x00000002;// Timer3 CLK'u aktif edelim RCC->APB2ENR|=0x00000001;//AFIO clock enable AFIO->MAPR |=0x00000C00;// timer3 full remap rehber 121 (önce clok aktif olmali) TIM3->PSC =239 ;// TIM3->ARR =500;// TIM3->CCR3=0;// TIM3->CCR4=500;// TIM3->CCMR2 |=0x6060;//(rehber sayfa 323) PWM mode olarak seçildi TIM3->CCER |=0x1100;//Capture/Compare 3-4 output enable //TIM3->CR1=0x0080;// Otomatik Reload TIM3->DIER=0x0001;// Update Int enable NVIC->ISER[0] = 0X20000000;// NVIC de Timer 3 interrupta izin verelim TIM3->CR1|=0x0001;// Counter Enable //******************************************************************* } void TIM3_IRQHandler() { TIM3->SR &=0;// Timer Int Flagini silelim UIF TIM3->CCR3 +=5;//Her kesmede CCR3 e 5 ekle (PWM_1 in sinyalinin Duty değeri değişir) if (TIM3->CCR3==500)//Eğer CCR3, 500 ü geçtiyse { TIM3->CCR3=0;//CCR3 ü Sıfırla TIM3->CCR4 -=5;//CCR4 den 5 çıkart (PWM_2 nin Duty Değeri değiştir) } if (TIM3->CCR4==0)//CCR4 sıfırsa { TIM3->CCR4==500;//CCR4 e 500 degeririni at (Duty degeri) } } main() { while(1) { } } |
Ek:
Yazıda herhangi bir yerde Pwm frekansı ve duty oranıyla alakalı bir hesaplama geçmediğini farkettim. hesaplama yöntemi aşağıdadır.
1 2 |
Frekans=(APBx_Speed/PSC) / (ARR+1) Duty Oranı =(CCRx/(ARR+1))*100 |