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。
值得学习:
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个字节了
}
};
}