oled+w25x16+vs1003編程經驗

1.
請注意區分 全局變量以及局部變量的區別,局部變量纔會在堆棧中,全局變量是在靜態存儲區,不會出現在堆棧內,全局變量的大小受到SRAM大小的影響,局部變量的大小受到STACK大小的影響

2.
/—-The Length of This Array is 76711 Byte.—-/
const unsigned char music[]=
{
}
嵌入式系統高級C語言編程P31:很多嵌入式微處理器的編譯器在處理const關鍵字修飾的變量時,往往會將這些變量的地址分配在ROM的地址空間。eg:Program Size: Code=10204 RO-data=74456 RW-data=56 ZI-data=5344
這裏寫圖片描述

3.
我在main.c 中定義 u8 datatemp[SIZE];(SIZE==76711 )。
datatemp是局部變量,即auto自動變量,它會被存儲在堆棧中,或者被存儲在CPU的寄存器中。
stm32f103rc哪有那麼大的堆棧,記住那個程序正確下載,系統卻毫無動作的現象。

昨天,datatemp和SPI_FLASH_BUF分開,可以播放卻不能寫入flash,原因是可能是datatemp這個buf先在堆棧中建立,到調用SPI_Flash_Write這個函數時,datatemp還沒有釋放,無法再堆棧中建立這個SPI_FLASH_BUF,所以程序無法執行。程序停在了SPI_Flash_Write這個函數的位置,不在往下執行。
(這個總結是錯誤的,下面重新總結)
flash.c:
u8 SPI_FLASH_BUF[4096];
void SPI_Flash_Write(u8* pBuffer,u32 WriteAddr,u16 NumByteToWrite)
{
}
flash.h
extern u8 SPI_FLASH_BUF[4096];

SPI_FLASH_BUF是一個全局變量,編譯器在編譯過程中將全局變量映射在普通內存中,在程序的整個執行期間該變量始終佔據編譯器爲它分配的內存空間,它始終保持原來的值,直到對這個變量進行賦值操作或是程序結束,全局變量是靜態的。
SPI_FLASH_BUF[4096] 遠大於arm的堆棧1M堆棧空間,datatemp和它公用,佔用普通內存,沒有佔用堆棧空間。

今天,datatemp和SPI_FLASH_BUF共用,可以先寫入,再讀出播發。

現在,發現一個問題,原來的datatemp和SPI_FLASH_BUF共用,可以先寫入,再讀出播發,但是卻不能讀出播放後再進行寫入,這是一個bug,需繼續解決。

現在是11.33終於找出了這個bug,原來if(key==1){}和if(key==3)這兩個程序段公用了變量count_times,它在main.c的一開頭定義。
在if(key==3){}中記得了u8 count_times=0;但是在if(key==1){}卻沒有,所以先執行key==3再執行key==1,if(key==1){}中用的變量就是直接遺留的。所以在
printf(“count=:%d\n”,count);
SPI_Flash_Write((u8*)(&music[65535*count_times]),cal,count);
OLED_6x8Str(0,3,”W25X16 Write Finished!”);//提示傳送完成
處出現程序停滯。

suffer:在 if(key==1){}和if(key==3){}中分別定義count_times,減小程序段之間的耦合性,降低bug,提高程序穩定性。

4.
u32 count;
//if(count<0)break; //suffer:無符號數不可能小於零,%d按有符號數打印

5.
if(key==3)//WK_UP按下,讀取寫入的字符傳字符串並顯示
{
u8 count_times=0;
OLED_Fill(0x00);
OLED_6x8Str(0,0,”Start Read W25X16…. “);
OLED_6x8Str(0,1,”Start play music…. “);
。。。。
}
suffer:程序段中變量定義要放在最前面,不然會報這個錯誤
declaration may not appear after executable statement in block

6.
key=KEY_Scan(0);
if(key==2)
{
//key=0;
vol+=0x10;
Mp3WriteRegister(0x0b,vol,vol);
printf(“vol=:%d\n”,vol);
}
TXDCS_SET( 0 );
suffer:添加一個 TXDCS_SET( 0 );就能實現音量控制,這需要好好研讀代碼,不懂代碼,隨便添加一點程序就會出現意想不到的bug。

  1. 值得學習:
    void SPI_Flash_Write_NoCheck(u8* pBuffer,u32 WriteAddr,u16 NumByteToWrite)
    {
    u16 pageremain;
    pageremain=256-WriteAddr%256; //單頁剩餘的字節數
    if(NumByteToWrite<=pageremain)pageremain=NumByteToWrite;//不大於256個字節
    while(1)
    {
    SPI_Flash_Write_Page(pBuffer,WriteAddr,pageremain);
    if(NumByteToWrite==pageremain)break;//寫入結束了
    else //NumByteToWrite>pageremain
    {
    pBuffer+=pageremain;
    WriteAddr+=pageremain;

    NumByteToWrite-=pageremain; //減去已經寫入了的字節數
    if(NumByteToWrite>256)pageremain=256; //一次可以寫入256個字節
    else pageremain=NumByteToWrite; //不夠256個字節了
    }
    };
    }

發佈了51 篇原創文章 · 獲贊 26 · 訪問量 8萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章