<meter id="pryje"><nav id="pryje"><delect id="pryje"></delect></nav></meter>
          <label id="pryje"></label>

          新聞中心

          EEPW首頁 > 嵌入式系統(tǒng) > 設(shè)計(jì)應(yīng)用 > 【51單片機(jī)】學(xué)習(xí)總結(jié)

          【51單片機(jī)】學(xué)習(xí)總結(jié)

          作者: 時(shí)間:2016-11-28 來源:網(wǎng)絡(luò) 收藏
          1. Ctrl+S為保存當(dāng)前文件,如圖

          打開了兩個(gè)文件,可以看到有個(gè)文件是帶星號(hào)且有個(gè)紅叉的,有個(gè)紅叉說明它為當(dāng)前打開的文件,也就是正在編輯的文件。當(dāng)按下Ctrl+S時(shí)只保存了當(dāng)前文件。另一個(gè)文件沒有保存,當(dāng)你的電腦意外斷電或死機(jī)時(shí),如果你在那之前按了Ctrl+S那么可以挽回點(diǎn)損失,可是另一個(gè)文件的信息可能就丟失了。所以推薦按F7(對所以文件進(jìn)行編譯,并且保存),這樣就可以在編譯的同時(shí)將所以文件保存一次。所以在真正做工程的時(shí)候就要學(xué)會(huì)定期按F7,不是說一定要程序編寫完整后才按F7。
          2. 默認(rèn)情況下頭文件和源文件應(yīng)該放在同一個(gè)文件目錄下,如果將頭文件放在一個(gè)獨(dú)立的文件夾中如名為include的文件夾,此時(shí)就讀取不出。要進(jìn)行一下設(shè)置才能讀取出來。如圖:

          在C51選項(xiàng)中的Include Paths 選項(xiàng)中要設(shè)置頭文件的路徑后方能打開頭文件,對頭文件進(jìn)行編譯!
          3. 對于不變化的變量,如數(shù)碼管顯示的數(shù)組,要通過前綴code將它放在ROM中避免占用了RAM的空間。
          4. 宏定義的內(nèi)容全用大寫字母,當(dāng)有兩個(gè)單詞時(shí)用_將他們分開,如#define LED_SEG P1_1;在特殊情況下才用小寫字母。
          5. 變量名的定義一般為 i , Led , DispBuff 即單個(gè)字母時(shí)小寫,多個(gè)字母一個(gè)單詞時(shí)首字母大寫,多個(gè)單詞時(shí)連寫且每個(gè)單詞的首字母大寫。
          6. 函數(shù)名的定義一般為 delay ,write_byte 即單個(gè)單詞時(shí)全小寫,多個(gè)單詞時(shí)也是小寫,但是單詞間用 _ 隔開。
          7. 不必糾結(jié)于該換行多少,空格多少,只要自己知道哪里該換行,哪里改空格就行了,像這些東西的尺度只有自己真正實(shí)踐的時(shí)候就能領(lǐng)悟出來。當(dāng)然這沒有絕對的標(biāo)準(zhǔn),就算是非常出色的工程師也很難做到精確的換行,當(dāng)是他們的程序整體看起來整齊有可讀性高就OK了。要懂得把精力放在恰當(dāng)?shù)牡胤健?br />8. 不要太死板,一定要照著那些條條框框,但我相信小宋老師我需要向他學(xué)習(xí),他的程序有很高的價(jià)值。
          9. 中斷函數(shù)書寫

          10. 在函數(shù)中無論是被調(diào)函數(shù)還是主函數(shù)都要懂得對一些變量進(jìn)行初始化,這是一個(gè)好習(xí)慣,別以為沒必要,或者繁瑣。這其實(shí)不是繁瑣,而是嚴(yán)謹(jǐn)。寫程序就應(yīng)該有嚴(yán)謹(jǐn)?shù)膽B(tài)度。
          11.main函數(shù)的標(biāo)準(zhǔn)寫法為:
          int main(void)
          {
          ……
          return 0;
          }
          12. 在定時(shí)器溢出進(jìn)入中斷時(shí),在執(zhí)行中斷時(shí)TF0或TF1會(huì)硬件(自動(dòng))清0,從新開始計(jì)數(shù)。但在串口發(fā)送或接受標(biāo)志位置1并引起中斷時(shí),在執(zhí)行中斷過程中TI或RI 需軟件(手動(dòng))清0.
          13. 有關(guān)UART通信定時(shí)器1模式2中 TH1 與 TL1(與TH1相等)的初始化。在實(shí)際計(jì)算中TH1 = 256 - 11059200/(12*32*9600); 可以計(jì)算得 TH1 = 0xFD; 但是當(dāng)你把TH1 = 256 - 11059200/(12*32*9600); 寫入編譯器中讓編譯器來完成計(jì)算時(shí),那么這樣寫就是錯(cuò)誤的了,在keil里默認(rèn)整數(shù)常量是 uint16 類型,取值為0~65535.故應(yīng)寫為TH1 = 256 – 11059200UL/(12*32*9600UL);要注意的是keil 對這類錯(cuò)誤不報(bào)錯(cuò)!
          14. 在串口通訊中,如:

          串口調(diào)試助手一般選擇“字符格式顯示”。如果想顯示數(shù)字則寫入語句UART_send_byte(‘8’) ,要注意顯示數(shù)字時(shí)只能顯示一位即0~9;想顯示字母時(shí)可寫入語句UART_send_byte(‘A’)。注意別掉了‘’尤其是寫數(shù)字時(shí)。寫字母丟失的話還會(huì)報(bào)錯(cuò)。寫數(shù)字丟失的話就不會(huì)報(bào)錯(cuò)。此時(shí)顯示的是數(shù)字相應(yīng)的ASII碼。
          15. 若uint8 temp = ‘A’; 則 temp = ‘A’ + 1 時(shí)temp = ‘B’ , 即字符與數(shù)字相加為對應(yīng)ASII碼相加。
          16. 在串口調(diào)試助手中,要發(fā)送字符時(shí)不用帶‘’因?yàn)檐浖呀?jīng)默認(rèn)帶上了。
          17. 關(guān)于對數(shù)組各元素賦值,有兩種方式,如uint8 table [11] = “how are you”; 另一種是 table[0] = ‘h’; table[1] = ‘o’;……其中第一種賦值只能在定義數(shù)據(jù)類型時(shí)使用,如上所示。
          在數(shù)據(jù)類型定義完畢后不能通過table [11] = “how are you”;來改變數(shù)組里面的元素,這樣做在keil 下會(huì)有警告!但不報(bào)錯(cuò),實(shí)際是不正確的。那么要改變數(shù)組的元素只能通過對里面元素逐個(gè)賦值。
          18. UART通訊是從低位開始接數(shù)據(jù),而I2C通訊是從高位開始接數(shù)據(jù)。
          19. 關(guān)于bit 類型的函數(shù)。如
          bit i2c_read_buf(uint8 *buf, uint8 addr, uint8 len)
          {
          while (len--)
          {
          if (i2c_readbyte(addr++, buf++))
          return 1;
          }
          return 0;
          }
          在主函數(shù)中可以直接寫為bit i2c_read_buf(&a, b, c); 也可以寫為 y = bit i2c_read_buf(&a, b, c),將函數(shù)的返回值給了y。
          20. uint8 table[] = “I”; 與 uint8 table[]={‘I’}; 兩者使用時(shí)等同,但是前者為字符串,故比后者多一個(gè)字節(jié)。
          21. 結(jié)構(gòu)體分配的地址是連續(xù)的。如:

          22. 關(guān)于結(jié)構(gòu)體指針問題。先看看以下一些程序通過結(jié)果進(jìn)行分析得出結(jié)論.程序如下:

          (1)結(jié)果為:44
          是否就說明結(jié)構(gòu)體指針 p 指向了整個(gè) int a 呢?
          (可以從第一個(gè)字節(jié)地址開始逐個(gè)指向下一個(gè)字節(jié)地址直到第4個(gè)為止)
          (2)接著把tmp={44}該為tmp={127};
          結(jié)果為:127
          依然正確
          (3)繼續(xù)改為tem={128};
          結(jié)果為:-128
          顯然不是我們想要的,倘若 p 指向了整個(gè) int a,那么結(jié)果應(yīng)該為 128 才對,顯然*p 只是指向int a的第一個(gè)地址。不會(huì)自動(dòng)指向下一地址繼續(xù)將剩下的3個(gè)字節(jié)讀完,只有將剩下的三個(gè)字節(jié)讀完才能讀取一個(gè)完整的INT型數(shù)據(jù)。以上是在指針為char 類型的時(shí)候。(4)承接上面的,繼續(xù)把char *p 改為 int *p
          結(jié)果為 128
          正常了。為什么?因?yàn)閏har類型指針一次只能放一個(gè)地址(一個(gè)字節(jié)一個(gè)地址),
          而int *p 一次能放4個(gè)地址,所以此時(shí) p 可以一次指向4個(gè)int a 的四個(gè)地址
          23. *p+1 的運(yùn)算順序是先 *p 后 +1,不要誤以為是*(p+1).
          24. 如有數(shù)組 int table[]={111,323,3423,3322}; 指針 char *p; 且 p = &table;
          那么 p 指向了一個(gè)地址(table的首地址),至于可以指向幾個(gè)地址這個(gè)由指針的類型決定?,F(xiàn)在指針類型為char而char占一個(gè)字節(jié)只能放一個(gè)地址,所以 p 一次只能指向一個(gè)地址,所以 *p != 111,因?yàn)?p只讀取了111的第一個(gè)地址的數(shù)據(jù),還有三個(gè)地址的數(shù)據(jù)沒讀。注意此時(shí) p+1不指向table[1]這個(gè)元素的首地址。而是指向第一個(gè)元素的第二個(gè)地址??梢宰鲆幌赂纳苼硪淮巫x取4個(gè)地址,即讓指針一次指向int類型數(shù)據(jù)的4個(gè)地址。
          把 char *p改成 int *p,這樣就可以一次指向四個(gè)地址了。則 *p = 111, *(p+1) = 232;注意括號(hào)一定要帶上,不然結(jié)果是 112.
          可以得出結(jié)論。p不是指向一個(gè)地址,指向幾個(gè)地址由p 的數(shù)據(jù)類型決定。p + 1不是代表下一個(gè)地址。如 int *p,則p+1代表下一段連續(xù)的4個(gè)地址。可以理解為 p+1指向了4個(gè)連續(xù)的地址。在進(jìn)行*(p+1)運(yùn)算后將4個(gè)地址的數(shù)據(jù)連續(xù)讀取出來,合成了一個(gè)完整的int類型的數(shù)據(jù)。
          25. 有關(guān)數(shù)組的長度。如 uint8 table[]={‘a’}; 與 uint8 table[]=”a”; 后者是用字符串形式來進(jìn)行初始化。需要注意的是 若有 uint8 *p=&table. 對于兩者均有 *p=‘a’;可是對于 *(p+1)兩者的情況卻是不同的,后者有 *(p+1)= ‘’; 而前者卻沒有這種情況,在實(shí)際試驗(yàn)中是要推后幾位才有這種情況。
          26. 有關(guān)二進(jìn)制(BCD碼)與十六進(jìn)制的相互轉(zhuǎn)換,0xFF—0b1111 1111 ,0xFE—0b1111 1110.
          分別寫成第一個(gè)數(shù)字或字母所對應(yīng)的二進(jìn)制數(shù)即可。至于二進(jìn)制到16進(jìn)制的轉(zhuǎn)化也是如此,倒過來就是了。反正記著,4位二進(jìn)制數(shù)對應(yīng)一位十六進(jìn)制數(shù)。
          27. 字符類型數(shù)據(jù)(uint8)在與整數(shù)運(yùn)算時(shí)都是以ASII碼形式或十進(jìn)制數(shù)存在的。若uint8 型變量里面放的是字母或2個(gè)BCD碼(8421),8位二進(jìn)制數(shù),在于整數(shù)進(jìn)行運(yùn)算時(shí)可以看出是ASII碼或十進(jìn)制數(shù)的運(yùn)算。
          28. 別誤把if 語句當(dāng)成循環(huán)語句了,if語句在執(zhí)行時(shí)先判斷括號(hào)內(nèi)的語句是否成立,成立的話就執(zhí)行{}里的內(nèi)容(if語句嵌套的內(nèi)容)。如果成立那么執(zhí)行{}里的內(nèi)容,執(zhí)行完后不再進(jìn)行一次if的判斷,而是執(zhí)行下一語句,即便判斷仍然成立。主要還是要說明if不是循環(huán)語句,只判斷一次,無論成立與否,在執(zhí)行完所需內(nèi)容后就直接執(zhí)行下一語句。
          29. 關(guān)于取地址符號(hào)&的使用,變量本來就表示地址了,那么就不能再加&這樣會(huì)報(bào)錯(cuò)。特殊例子是數(shù)組名a,它本身就代表第一個(gè)元素的首地址。但可以使用取地址符號(hào),且不會(huì)報(bào)錯(cuò)。加去地址符號(hào)后&a表示的含義發(fā)生了變化而是代表該數(shù)組的首地址,數(shù)值上似乎與a的相同,但含義卻是有差別的。
          30. *p+1等價(jià)于(*p)+1,因?yàn)?優(yōu)先級(jí)高于+;*p++等價(jià)于*(p++),因?yàn)?+優(yōu)先級(jí)高于*;
          &a+1等價(jià)于(&a)+1.不能出現(xiàn)&(a+1)的情況,系統(tǒng)不認(rèn)同,會(huì)報(bào)錯(cuò)!
          31. 對于數(shù)組 int a[4]={1,2,3,4}; 其中 a+1表示第二個(gè)元素的首地址(第一個(gè)字節(jié)的地址)。而(int)a+1表示第一個(gè)元素第二個(gè)字節(jié)的地址。
          32. 關(guān)于結(jié)構(gòu)體變量命名。如圖

          這種命名方法在KEIL下會(huì)報(bào)錯(cuò),然而在VC++下卻沒問題。當(dāng)你把code改成其他字母(不要與原來的code一樣就行),你會(huì)發(fā)現(xiàn)都沒問題??梢钥闯霾⒉皇敲拇笮懗鰡栴}。原因是KEIL不認(rèn)同以結(jié)構(gòu)體小寫字母來命名(這里是指全小寫),當(dāng)你把其中一個(gè)字母該為大寫時(shí)就沒問題了。如把最后一行改成 CODE Code 讓變量名的第一個(gè)字母為大寫就行了。
          33. 單片機(jī)要進(jìn)行通信時(shí)要注意先關(guān)掉所有中斷(EA=0),在通信結(jié)束后才打開(EA=1).由于通信時(shí)通常要遵守時(shí)序,而中斷一旦被觸發(fā)便會(huì)打亂時(shí)序,使得傳輸數(shù)據(jù)失敗或者異常!注意通信中時(shí)序是非常重要的!
          34. 在通信過程中需要注意,比如在傳輸一個(gè)字節(jié)數(shù)據(jù)時(shí)是一位一位地傳讓后湊夠8位構(gòu)成一字節(jié)的。要從低位開始傳還是高位開始傳,要傳低位開始接還是高位開始接。這些不能處理好的話會(huì)直接影響到結(jié)果。也就是說發(fā)送端和接收端要保持一致,有兩種方式,一是從低位開始發(fā)(發(fā)送方),然后從低位開始接(接收方)。另一種就是從高位開始發(fā)(發(fā)送方),然后從高位開始接(接收方)。還有一個(gè)字節(jié)接收和發(fā)送的方向也要一致,只有這些保證了,才能保證信息準(zhǔn)確傳輸。比如:在UART通信中,如果你要用單片機(jī)IO口模擬UART通信就需要注意這些,一般采取UART通信的統(tǒng)一標(biāo)準(zhǔn),從低位開始傳輸。這樣跟標(biāo)準(zhǔn)UART器件就能很容易接上,不需要再作處理。當(dāng)兩個(gè)通信器件都接標(biāo)準(zhǔn)UART接口時(shí),那么就不用考慮這里了,這個(gè)在傳輸過程中他們自己會(huì)進(jìn)行處理,我們無需考慮。只要把字節(jié)的排序弄好就行了。位的處理他們會(huì)自己完成。
          35. 定時(shí)器1工作在模式1時(shí)的溢出是指在TH1=255(0xFF),TL1 =0的情況下,TL1達(dá)到255再 +1 就溢出了,此時(shí)溢出標(biāo)志位TF1=1,需要清零才能讓定時(shí)器繼續(xù)工作。否則不定時(shí),而是處于等待狀態(tài),等待TF1=0,然后才開始定時(shí)。要弄清什么時(shí)候才會(huì)溢出!
          還有就是TL1每加1表示已經(jīng)定時(shí)一個(gè)機(jī)器周期,在12T/11.0592MHz的單片機(jī)中機(jī)器周期為12/11059200 s 大約為1us.也就是說TL1每加1表示已經(jīng)定時(shí)1us 。而TH1加1就表示已經(jīng)經(jīng)歷了256個(gè)機(jī)器周期。這里說的+1并不會(huì)使定時(shí)器溢出,只有TH1達(dá)到255了那么接下來的256個(gè)機(jī)器周期后就會(huì)溢出了!


          評(píng)論


          技術(shù)專區(qū)

          關(guān)閉
          看屁屁www成人影院,亚洲人妻成人图片,亚洲精品成人午夜在线,日韩在线 欧美成人 (function(){ var bp = document.createElement('script'); var curProtocol = window.location.protocol.split(':')[0]; if (curProtocol === 'https') { bp.src = 'https://zz.bdstatic.com/linksubmit/push.js'; } else { bp.src = 'http://push.zhanzhang.baidu.com/push.js'; } var s = document.getElementsByTagName("script")[0]; s.parentNode.insertBefore(bp, s); })();