Uygulamayı CooCox ide ile gerçekleştireceğim. Proje oluşturma adımları , GPIO uygulamasındakine benzer.
PWM çıkışı için Timer3 ve PC6 ve PC7 pinlerini kullanacağım.
PWM kanallarını 4Khz bir sinyal ile süreceğim.
Kanallar bir birine simetrik bir şekilde 0-100 arasında değerlerde değişecek.
CH0 0 ->100 ->0
CH1 100->0 ->100
Her PWM kanalınada bir adet 12V fırçasız motor bağladım. ( Doğrudan mikro işlemci bacağına bağlı değil arada open collector bir transistör sürücü var )
Code kısmına gelince, Aşağıdaki gibi,
/**
*****************************************************************************
* @title EDS1 PWM TEST.c.c
* @author Veysel KARADAĞ
* @date 24.04.2014
* @brief GPIO Example
*******************************************************************************
*/
#include "stm32f10x_rcc.h"
#include "stm32f10x_gpio.h"
#include "stm32f10x_tim.h"
void confPWM(void);
void set_duty_PWM(int ch ,int duty);
void delay(long int tik);
int main(void)
{
int i=0;
int yon=0;
confPWM();
while(1)
{
delay(500000);
set_duty_PWM(0,i);
set_duty_PWM(1,100-i);
if(yon==0){
i++;
}else{
i--;
}
if(i==100){
yon=1;
}
if(i==0){
yon=0;
}
}
}
/*******************************************************************************
* Function Name : confPWM
* Description : PWM 1-2 kanalı 4Khz kurar
* : PB0,PB1
* Input : None
* Output : None
* Return : None
*******************************************************************************/
void confPWM(void){
GPIO_InitTypeDef GPIO_InitStructure;
TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStruct;
TIM_OCInitTypeDef TIM_OCInitStruct;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC | RCC_APB2Periph_AFIO, ENABLE );
RCC_APB1PeriphClockCmd( RCC_APB1Periph_TIM3 , ENABLE );
GPIO_StructInit(&GPIO_InitStructure); // GPIO yapısını Resetler
GPIO_PinRemapConfig(GPIO_FullRemap_TIM3,ENABLE);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6 | GPIO_Pin_7; // Pin6 ve Pin7 Seçilir.
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; // Push Pull olarak set edilmesi ayarlanır.
GPIO_Init( GPIOC, &GPIO_InitStructure ); // GPIOC yukarıdaki ayarlara göre Set edildi.
// Let PWM frequency equal 100Hz.
// Let period equal 1000. Therefore, timer runs from zero to 1000. Gives 0.1Hz resolution.
// Solving for prescaler gives 18. ( Frekans = 72Mhz/1000/18)
TIM_TimeBaseStructInit( &TIM_TimeBaseInitStruct );
TIM_TimeBaseInitStruct.TIM_ClockDivision = TIM_CKD_DIV4;
TIM_TimeBaseInitStruct.TIM_Period = 1000-1; // 0..999
TIM_TimeBaseInitStruct.TIM_Prescaler = 18-1; // Div 18-1
TIM_TimeBaseInit( TIM3, &TIM_TimeBaseInitStruct );
TIM_OCStructInit( &TIM_OCInitStruct );
TIM_OCInitStruct.TIM_OutputState = TIM_OutputState_Enable;
TIM_OCInitStruct.TIM_OCMode = TIM_OCMode_PWM1;
TIM_OCInitStruct.TIM_Pulse = 500; // 0 .. 1000 (0=Herzaman kapalı , 1000= Herzaman Açık) %25
TIM_OC1Init( TIM3, &TIM_OCInitStruct );
TIM_OC2Init( TIM3, &TIM_OCInitStruct );
TIM_Cmd( TIM3, ENABLE );
}
/*******************************************************************************
* Function Name : set_duty_PWM
* Description : setup duty cycle pwm cH0/1
* Input : int ch and duty ( ch:0/1 duty 0-100)
* Output : None
* Return : None
*******************************************************************************/
void set_duty_PWM(int ch ,int duty){
switch(ch){
case 0:
TIM3->CCR1 = duty*10; // SET Duty CH0 %X
break;
case 1:
TIM3->CCR2 = duty*10; // SET Duty CH1 %X
break;
default :
break;
}
}
/*******************************************************************************
* Function Name : delay
* Description : delay sistem tik
* Input : long int delay tik
* Output : None
* Return : None
*******************************************************************************/
void delay(long int tik){
int i=0;
for (i=0;i<tik;i++);
}
Program Çalıştığında PWM çıkışları aşağıdaki gibi oluyor. Video olan dosyada delay süresini biraz uzattım. Delay az olunca fanın yavaşladığı belli olmuyordu.