Arkadaşlar merhaba ben Yusuf, bu yazıda sizlerle alışık olduğumuz Arduino programlamadan çıkıp daha yetenekli olan STM32 kodlamayı öğreneceğiz. Amacım sizlere temel seviyede STM32 kodlamasını en sade biçimde anlatmak olacak. Bu seride kullanmak için STM32F103 mikrodenetleyicisini seçtim, detaylarını yazımın devamında bulabilirsiniz. Kafanıza takılan herhangi bir soruyu yorum atarak sorabileceğiniz gibi öneri ve eleştirilerinizi de bekliyorum.

MALZEMELER

  1. STM32F103 Arduino Mini Geliştirme Kartı(Blue Pill)
  2. USB-UART Dönüştürücü

NOT: Geliştirme kartınızı satın aldığınızda üzerindeki çipin STM firmasının ismini ve logosunu barındırdığından emin olunuz. Aksi halde gelen CKS firmasına ait çipli kartları satın aldığınız yere başvurarak orijinalleri ile değiştirin.

STM32 NEDİR?

STMicroelectronics firması tarafından geliştirilen 32bit mikrodenetleyici ailesidir. Seri olarak F0, F1, F2, F3, F4, F7 gibi serileri bulunmaktadır. Bu eğitimde F1 serisine ait olan STM32F103C8T6 mikrodenetleyicili blue pill isimli kartı kullanacağım. Bu kartın en belirgin özelliklerinden birisi çok güçlü bir Arduino Nano alternatifi olmasıdır. Ayrıca diğer serilere göre daha ucuz ve ulaşılabilir olmasıdır.

STM32F103 ÖZELLİKLERİ

  • Çekirdek: Cortex-M3;
  • Çalışma Frekansı: 72MHz;
  • Depolama Kaynakları: 64K Byte Flash, 20KByte SRAM;
  • Arayüz Kaynakları: 2x SPI, 3x USART, 2x I2C, 1x CAN, 37x I / O ports,
  • ADC: 2x ADC (12-bit / 16-kanal)
  • Timers: 3 genel timer ve 1 advanced timer

Aşağıda Arduino Nano ile küçük bir karşılaştırmasına ait görsel bulunmaktadır.

Burada ise detaylı bir pinout görseli bulunmakta.

DEVRE ŞEMASI

Gerekli programlara geçmeden önce bu kartımızda bir UART dönüştürücü olmadığını belirtmek isterim. Kartımız kendisini HID olarak gösterebildiği için bir adet micro usb girişine sahip. Bu nedenle kodlarımızı yüklemek için bir USB-UART dönüştürücü kullanacağız aşağıda devre şemasını görebilirsiniz.

Not: Yükleme yapmadan önce yukarıdaki şemaya göre üstteki BOOT0 jumperını bir kenara kaydırıp birkaç defa reset atmanız lazım aksi takdirde STM32F103 mikrodenetleyicisi yükleme moduna giremez ve kod yükleyemezsiniz. Kod yükleme işlemi bittikten sonra tekrar eski yerine getirip reset attığınızda kodunuzun çalıştığını göreceksiniz.

YAZILIMLAR

CubeMX Kurulumu:

Şimdi sırada gerekli programları kurmak var. Öncelikle buradan STM32CubeMX isimli programı indirmemiz gerekiyor sayfa açıldıktan sonra aşağıda da görebildiğiniz alana gelip işletim sisteminizle uyumlu olan sürümü indirmeniz gerekmektedir.

Get Software dedikten sonra uygulamamızın inmesini bekliyoruz. İnen programı çalıştırdığımızda böyle bir programla karşılaşacağız.

Next dedikten sonra kullanıcı sözleşmesini kabul ediyoruz.

Tekrar next dedikten sonra Gizlilik Sözleşmesi’ni onaylıyoruz

Tekrar next dedikten sonra yükleme konumunu seçip next diyerek kurulumu tamamlıyoruz.

Keil Kurulumu:

Şimdi sırada KEİL editörünü yüklemekte. Buradan indirebilirsiniz. Sayfayı açtığınızda böyle bir ekran gelecektir istenilen bilgileri girdikten sonra Submit diyoruz.

Daha sonra altı çizili olan yere tıklayarak programı indiriyoruz.

İnen programı çalıştırdığımızda böyle bir ekran ile karşılaşacağız. Next diyerek devam ediyoruz.

Daha sonra kaşımıza bu ekran geliyor Kullanıcı Sözleşmesi’ni onaylayıp devam ediyoruz.

Şimdi ise karşımıza gelen bu ekranda istenilen bilgileri girerek devam ediyoruz.

Kurulum tamamlandıktan sonra karşımıza böyle bir sekme çıkacak. Sol taraftaki menüden STMicroelectronics>STM32F1 Series> STM32F103>STM32F103C8 dizinine gelip sol tıklıyoruz daha sonra sağ taraftaki menüde mavi ile gösterilen dizindeki Install tuşuna tıklayıp kurmasını bekliyoruz.

Paket kurulduktan sonra bu sekme ie işimiz bitiyor kapatabilirsiniz.

Demonstrator Kurulumu:

Son programımız olan Demonstrator programını buradan indirip diğerleri gibi hızlıca kuruyoruz..

CubeMX Ayarları:

Şimdi ise sırada mikrodenetleyicinin konfigürasyonunu yapacağımız CubeMX uygulamasında. Uygulamamızı açtığımızda karşınıza böyle bir ekran gelecektir. Buradan “ACCESS TO MCU SELECTOR” butonuna tıklıyoruz.

NOT: Eğer sizde CubeMX’in masaüstü kısayolu oluşmadı ise buradaki dizinde bulabilirsiniz “C:\Program Files\STMicroelectronics\STM32Cube\STM32CubeMX”

Açılan bu ekranda üzerinde çalışacağımız mikrodenetleyiciyi seçmemiz lazım. Bunun için soldaki altı çizili alana mikrodenetleyicimiz olan STM32F103C8’i yazıyoruz. Daha sonra alt tarafta altı çizili olan yere gelen mikrodenetleyicimize çift tıklıyoruz.

Daha sonra mikrodenetleyicimizin pinlerini ayarlayacağımız bu ekrana geleceğiz. Mikrodenetleyicinin soldan 2. olan PC13 pinine sol tıklayarak. Açılan menüden GPIO_Output seçeneğine tıklıyoruz. Daha sonra bir isim verebilmek için sağ tıklayıp Enter User Label seçeneğine tıklayıp bir isim veriyoruz. Ben ilk proje için kartın üzerinde bulunan ledi yakıp söndürecek blink projesini yapacağım için LED ismini verdim.

Daha sonra sol taraftaki menüden System Core > RCC kısmına geliyoruz ve hemen yanında açılan menüden High Speed Clock(HSE) seçeneğine tıklayarak Crystal/Ceramic Resonator seçeneğini seçiyoruz.

Şimdi ise mikrodenetleyicimizin frekans ayarlarını yapmak var bunun için üst taraftaki menüden Clock Configuration kısmına geliyoruz. Altı çizili olan yeri (büyük ihtimalle sizde 8 yazıyor olacaktır) 72 ile değiştirip enter tuşuna tıklıyoruz ve gelen uyarılara yes dedikten sonra karşımızda aşağıdaki gibi bir ekran oluşacaktır.

Şimdi ise üst menüden Project Manager kısmına geliyoruz. Buradan önce Project Name kısmından projemize isim veriyoruz ben Blink ismini verdim. Hemen altından ise projemizin klasörünü seçiyoruz daha sonra Toolchain/IDE kısmından MDK-ARM, Min Version kısmından ise son versiyonu seçiyoruz. Ayarlarımızı yaptıktan sonra ekranımız aşağıdaki görseldeki gibi olacaktır. Her şeyi tamamladıktan sonra sağ üstten GENERATE CODE tuşuna basıyoruz ve gerekli dosyaların hazırlanmasını bekliyoruz. Gerekli dosyalar oluşturulduktan sonra gelen ekranda Open Project diyoruz ve daha önce kurduğumuz Keil programının açılmasını bekliyoruz.

KODUN İNCELENMESİ

Kodun Yazılması:

Keil açıldıktan sonra sol taraftaki menüden Project: Blink > Blink > Application/User/Core/main.c dosyasını açıyoruz.

CubeMX uygulaması kodlama kısmındaki yorucu olan tanımlama gibi kısımları otomatik oluşturdu. Ancak yine de bir göz atmakta fayda var. Aşağıdaki örnekte olduğu gibi kodumuzda USER CODE BEGIN ve USER CODE END yorum satırları var. Eğer kodlarınızı bu BEGIN ve END kısımları arasına yazarsanız, CubeMX ile ayarları değiştirdikten sonra tekrar kodları oluşturduğunuzda buralardaki kodlar silinmeyecektir. Ben de kodlarımı buna göre yazacağım.


/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */

/* USER CODE END Includes */

/* Private typedef -----------------------------------------------------------*/
/* USER CODE BEGIN PTD */

/* USER CODE END PTD */

/* Private define ------------------------------------------------------------*/
/* USER CODE BEGIN PD */
/* USER CODE END PD */

/* Private macro -------------------------------------------------------------*/
/* USER CODE BEGIN PM */

/* USER CODE END PM */

Kodumuzu başlıklar halinde inceleyecek olursak.

Bu kısım Arduino’daki void setup ile aynı görevdedir yani tanımlama gibi tek seferlik kodları yazdığımız kısımdır.

int main(void)
{
...
}

int main(void) fonksiyonu içinde bulunan bu kısımda ise döngü yani sürekli tekrarlanacak kodlarımızı yazdığımız kısımdır.

while (1)
{
...
}

Bu kısımlarda değişiklik yapmayacağız ancak bilmekte fayda var. Bu kısımda mikrodenetleyicimizin frekans ayarları yer almakta.

void SystemClock_Config(void)
{
...
}

Burada ise GPIO pinlerimizin tanımlamaları yer almakta. Burada bulunan “HAL_GPIO_WritePin(LED_GPIO_Port, LED_Pin, GPIO_PIN_RESET);” komutu gpio pinimizin başlangıç durumunu göstermekte yani burası mikrodenetleyici çalışmaya başladığında pin 0 mı olsun yoksa 1 mi olsun sorusunun cevabı olan kısım.

static void MX_GPIO_Init(void)
{
...
}

Void main’de yer alan while(1) kısmına tekrar geri dönüyoruz. “}” ile “USER CODE BEGIN” arasına ilk fonksiyonumuz olan “HAL_GPIO_WritePin(LED_GPIO_Port, LED_Pin, GPIO_PIN_SET);” fonksiyonunu yazıyoruz. Bu fonksiyon basitçe LED portundaki LED pinine 1 yani HIGH durumuna geçmesi gerektiğini söylüyor. Aynı şekilde eğer SET yerine RESET yazacak olursak 0 yani LOW durumuna geçmesi söylenecek. Kodumuzda ilgili yerin bu şekilde gözükmesi gerecek.

  /* USER CODE BEGIN WHILE */
  while (1)
  {
    /* USER CODE END WHILE */

    /* USER CODE BEGIN 3 */
     HAL_GPIO_WritePin(LED_GPIO_Port, LED_Pin, GPIO_PIN_RESET);
     HAL_Delay(500);
     HAL_GPIO_WritePin(LED_GPIO_Port, LED_Pin, GPIO_PIN_SET);
     HAL_Delay(500);
  }
  /* USER CODE END 3 */


Kodlarımızı yazdıktan sonra main.c dosyamız bu şekilde olacaktır.



#include "main.h"



void SystemClock_Config(void);
static void MX_GPIO_Init(void);

int main(void)
{
  HAL_Init();


  SystemClock_Config();

  MX_GPIO_Init();
  
  while (1)
  {
   
    /* USER CODE BEGIN 3 */
        HAL_GPIO_WritePin(LED_GPIO_Port, LED_Pin, GPIO_PIN_RESET);
	HAL_Delay(500);
	HAL_GPIO_WritePin(LED_GPIO_Port, LED_Pin, GPIO_PIN_SET);
	HAL_Delay(500);
  }
  /* USER CODE END 3 */
}

void SystemClock_Config(void)
{
  RCC_OscInitTypeDef RCC_OscInitStruct = {0};
  RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};


  RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI;
  RCC_OscInitStruct.HSIState = RCC_HSI_ON;
  RCC_OscInitStruct.HSICalibrationValue = RCC_HSICALIBRATION_DEFAULT;
  RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
  RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSI;
  RCC_OscInitStruct.PLL.PLLM = 13;
  RCC_OscInitStruct.PLL.PLLN = 195;
  RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV2;
  RCC_OscInitStruct.PLL.PLLQ = 4;
  if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
  {
    Error_Handler();
  }

  RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
                              |RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2;
  RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
  RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
  RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV4;
  RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV2;

  if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_3) != HAL_OK)
  {
    Error_Handler();
  }
}


static void MX_GPIO_Init(void)
{
  GPIO_InitTypeDef GPIO_InitStruct = {0};

  __HAL_RCC_GPIOC_CLK_ENABLE();


  HAL_GPIO_WritePin(LED_GPIO_Port, LED_Pin, GPIO_PIN_RESET);


  GPIO_InitStruct.Pin = LED_Pin;
  GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
  GPIO_InitStruct.Pull = GPIO_NOPULL;
  GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
  HAL_GPIO_Init(LED_GPIO_Port, &GPIO_InitStruct);

}


void Error_Handler(void)
{

  __disable_irq();
  while (1)
  {
  }

}


void assert_failed(uint8_t *file, uint32_t line)
{

}
#endif

NOT: Kodumuzun daha az yer kaplaması için yorum satırlarını sildim.

Kodumuzu yazdığımıza göre şimdi kodumuzu derleme ve yükleme kısmı geldi. Kodu derlemek için editörümüzün sol üst tarafında bulunan build tuşuna basıyoruz ve ekranın altında açılan konsol sekmesinden derlemenin tamamlanmasını bekliyoruz. Fotoğrafta ise altı çizili yer olarak karşımıza geliyor.

STM32F103 Mikrodenetleyicisine Kod Yükleme:

Derleme tamamlandıktan sonra Demonstrator uygulamamızı açıyoruz. Gelen ekranda UART dönüştürücünüzün takılı olduğu com portu seçip next diyoruz. Benim UART dönüştürücüm COM5 portunda olduğu için onu seçiyorum.
NOT: Bu işlemleri yapmadan önce mikrodenetleyicinizin yükleme modunda olduğuna emin olun.

Daha sonra gelen ekrana da next dedikten sonra karşımıza böyle bir ekran gelecek İlk olarak Download to Device’ı işaretliyoruz. Ardından Download from File kısmının yanındaki üç noktalı tuşa tıklıyoruz ve projemizin dosyasına gidiyoruz. Sırasıyla MDK-ARM/Blink klasörlerine giriyoruz ve sağ alttan dosya türünü .hex olarak değiştiriyoruz daha sonra ise ekrana gelen tek dosyayı seçiyoruz. Üç noktalı tuşun hemen altında yer alan Global Erase seçeneğini seçiyoruz. Ardından onun da altında bulunmakta olan Verify after download seçeneğini seçip next diyoruz.

Eğer tüm aşamaları doğru yaptıysanız böyle bir ekran ile karşılaşacaksınız. Tebrikler STM32F103 mikrodenetleyicisine ilk kodunuzu yüklemiş bulunmaktasınız. Şimdi yükleme yaparken yerini değiştirdiğiniz BOOT0 jumperini eski yerine alıp resetleyerek ledinizin yanışını izleyebilirsiniz.

BAĞLANTILAR

Proje dosyaları: https://github.com/REevee0/STM32F103_Blink
Usb-Uart dönüştürücü kullanımı: https://lezzetlirobottarifleri.com/arduino-karti-yerine-sadece-mikrodenetleyiciyi-kullanmak/

Instagram: https://www.instagram.com/lezzetlirobottarifleri/
Discord sunucusu: https://discord.gg/8MVnu59tkx