Perhatikan pada function DelayMs, saya menggunakan down counter dimana nilai uDelayTimerCounter ditest apakah tidak bernilai 0. Mentest suatu variable dengan bilangan 0 lebih effisien daripada mentest variable <= X.
Tidak Efisien:
if(uDelayTimerCounter >= milis)
uDelayTimerCounter++;
Code diatas tidak effisien karena processor akan mentest overflow dari data type variable tsb.
Untuk membuat USER button berfungsi, clock pada APB2 GPIO A perlu dienable. USER button dalam discovery board dihubungkan pada port PA0.
Perhatikan pada main loop, kita mengambil nila dari USER button 2 kali dengan delay sebesar X ms. Ini dimaksudkan untuk memastikan apakah button masih ditekan.
file main.c
/* Includes */
#include
#include "stm32f10x.h"
volatile uint32_t uDelayTimerCounter;
void initBoard()
{
GPIO_InitTypeDef GPIO_InitStructure;
/* Aktifkan clock untuk portC. Lihat Discovery Board manual page 8 atau STM32F100RBT6B block diagram */
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC, ENABLE);
/* Enable GPIO Port A */
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
/* Konfigurasi led hijau di pin PC9*/
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;
/* Gunakan mode PushPull, led akan nyala bila diberi tegangan (aktif high) */
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
/* default speed 50Mhz, pin akan didrive sangat cepat */
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
/* Inisialisasi PORT C */
GPIO_Init(GPIOC, &GPIO_InitStructure);
/* Konfigurasi USER button di GPIO PA0*/
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;
/* Gunakan mode Input floating */
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
/* default speed 50Mhz, pin akan didrive cepat */
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
/* Inisialisasi PORT C */
GPIO_Init(GPIOA, &GPIO_InitStructure);
/* Konfigurasi systick timer setiap 1ms. Systick interrupt akan aktif setiap 1ms.
* Systick interrupt akan di handle oleh function Systick_Handler di file stm32f10x_it.c
* Note: Microcontroller pada board ini mempunyai clock max 24Mhz, dalam 1 detik clock ticknya 24.000.000
* berarti dalam 1/2 detik, clock tick 24Mhz/2 = 12Mhz
* Dalam 1ms clock tick adalah 24.0000
* Systick_Config akan error bila diberi nilai 24.000.000
*/
if (SysTick_Config(SystemCoreClock / 1000))
{
/* Capture error */
while (1);
}
}
void ledOn()
{
/* Set bit 1 to PC9 */
GPIO_SetBits(GPIOC, GPIO_Pin_9);
}
void ledOff()
{
/* Reset bit PC9*/
GPIO_ResetBits(GPIOC, GPIO_Pin_9);
}
void DelayMs(uint32_t milis)
{
uDelayTimerCounter = milis;
/* Loop sampai uDelayTimerCounter = 0
* Nilai uDelayTimerCounter akan berkurang tiap 1ms (lihat functino Systick_Handler)
* */
while(uDelayTimerCounter!=0);
}
int main(void)
{
int buttonState = 0; /* By default button is no pressed */
int ledStatus = 0;
initBoard();
ledOff();
/* Main loop. Never exit from this main loop */
while(1){
if(ledStatus == 0){
ledOn();
DelayMs(500);
ledOff();
DelayMs(100);
}
/* Nilai buttonState akan 1 apabila button dalam keadaan idle
* buttonState akan 0 apabila button ditekan
*/
buttonState = GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_0);
if(buttonState == 1){
/* Tunggu sebentar, check lagi apakah button masih ditekan */
DelayMs(50);
buttonState = GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_0);
if(buttonState == 1){
ledStatus = !ledStatus;
/* Tambah delay untuk nunggu button debounce */
DelayMs(500);
}
}
}
return 0;
}
file stm32f10x_it.c
/* Gunakan keyword extern apabila variable atau function
* dideclare di file lain
*/
extern void ledOn(void);
extern void ledOff(void);
extern uint32_t uDelayTimerCounter;
/**
* @brief This function handles SysTick Handler.
* @param None
* @retval None
*/
void SysTick_Handler(void)
{
if(uDelayTimerCounter!=0)
--uDelayTimerCounter;
}
Next PwM di STM32