Merhaba,
Stm32f051 DiscoveryBoard ile bir çalışmada veriyi başlangıçta yazmam, sonrasında okumam gerekti. EEPROM Pahalı olduğundan sanırım, STM firması işlemcilerine bu üniteden koymuyor. Belki var olan serileri mevcuttur ama ben bilmiyorum.
EEPROM uygulamasını STD ile ve Register Kodlamasıyla ile yapmıştım ama hiç HAL ile yapmamıştım. Hem çalışma olur demiştim. Tabiki hayat dikensiz gül bahçesi değil. Yazmadı.
Şimdi neden yazmadığını ve çözümünü hızlaca anlatmaya çalışacağım. Ama önce şu belgeyi indiriniz.(flash açıklama belgesi)
Stm32 de flash belleğe veri yazmak için önce silinmesi gerekiyor. Silme işleminde adres için değil, adresi barındıran PAGE in tamamı için yapılıyor. Dökümanında geçen tabir “The Flash memory can be erased page by page or completely (Mass Erase).”
Bu arada unutmadan yazayım, çok sık veri yazmaya silmeye uygun bir çevresel birim değildir flash. Eğer öyle bir ihtiyacınız varsa harici bir EEPROM kullanınız.
Veriyi Yazmak İçin önce Flash ın kilidini açmak, Silmek, Yazmak ve son olarakta tekrardan kilitlemek gerekiyor. Bunlar için HAL içerisinde fonksiyonlar tanımlanmış.
İlk Yapmamız gereken Flash ın kilidini açmak.Aşağıdaki kod düzgünce yapıyor bu işlemi.
1 |
HAL_FLASH_Unlock(); |
Sonra Gerekli PAGE silmek. Ben Burada Flash belleğin son PAGE ini kullanacağımdan adresi ona göre verdim.(0x0800 FC00). Alimallah uygulamamızın yazıldığı belleği silmeyelim yoksa. Dikkat etmek, hangi Page in hangi adresten başladığını bilmek gerek. Bunun için STM mühendisleri belgeler hazırlamış. (REF_MAN Table 4 Page 55)
Silme işlemi için aşağıdaki fonksiyonu çağırmanız yeterli oluyor(mu ?).
1 |
FLASH_PageErase(adr); |
İçeriğinde neler dönüyor bakalım. stm32f0xx_hal_flash_ex.c dosyasının içerisindedir.
1 2 3 4 5 6 7 8 9 10 |
void FLASH_PageErase(uint32_t PageAddress) { /* Clean the error context */ pFlash.ErrorCode = HAL_FLASH_ERROR_NONE; /* Proceed to erase the page */ SET_BIT(FLASH->CR, FLASH_CR_PER); WRITE_REG(FLASH->AR, PageAddress); SET_BIT(FLASH->CR, FLASH_CR_STRT); } |
Burada önce PER bitini set etmiş, gerekli adresi yüklemiş ve STRT bitini set etmiş. Aşağıdaki şekile göre doğru.(flash açıklama belgesi Sayfa 15)
Sırada Veriyi yazmak var. Aşağıdaki Fonksiyon 16 bitlik bir veriyi belirtilen adrese yazmayı sağlıyor.
1 |
HAL_FLASH_Program(FLASH_TYPEPROGRAM_HALFWORD, adr, data); |
bu fonksiyonun da neler yaptığını son tahlilde nerede işlem yaptığına bakalım.
1 2 3 4 5 6 7 8 9 10 11 |
static void FLASH_Program_HalfWord(uint32_t Address, uint16_t Data) { /* Clean the error context */ pFlash.ErrorCode = HAL_FLASH_ERROR_NONE; /* Proceed to program the new data */ SET_BIT(FLASH->CR, FLASH_CR_PG); /* Write data in the address */ *(__IO uint16_t*)Address = Data; } |
Yukarıda yapılan iki işlem var. PG bitini set etmiş ve belirtilen adrese data yı yazmış.Ama nedense verilen data yı adrese yazmıyor. burada bir hata olabileceğini düşünürken Register seviyesi kodlamalarla karşılaştırmak geldi. Karşılaştırmalarım sonucunda aşağıdaki sonuçlara ulaştım ve HAL LIB ile yazma ve okuma aşağıdaki halini aldı.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
void halWriteFlash(uint32_t adr, uint16_t data){ HAL_FLASH_Unlock(); FLASH_PageErase(adr); FLASH->CR &= ~0x00000042;// PER ve STRT yi RESET yap diğer bitleri değiştirme. HAL_FLASH_Program(FLASH_TYPEPROGRAM_HALFWORD, adr, data); HAL_FLASH_Lock(); } uint32_t flashRead(uint32_t flashAdress ){ uint32_t flashData; flashData=*(uint32_t*)flashAdress; return flashData; } |
Son olarak Flash i kitlemek kaldı.
1 |
HAL_FLASH_Lock(); |
Kütüphaneler Bizlere yaklaştıkça makinelere uzaklaşıyor malumunuz olduğu üzere. Program boyutları büyüyor. Hızları geriliyor. HAL lib ile alakalı çok şikayet duyuyorum. Çoğu geliştirici ya LL yada STD kullanıyor. Register kullananlarda ve ASM kullanan tanıdıklarımda mevcut ama onları STD Sapmanın dışında görüyorum. STM in hala bu hatalarla geliştiricileri uğraştırmaması gerekir.
Saygı ve Sevgilerimle.
FLASH_PageErase(adr); kodundaki adr yerine ne yazmamız gerekir
stm32f103c8t6 referans manual de page127 de işlem yapmak istiyorum ve bununkarşısındaki değer 0x0803F800 şeklide bunu yazınca kabul etmiyor