St_Lib ile init edilmesi en kolay özellik SysTick.
SysTick basit bir timer. Diğer zamanlayıcıların input capture / output compare gibi özellikleri olduğu için, bu zamanlayıcıları sıradan zamanlama içi için kullanmak, işlemci kaynaklaını boşa harcamak demek.
Birçoğumuzun 1 milisaniylik bir zamanlayıcısı olur ve standart zamanlamarı bu zamanlayıcıdan alırız. Bu iş için Stm32 serilerinde bulunan SysTick zamanlayıcısını kullanabiliriz.
Zamanlayıcıyı ayarlamak ve başlatmak ST_Lib ile oldukça basit.
SysTick_Config(zamanlama değeri);
Tüm başlatma kodu bu kadar. Bu fonksiyon "CoreCm3.h" içerisinde tanımlı.
Zamanlama değerini nasıl hesap edeceğiz?
Hiç zamanlama hesabı yapmaya gerek yok.
SystemCoreClock değerini mikrosaniye cinsinden gireceğiniz değere bölmeniz yeter.
SysTick_Config(SystemCoreClock/100); // 100us zamanlayıcı elde ettik.
SysTick_Config(SystemCoreClock/1000); // 1000us = 1ms zamanlayıcı elde ettik.
SysTick_Config(SystemCoreClock/1000000); // 1saniye zamanlayıcı elde ettik.
Artık interrupt kodumuzu yazabiliriz.
void SysTick_Handler(void){
// Sizin kodunuz.
// örnek tick_counter++;
}
Hocam
Kesme Rutinine girildiğinde SysTick Değerinin Yeniden Yüklenmesi Gerekiyor.
SysTick_Config(SysTick_LOAD_RELOAD);
ile bu işlem yapılıyor.
Kesme rutinine girdiğimde yeniden yüklemiyorum. Zamanlamada bir sıkıntı yok şu ana kadar.
Alıntı yapılan: muhittin_kaplan - 17 Kasım 2012, 20:51:32
Hocam
Kesme Rutinine girildiğinde SysTick Değerinin Yeniden Yüklenmesi Gerekiyor.
SysTick_Config(SysTick_LOAD_RELOAD);
ile bu işlem yapılıyor.
Yeniden yüklemeye gerek yok hocam ama sanırım kesmeden çıkmadan hemen önce şu işlem gerekiyor.
STK_CTRL&= ~0x00010000; // Count Flagi sil
En azından ben yapıyorum.
#include "stm32f10x.h"
#include "stm32f10x_rcc.h"
#include "stm32f10x_gpio.h"
#include "stm32f10x_flash.h"
GPIO_InitTypeDef GPIO_InitStructure;
void SetSysClockTo24(void)
{
int i;
/* SYSCLK, HCLK, PCLK2 and PCLK1 configuration -----------------------*/
/* RCC system reset(for debug purpose) */
RCC_DeInit();
RCC_HSEConfig(RCC_HSE_ON); /* Enable HSE */
for(i=0;i<0x000FFFF;i++); /* Wait till HSE is ready */
FLASH_SetLatency(FLASH_Latency_0);
RCC_HCLKConfig(RCC_SYSCLK_Div1); /* HCLK = SYSCLK */
RCC_PCLK2Config(RCC_HCLK_Div1); /* PCLK2 = HCLK */
RCC_PCLK1Config(RCC_HCLK_Div1); /* PCLK1 = HCLK */
/* PLLCLK = (8MHz/2) * 6 = 24 MHz */
RCC_PREDIV1Config(RCC_PREDIV1_Source_HSE,RCC_PREDIV1_Div1);
RCC_PLLConfig(RCC_PLLSource_PREDIV1, RCC_PLLMul_3);
RCC_PLLCmd(ENABLE); /* Enable PLL */
while (RCC_GetFlagStatus(RCC_FLAG_PLLRDY) == RESET) /* Wait till PLL is ready */
{
}
RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK); /* Select PLL as system clock source */
while (RCC_GetSYSCLKSource() != 0x08) /* Wait till PLL is used as system clock source */
{
}
}
void SysTick_Handler(void){
int a;
a=GPIO_ReadOutputData(GPIOC);
if (a==0x000000200) {
GPIO_ResetBits(GPIOC,GPIO_Pin_9);
}
else {
GPIO_SetBits(GPIOC,GPIO_Pin_9);
}
//SysTick_Config(SysTick_LOAD_RELOAD);
}
int main(void)
{
SetSysClockTo24();
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC, ENABLE);
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_All ;
GPIO_Init(GPIOC, &GPIO_InitStructure);
SysTick_Config(12000000);
while(1)
{
}
}
Evet Haklısınız Hocam. gerek Yok O Komuta.
Yukardaki Kodlar 500ms ledin yanmasını ve 500Ms Sönmesini Saglıyor.(Sistem Saati24mhz)
-
merhaba,
kesme önceliği ile ilgili yapmış olduğunuz örnek var mı yada mevcut stdlib systick kesme önceliğini nasıl değiştirebiliriz ?
tşk.
Alıntı yapılan: Klein - 17 Kasım 2012, 06:20:18
SysTick_Config(SystemCoreClock/100); // 100us zamanlayıcı elde ettik.
SysTick_Config(SystemCoreClock/1000); // 1000us = 1ms zamanlayıcı elde ettik.
SysTick_Config(SystemCoreClock/1000000); // 1saniye zamanlayıcı elde ettik.
Systicki deniyordum ama sanki burada bir hata var zira 1000 için evet her halükarda 1ms yapıyor ama burada systemcoreclock / x dendigindeki x 1 sn nin bölümü oluyor.yani 10 ms için 100 değeri 100 us için 10000 degeri girilmeli.Denedim dediğim gibi çalışıyor ama x i 10 yaptıgımda nedense duzgun calismıyor
Evet yanlışlık var.
Değeri 10 yapamazsın. SYSTICK 24 bit. STM32F4 için SystemCoreClock 168000000.
ok hocam teşekkürler
SysTick_CLKSourceConfig(SysTick_CLKSource_HCLK_Div8);
Bu şekilde yaparak 1 saniye elde edebilirsiniz.Bu şekilde değer şu şekilde olur.10 sayısına bölünce 100ms elde ediliyormus.
SysTick_Config((SystemCoreClock/8)/10);
(168000000/8)/10 = 2100000 = 0x200B20
mesaj birleştirme:: 02 Temmuz 2015, 15:45:58
Alıntı yapılan: erolcalisgan - 17 Kasım 2012, 22:51:49
merhaba,
kesme önceliği ile ilgili yapmış olduğunuz örnek var mı yada mevcut stdlib systick kesme önceliğini nasıl değiştirebiliriz ?
teşekkür.
core_cm4.h dosyasında
NVIC_SetPriority(IRQn_Type IRQn, uint32_t priority) ;
kullanımı ise
NVIC_SetPriority(SysTick_IRQn, 0x04);
şeklindedir.
Systick in o anki değerini alabileceğimiz bir fonksiyon stdlibde tanımlı değil mi?
Hiç Görmedim hocam stdlibde baktım ama yok sanırım.
st lib'de fonksiyon olarak yok, aşağıdaki şekilde register olarak ulaşabilirsin,
u32 StickValue;
StickValue = SysTick->VAL;
veya doğrudan "SysTick->VAL"