Membuat PWM dengan STM8


Salah satu fungsi PWM yang banyak digunakan adalah untuk mengatur kecepatan Motor DC, mengatur cahaya Lampu atau mengatur derajat putar motor servo. Untuk penjelasan mengenai PWM sebelumya sudah saya tulis di artikel Mengatur PWM dengan Arduino
Penggunaan PWM di Arduino mungkin cendereung lebih mudah karena sudah disediakan fungsi-fungsi yang sangat mudah dimengerti, tetapi untuk minrokontroller lain, akan cenderung lebih sulit, karena kita harus tau register-register dari mikrokontroller tersebut. Dalam artikel ini saya akan membahas bagaimana mengaktifkan PWM pada mikrokontroller Stm8.
STM8s sudah menyediakan standard firmware library nya, untuk mendownload-nya anda bisa searching di google “Standard firmware library STM8s”. Bila anda menggunakan standard firmware library ini, anda dapat menggunakan program berikut untuk mengaktifkan PWM pada pin D3

#include "inc/stm8s_conf.h"//seduaikan dengan tempat penyimpanan library

int duty = 50;
int main() {
uint8_t direction;
uint16_t __ARR;
direction = 0;
__ARR = 999;
// Configure pins
GPIOD->CR1 = GPIO_PIN_3; // Enable push-pull
//TimeBaseInit
TIM2->ARRH = BYTE_1(__ARR);
TIM2->ARRL = BYTE_0(__ARR);

//OC2Init
TIM2->CCER1 = TIM2_CCER1_CC2P | TIM2_CCER1_CC2E ; // Set output polarity to active low and enable output
TIM2->CCMR2 = TIM2_OCMODE_PWM2 | TIM2_CCMR_OCxPE ; //Set pwm1 mode and enable preload for CCR2H/L

TIM2->CCR2H = BYTE_1(duty);
TIM2->CCR2L = BYTE_0(duty);
//Enable TIM2
TIM2->CR1 = TIM2_CR1_CEN | TIM2_CR1_ARPE ;

while(1){}
}



Bila tidak menggunakan library, maka program yang digunakan adalah sebagai berikut :

#include

#define enable_interrupts() __asm__("rim");
#define disable_interrupts() __asm__("sim");

#define TIM2_CR1 (*(volatile uint8_t *)0x5300) //TIM2 Control Register
#define PD_DDR (*(volatile uint8_t *)0x5011) //data direction register, untuk mengatur apakah pin digunakan untuk input atau output, bila diberi nilai 1(HIGH), maka pin digunakan untuk OUTPUT, bila diberi nilai 0 maka pin digunakan untuk input
#define PD_CR1 (*(volatile uint8_t *)0x5012) //control register 1
#define TIM2_CR1 (*(volatile uint8_t *)0x5300) //TIM2 Control Register
#define TIM2_CCMR1 (*(volatile uint8_t *)0x5307) //TIM2 capture/compare mode register 1
#define TIM2_CCER1 (*(volatile uint8_t *)0x530A) //TIM2 capture/compare enable Register 1
#define TIM2_CCER2 (*(volatile uint8_t *)0x530B) //TIM2 capture/compare enable Register 2
#define TIM2_PSCR (*(volatile uint8_t *)0x530E) //TIM2 prescaler Register
#define TIM2_ARRH (*(volatile uint8_t *)0x530F) //TIM2 auto reload Register HIGH
#define TIM2_ARRL (*(volatile uint8_t *)0x5310) //TIM2 auto Reload Register low
#define TIM2_CCR1H (*(volatile uint8_t *)0x5311) //TIM2 capture/compare register 1 HIGH
#define TIM2_CCR1L (*(volatile uint8_t *)0x5312) //TIM2 capture/compare Register 1 low

const uint16_t timer2_arr = 999; //999 PWM with 2kHz frequency
uint16_t dutyCycle = 80;


int main() {
disable_interrupts();
//1. konfigurasi pin output
// As per datasheet of stm8s103f3 PD4 pin is timer 2 channel 1.

PD_DDR = 0x10;
PD_CR1 = 0x10;

//2. Atur prescaler
TIM2_PSCR = 0x00; // Prescaler = 1

//3. configure auto reload register
TIM2_ARRH = timer2_arr >> 8; //return the second byte of 32 byte value
TIM2_ARRL = timer2_arr & 0x00FF; //return the low byte of 32-bit value

//karena pin D4 = TIM2 CHN 1, maka mengguanakn capture/compare 1 0x02 dan 0x01 **lihat di stm8s.h default header
TIM2_CCER1 = 0x02 | 0x01;/*!< Capture/Compare 1 output Polarity mask. */ /*!< Capture/Compare 1 output enable mask. */ //4. Configure Capture/Compare register TIM2_CCR1H = dutyCycle >> 8;
TIM2_CCR1L = dutyCycle & 0x00FF;//

// PWM mode 1.
//mengatur mode PWM dengan memberikan nilai pada TIM2 capture/compare mode register 1
TIM2_CCMR1 = 0x60|0x08 ;
TIM2_CR1 = 0x01;//enable timer

enable_interrupts();
while(1){}
}



dari kedua cara diatas, saya sendiri lebih suka cara yang kedua, karena kita mendefinisikan sendiri register_register yang dipakai, sehingga lebih mudah dipahami. Dalam program yang kedua, disana terdapat variable yang bernama dutyCycle, perubahan nilai tersebut akan mempengaruhi besar kecilnya duty cycle dari PWM. Apabila kita ingin mencoba mengontrol putaran motor servo, kita bisa mencoba merubah-rubah nilai dari dutyCycle tersebut

Comments