STM32-内蔵フラッシュを正しく使用する

まえがき


STMicroelectronicsが注目すべき32ビットARMマイクロコントローラーSTM32を製造していることは誰にとっても秘密ではありません。 最近、彼らはますます人気を集めており、そのための正当な理由がありますが、この記事では繰り返しません。 誰が気にする-1、2、3。



しかし、人気の急上昇には不愉快な欠点があります-非常に多くの場合、記事の著者は同じ間違いを繰り返します。 メーカーの公式文書にも必要な瞬間が表面的に記載されている場合、悪魔は問題の解決策を見つけるまで足を骨折します。



私が伝えたいのはこの瞬間についてです。 つまり-MKの内蔵フラッシュに記録する機能を適切に使用する方法。 猫へようこそ。





マナを吸い、記事を読む


大部分の記事 (または、私が見たすべてのもの)は、 公式のフラッシュプログラミングマニュアルで推奨されているアルゴリズムの実装を提供しています 。 これは:







コード、コンパイル、チェック-すべてが機能します。 うまくいきます。 最適化を有効にするまで正確に。 gccを使用し、-O1および-O2スイッチでチェックしました。 最適化なしで機能します。 最適化あり-動作しません。 私たちは神経質に喫煙し、コーヒーを飲み、1〜2日を過ごして、存在の過渡期に関する問題や考えを探します。



方法


製造元が不適切に機能するアルゴリズムの使用を勧める理由がわかりません。 おそらくどこかで説明されたのかもしれませんが、2日間で何も見つかりませんでした。 解決策は非常に簡単であることが判明しました-FLASH-> SRレジスタでは、操作の終了を制御するために、BSYビットを使用する必要があります(STがそれを使用することをお勧めする理由を心から理解していません)が、EOPビットは現在の消去/書き込み操作の終了時に設定されます。



理由は簡単です-何らかの理由で、検証時に、BSYビットがまだ設定されていない可能性があります。 ただし、操作が完了したときにのみ、EOPビットが設定されます。 このビットは、ユニットに書き込むことにより手動でリセットされます。 コーディング、検証、人生を楽しみます。





写真を完成させるには、このトピックに関する他の記事を見つけて読む必要があります(それらへのリンクは上記にあります)。 ここに、簡単な説明とともにソースも添付します。



フラッシュのロック解除作業-これらの2行をMK初期化関数に挿入する必要があります。

FLASH->KEYR = 0x45670123; FLASH->KEYR = 0xCDEF89AB;
      
      







フラッシュページの消去-記録する前に、目的のアドレスのデータを消去する必要があります。これはフラッシュ機能です。

 //pageAddress -  ,    void Internal_Flash_Erase(unsigned int pageAddress) { while (FLASH->SR & FLASH_SR_BSY); if (FLASH->SR & FLASH_SR_EOP) { FLASH->SR = FLASH_SR_EOP; } FLASH->CR |= FLASH_CR_PER; FLASH->AR = pageAddress; FLASH->CR |= FLASH_CR_STRT; while (!(FLASH->SR & FLASH_SR_EOP)); FLASH->SR = FLASH_SR_EOP; FLASH->CR &= ~FLASH_CR_PER; }
      
      







記録:

 //data -     //address -   flash //count -   ,    2 void Internal_Flash_Write(unsigned char* data, unsigned int address, unsigned int count) { unsigned int i; while (FLASH->SR & FLASH_SR_BSY); if (FLASH->SR & FLASH_SR_EOP) { FLASH->SR = FLASH_SR_EOP; } FLASH->CR |= FLASH_CR_PG; for (i = 0; i < count; i += 2) { *(volatile unsigned short*)(address + i) = (((unsigned short)data[i + 1]) << 8) + data[i]; while (!(FLASH->SR & FLASH_SR_EOP)); FLASH->SR = FLASH_SR_EOP; } FLASH->CR &= ~(FLASH_CR_PG); }
      
      







これらはパイです。 優れたコーディングと少ないバグを持っています。



All Articles