編程那些事兒(持續更新中)

    現在在用STC12C5A60S2單片機做32*128的LED點陣,各種糾結的問題是遇到不少的。當然,其實大都是一些常識性的錯誤,但是這些對於初學者而言,如果沒有人指導,自己又不喜歡去看書,很難找到錯誤的原因。我就遇到一些,現在逐漸總結出來。

//問題代碼一(eeprom數據寫入程序):
unsigned char i;	
for(i=0;i<256;i++)	//將數據寫入eeprom中
  {	     
     Byte_Program(eeprom_address+i,0x5a);	
  }

這是一段EEPROM的寫入程序,此單片機EEPROM的第一扇區地址爲00H--1FFH。然後發現數據老是寫不進去,而把循環變量改爲i<255後纔可以寫進去,可是我的數據有256字節啊。。。當時爲這個問題糾結了很久很久。聰明的你是不是一下子找到了問題所在呢?對,就是i的聲明問題。要知道unsigned char型變量的範圍是0-255哦親!i永遠不可能自增到256的,判斷條件失效,所以根本無法跳出for循環(其實不是沒寫進去,而是後面的eeprom讀程序根本執行不到,一直在這個for裏兜圈圈,至於寫沒寫進去俺就不知道啦)。

ok,改成下面的就行了:

//修改後代碼(eeprom數據寫入程序)
unsigned int i;	
for(i=0;i<256;i++)	//將數據寫入eeprom中
  {		  
     Byte_Program(eeprom_address+i,0x5a);	
  }

接着上程序~

//問題代碼二(eeprom扇區擦除程序):
 unsigned int eeprom_address;   
 Sector_Erase(eeprom_address);      //擦除將該eeprom_address所在的扇區整個擦除
  for(i=0;i<=255;i++)                        //將數據寫入eeprom中
    {
        Byte_Program(eeprom_address+i,0x5a);        
    }

咦我寫的數據每次居然還不一樣耶真是好玩。之後那又是怎樣一陣瘋狂的查找錯誤不斷調試刻骨銘心的歷程啊!

看出有什麼問題了嗎? 哎,要是沒看出來你跟我一起去面壁思過吧。以後一定要記住記住:申明地址變量時一定一定,要賦初值!要不然誰TM知道系統給的是什麼初值?然後運氣好給的初值在00H-0FFH之間(eeprom第一扇區的地址區間),然後可以順利擦除該扇區,運氣不好的話系統隨機給的地址不在這個區間中(注:eeprom的擦除是按扇區擦除的,只需要你給出扇區中的任何一個地址,即可擦除整個扇區),需要擦除的扇區就沒有擦除,自然有可能寫不進去了。

//修改後代碼(eeprom扇區擦除程序)
 unsigned int eeprom_address=0; 
 Sector_Erase(eeprom_address); //擦除將該eeprom_address所在的扇區整個擦除
 for(i=0;i<=255;i++) //將數據寫入eeprom中 
  { 
        Byte_Program(eeprom_address+i,0x5a); 
  }

關於賦初值的問題再多說一點:

《你必須知道的495個C語言問題》(Steve Summit著)有這麼一段(第18頁):

具有靜態生存期的未初始化變量(包括數組和結構)——即在函數外聲明的變量和靜態存儲類型的變量確保初始值爲零,就像程序員鍵入了‘=0’或‘={0}’一樣。因此,這些變量如果是指針就會被初始化爲正確類型的空指針,如果是浮點數則會被初始化爲0.0。

具有自動(automatic)生存期的變量(即非靜態存儲類型的局部變量)如果沒有顯式地初始化,則包含的是垃圾內容。對垃圾內容不能作任何有用的假定。

用malloc和realloc動態分配的內存也可能包含垃圾數據,因此必須由調用者正確地初始化。用calloc獲得的內存全爲零,但這對指針和浮點值不一定有用。

簡單點理解,似乎是全局變量默認是0(據說在linux下全局變量默認值不是0.),局部變量默認的就不是0,數組和結構體也一樣。

C菜鳥們,讓我們進一步探索——神馬是靜態生存期和自動生存期?

 



發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章