1. 用c++怎樣編寫51單片機程序
相信很多初學者都有同樣的疑問,也有同樣的希望。就是用C++語言來寫單片機程序的源代碼。現在我來解釋一下單片機的源代碼程序幾乎沒有人用C++來寫的。
1. 假設一下你現在用C++寫完了一個程序代碼。那麼你要讓單片機認識必須要編譯吧,對吧 。請問你有合適的編譯軟體來編譯你的代碼嗎?
2. 就算有編譯器能編譯,你能保證它的代碼效率一定能給單片機用嗎?
單片機的ROM是K級的水平,執行指令的速度也遠遠小於PC。絕對不能和PC機相比的。這個就決定了單片機編程時很多時候要考慮它的代碼效率和代碼大小問題。所以一般情況下對於單片機編程我們之用匯編語言或者C語言。就算是用C寫程序也要注意代碼的效率等問題。
還有就是只有很大型的項目及應用程序開發才有可能有C++來寫程序。一般的系統文件,應用程序都是用C來寫的。有的系統代碼甚至要用匯編語言來寫。
舉個生活中的例子:如果你從家裡去公司上班你一般的出行方式是什麼?
1.坐公車 2.騎車 3.自己開車 4.坐地鐵 5.走過去。如果誰說他是做直升飛機去上班的。那要麼這個人腦子不正常,要麼就是太有錢了炫富。如果你要打蒼蠅用蒼蠅拍子就行了。如果要你用巡航導彈來打蒼蠅,你認為可能嗎?
所以我們單片機寫程序的話一般就是匯編語言和C語言。幾乎沒有人用C++語言的。
2. 快速學習單片機編程的方法
單片機匯編語言編程規范
軟體設計更多地是一種工程,而不是一種個人藝術。如果不統一編程規范,最終寫出的程序,其可讀性將較差,這
不僅給代碼的理解帶來障礙,增加維護階段的工作量,同時不規范的代碼隱含錯誤的可能性也比較大。分析表明,編碼
階段產生的錯誤當中,語法錯誤大概佔20%左右,而由於未嚴格檢查軟體邏輯導致的錯誤、函數(模塊)之間介面錯誤
及由於代碼可理解度低導致優化維護階段對代碼的錯誤修改引起的錯誤則佔了一半以上。可見,提高軟體質量必須降低
編碼階段的錯誤率。如何有效降低編碼階段的錯誤呢?這需要制定詳細的軟體編程規范,並培訓每一位程序員,最終的
結果可以把編碼階段的錯誤降至10%左右,同時也降低了程序的測試費用,效果相當顯著。
本文從代碼的可維護性(可讀性、可理解性、可修改性)、代碼邏輯與效率、函數(模塊)介面、可測試性四個方
面闡述了軟體編程規范,規范分成規則和建議兩種,其中規則部分為強制執行項目,而建議部分則不作強制,可根據習
慣取捨。
1.排版
規則 1
程序塊使用縮進方式,函數和標號使用空格縮進,程序段混合使用TAB 和空格縮進。縮進的目的是使程序結構清晰,便
於閱讀和理解。
<TAB>默認寬度應為8 個空格,由於Word 中<TAB>為4 個空格,為示範清晰,此處用2 個<TAB>代替(下同)。
例如:
MOV R1, #00H
MOV R2, #00H
MOV PMR, #PMRNORMAL
MOV DPS, #FLAGDPTR
MOV DPTR, #ADDREEPROM
read1kloop:
read1kpage:
INC R1
MOVX A, @DPTR
MOV SBUF, A
JNB TI, $
CLR TI
INC DPTR
CJNE R1, #20H, read1kpage
INC R2
MOV R1, #00H
CPL WDI
CJNE R2, #20H, read1kloop ;END OF EEPROM
規則2
在指令的操作數之間的,使用空格進行間隔,採用這種鬆散方式編寫代碼的目的是使代碼更加清晰。
例如:
CJNE R2, #20H, read1kloop ;END OF EEPROM
規則 3
一行最多寫一條語句。
規則 4
變數定義時,保持對齊。便於閱讀和檢查內存的使用情況。
例如:
RegLEDLOSS EQU 30H ; VARIABLE ;
TESTLED==RegLEDLOSS.0
RegLEDRA EQU 31H ; VARIABLE
RUNLED_Flag EQU 32H ; VARIABLE ;
256ms 改變一次RUNLED 狀態
RUNLED_Def EQU 10H ; STATIC ;
16*32ms=500ms 改變一次LED 狀態
2.注釋
注釋的原則是有助於對程序的閱讀理解,注釋不宜太多也不能太少,太少不利於代碼理解,太多則會對閱讀產生干擾,
因此只在必要的地方才加註釋,而且注釋要准確、易懂、盡可能簡潔。注釋量一般控制在30%到50%之間。
規則 1
程序在必要的地方必須有注釋,注釋要准確、易懂、簡潔。
例如如下注釋意義不大:
MOV DXCE1COUNTER, #00H ; 將DXCE1COUNTER 賦值為0
而如下的注釋則給出了額外有用的信息:
JNZ PcComm_Err ; 假如校驗出錯
規則 2
注釋應與其描述的代碼相近,對代碼的注釋應放在其上方或右方(對單條語句的注釋)相鄰位置,不可放在下面,如放
於上方則需與其上面的代碼用空行隔開。
規則 3
頭文件、源文件的頭部,應進行注釋。注釋必須列出:文件名、作者、目的、功能、修改日誌等。
規則 4
函數頭部應進行注釋,列出:函數的目的、功能、輸入參數、輸出參數、涉及到的通用變數和寄存器、調用的其他函數
和模塊、修改日誌等。對一些復雜的函數,在注釋中最好提供典型用法。
規則 5
對重要代碼段的功能、意圖進行注釋,提供有用的、額外的信息。並在該代碼段的結束處加一行注釋表示該段代碼結束。
規則 6
對於所有的常量,變數,數據結構聲明(包括數組、結構、類、枚舉等),如果其命名不是充分自注釋的,在聲明時都必
須加以注釋,說明其含義。
規則 7
維護代碼時,要更新相應的注釋,刪除不再有用的注釋。保持代碼、注釋的一致性,避免產生誤解。
3.命名
規則 1
標識符縮寫
形成縮寫的幾種技術:
1) 去掉所有的不在詞頭的母音字母。如screen 寫成scrn, primtive 寫成prmv。
2) 使用每個單詞的頭一個或幾個字母。如Channel Activation 寫成ChanActiv,ReleaseIndication 寫成RelInd。
3) 使用變數名中每個有典型意義的單詞。如Count of Failure 寫成FailCnt。
4) 去掉無用的單詞後綴 ing, ed 等。如Paging Request 寫成PagReq。
5) 使用標準的或慣用的縮寫形式(包括協議文件中出現的縮寫形式)。
如 BSIC(Base Station Identification Code)、MAP(Mobile Application Part)。
關於縮寫的准則:
1) 縮寫應該保持一致性。如Channel 不要有時縮寫成Chan,有時縮寫成C
h。Length 有時縮寫成Len,有時縮寫成len。
2) 在源代碼頭部加入註解來說明協議相關的、非通用縮寫。
3) 標識符的長度不超過12 個字元。
規則 2
變數命名約定:<前綴> + 主體 ; 注釋
變數命名要考慮簡單、直觀、不易混淆。
前綴是可選項,表示變數類型,由於匯編中變數多是單位元組變數,所以單位元組變數可以不加前綴,對於 bit 和雙位元組型
變數,使用小寫的b 和d 作為前綴表示。
主體是必選項,可多個單詞(或縮寫)合在一起,每個單詞首字母大寫,其餘部分小寫。
規則 3
常量的命名
常量的命名規則:單詞的字母全部大寫,各單詞之間用下劃線隔開。
規則 4
函數的命名
單詞首字母為大寫,其餘均為小寫。函數名應以一個動詞開頭,即函數名應類似一個動詞斷語或祈使句。
例如:Test_Protect, Check_EEPROM, Init_Para
4.可維護性
規則 1
函數和過程中關系較為緊密的代碼盡可能相鄰。
規則 2
每個函數的源程序行數原則上應該少於200 行。對於消息分流處理函數,完成的功能統一,但由於消息的種類多,可能
超過200 行的限制,不屬於違反規定。
規則 3
語句嵌套層次不得超過5 層。嵌套層次太多,增加了代碼的復雜度及測試的難度,容易出錯,增加代碼維護的難度。
規則 4
避免相同的代碼段在多個地方出現。當某段代碼需在不同的地方重復使用時,應根據代碼段的規模大小使用函數調用或
宏調用的方式代替。這樣,對該代碼段的修改就可在一處完成,增強代碼的可維護性。
規則 5
每個函數完成單一的功能,不設計多用途面面俱到的函數。多功能集於一身的函數,很可能使函數的理解、測試、維護
等變得困難。使函數功能明確化,增加程序可讀性,亦可方便維護、測試。
規則 6
在函數的項目維護文檔中,應該指出軟體適用的硬體平台及版本。
建議 1
使用專門的初始化函數對所有的公共變數進行初始化。
5.程序正確性、效率
規則 1
嚴禁使用未經初始化的變數。引用未經初始化的變數可能會產生不可預知的後果,特別是引用未經初始化的指針經常會
導致系統崩潰,需特別注意。
規則 2
防止內存操作越界。
說明:內存操作越界是軟體系統主要錯誤之一,後果往往非常嚴重。
規則 3
注意變數的有效取值范圍,防止表達式出現上溢或下溢。
規則 4
防止易混淆的指令和操作數拼寫錯誤。
規則 5
避免函數中不必要語句,防止程序中的垃圾代碼,預留代碼應以注釋的方式出現。程序中的垃圾代碼不僅佔用額外的空
間,而且還常常影響程序的功能與性能,很可能給程序的測試、維護等造成不必要的麻煩。
規則 6
通過對系統數據結構的劃分與組織的改進,以及對程序演算法的優化來提高空間效率。這種方式是解決軟體空間效率的根
本辦法。
規則 7
循環體內工作量最小化。應仔細考慮循環體內的語句是否可以放在循環體之外,使循環體內工作量最小,從而提高程序
的時間效率。
規則 8
在多重循環中,應將最忙的循環放在最內層。
規則 9
避免循環體內含判斷語句,將與循環變數無關的判斷語句移到循環體外。目的是減少判斷次數。循環體中的判斷語句是
否可以移到循環體外,要視程序的具體情況而言,一般情況,與循環變數無關的判斷語句可以移到循環體外,而有關的
則不可以。
規則 10
中斷和恢復
中斷程序應該盡量短,應該在中斷中進行標記,在主程序中處理。但實時性很高的程序段例外。
中斷時應該保存所有涉及到的通用變數和寄存器,如 A, PSW, DPTR 等。
規則 11
堆棧設置
堆棧對於程序非常重要,對於堆棧的設置要合理。堆棧太小,在嵌套調用和容易溢出,造成系統故障;堆棧太大,浪費
RAM 資源。為了節約堆棧資源,中斷時要求不要保存太多資源,中斷嵌套和程序嵌套層數不要太多,盡量不要超過5
層。這就要求合理的劃分功能模塊。
規則 12
看門狗
看門狗電路用於在單片機死機時自動復位。單片機需要定時向看門狗發送脈沖,俗稱」喂狗」。喂狗不可太勤,這樣看門
狗沒有起到作用;也不可太慢,這樣容易造成單片機復位。正確的喂狗應該在主循環中進行,最好是建立一個獨立的系
統監控進程。不可以在定時中斷中喂狗,應為單片機有時可能會在主循環中死掉。
6.介面
規則 1
去掉沒有必要的公共變數,編程時應盡量少用公共變數。公共變數是增大模塊間耦合的原因之一,故應減少沒必要的公
共變數以降低模塊間的耦合度。應該構造僅有一個模塊或函數可以修改、創建,而其餘有關模塊或函數只訪問的公共變
量,防止多個不同模塊或函數都可以修改、創建同一公共變數的現象。
規則 2
當向公共變數傳遞數據時,要防止越界現象發生。對公共變數賦值時,若有必要應進行合法性檢查,以提高代碼的可靠
性、穩定性。
規則 3
盡量不設計多參數函數,將不使用的參數從介面中去掉,降低介面復雜度,減少函數間介面的復雜度。
規則 4
對所調用函數的返回碼要仔細、全面地處理。防止把錯誤傳遞到後面的處理流程。如有意不檢查其返回碼,應明確指明。
規則5
檢查介面函數所有輸入參數的有效性。
規則 6
檢查函數的所有非參數輸入,如外部數據、公共變數等。
7.代碼可測性
規則 1
模塊編寫應該有完善的測試方面的考慮。
規則 2
源代碼中應該設計了代碼測試的內容。
在編寫代碼之前,應預先設計好程序調試與測試的方法和手段,並設計好各種調測開關及相應測試代碼。程序的調試與
測試是軟體生存周期中很重要的一個階段,如何對軟體進行較全面、高率的測試並盡可能地找出軟體中的錯誤就成為很
關鍵的問題。因此在編寫源代碼之前,除了要有一套比較完善的測試計劃外,還應設計出一系列代碼測試手段,為單元
測試、集成測試及系統聯調提供方便。
規則 3
在同一項目組或產品組內,要有一套統一的為集成測試與系統聯調准備的調測開關及相應函數,並且要有詳細的說明。
本規則是針對項目組或產品組的。
規則 4
在同一項目組或產品組內,調測列印出的信息串的格式要有統一的形式。信息串中至少要有所在模塊名(或源文件名)
及行號。統一的調測信息格式便於集成測試。
規則 5
正式軟體產品中應把調測代碼去掉(即把有關的調測開關關掉)。
規則 6
用調測開關來切換軟體的DEBUG 版和正式版,而不要同時存在正式版本和DEBUG 版本的不同源文件,以減少維護的
難度。
規則 7
在軟體系統中設置與取消有關測試手段,不能對軟體實現的功能等產生影響。即有測試代碼的軟體和關掉測試代碼的軟
件,在功能行為上應一致。
規則 8
發現錯誤應該立即修改,並且若有必要記錄下來。
規則 9
開發人員應堅持對代碼進行徹底的測試(單元測試),而不依靠他人或測試組來發現問題。
規則 10
清理、整理或優化後的代碼要經過審查及測試。
規則 11
代碼版本升級要經過嚴格測試。
8.代碼編譯
規則 1
打開編譯器的所有告警開關對程序進行編譯。防止隱藏可能是錯誤的告警。
規則 2
某些語句經編譯後產生告警,但如果你認為它是正確的,那麼應通過某種手段去掉告警信息。照著規范系統的學習,不久的將來你也是個高手了。
3. 求52單片機程序代碼
程序代碼如下:
#include<reg51.h>
sbitK1=P1^0;
sbitK2=P1^1;
voiddelay(inta)
{
inti;
while(a--)for(i=0;i<120;i++);
}
main()
{
unsignedcharkeyval=0,led=0xfe;
while(1)
{
if(K1==0)
{
delay(10);
if(K1==0)
{
keyval==1;
while(K1==0);
}
}
if(K2==0)
{
delay(10);
if(K2==0)
{
keyval==2;
while(K2==0);
}
}
if(keyval==1)P0=0xfe;
if(keyval==2)
{
P0=led;
led=_crol_(led,1);
delay(200);
}
}
}
4. 單片機應用程序的開發步驟
具體步驟如下:
1、首先,開啟我們的keil軟體,具體的安裝步驟就不做太多的介紹了;
開啟後,點擊菜單欄上的Project選項,創建我們的工程,如圖所示;
編譯完成後,在我們的文件夾下找到.hex的文件,將其燒寫到我們的晶元中即可。
5. 單片機C語言編程
KEY4EQU30H
KEY2EQU31H
ORG0000H
LJMPMAIN
ORG0030H
MAIN:
CLREA
MOVSP,#5FH
MOVKEY2,#0
MOVKEY4,#0
LOOP:
JBP1.0,LOOP
MOVR7,#10
LCALLDELAY
JBP1.0,LOOP
JNBP1.0,$
MOVP3,#0C0H
LOOP0:
LCALLKEYDEAL
MOVA,KEY4
JNZLOOP41
MOVA,P3
ANLA,#0F0H
ORLA,#0EH
MOVP3,A
SJMPLOOP21
LOOP41:
DECA
JNZLOOP42
MOVA,P3
ANLA,#0F0H
ORLA,#0DH
MOVP3,A
SJMPLOOP21
LOOP42:
DECA
JNZLOOP43
MOVA,P3
ANLA,#0F0H
ORLA,#0BH
MOVP3,A
SJMPLOOP21
LOOP43:
DECA
JNZLOOP21
MOVA,P3
ANLA,#0F0H
ORLA,#07H
MOVP3,A
LOOP21:
MOVA,KEY2
JNZLOOP22
MOVA,P3
ANLA,#0FH
ORLA,#20H
MOVP3,A
SJMPLOOP3
LOOP22:
DECA
JNZLOOP3
MOVA,P3
ANLA,#0FH
ORLA,#10H
MOVP3,A
LOOP3:
LJMPLOOP0
;----------------------------
DELAY:
MOVR2,#2
DLY1:
MOVR3,#250
DJNZR3,$
DJNZR2,DLY1
DJNZR7,DELAY
RET
;-----------------------------
KEYDEAL:
JBP1.1,KEYEN1
MOVR7,#10
LCALLDELAY
JBP1.1,KEYEN1
JNBP1.1,$
INCKEY4
MOVA,KEY4
ANLA,#03H
MOVKEY4,A
KEYEN1:
JBP1.2,KEYEN2
MOVR7,#10
LCALLDELAY
JBP1.2,KEYEN2
JNBP1.2,$
INCKEY2
MOVA,KEY2
ANLA,#01H
MOVKEY2,A
KEYEN2:
RET
;-----------------------------
6. 如何寫出高效的單片機C語言程序代碼
由於單片機的性能同電腦的性能是天淵之別的,無論從空間資源上、內存資源、工作頻率,都是無法
與之比較的。PC 機編程基本上不用考慮空間的佔用、內存的佔用的問題,最終目的就是實現功能就可以了。
對於單片機來說就截然不同了,一般的單片機的Flash 和Ram 的資源是以KB 來衡量的,可想而知,單片
機的資源是少得可憐,為此我們必須想法設法榨盡其所有資源,將它的性能發揮到最佳,程序設計時必須
遵循以下幾點進行優化:
1. 使用盡量小的數據類型
能夠使用字元型(char)定義的變數,就不要使用整型(int)變數來定義;能夠使用整型變數定義的變
量就不要用長整型(long int),能不使用浮點型(float)變數就不要使用浮點型變數。當然,在定義變
量後不要超過變數的作用范圍,如果超過變數的范圍賦值,C 編譯器並不報錯,但程序運行結果卻錯了,
而且這樣的錯誤很難發現。
2. 使用自加、自減指令
通常使用自加、自減指令和復合賦值表達式(如a-=1 及a+=1 等)都能夠生成高質量的
程序代碼,編譯器通常都能夠生成inc 和dec 之類的指令,而使用a=a+1 或a=a-1 之類
的指令,有很多C 編譯器都會生成二到三個位元組的指令。
3. 減少運算的強度
可以使用運算量小但功能相同的表達式替換原來復雜的的表達式。
(1) 求余運算
N= N %8 可以改為N = N &7
說明:位操作只需一個指令周期即可完成,而大部分的C 編譯器的「%」運算均是調用子程序來
完成,代碼長、執行速度慢。通常,只要求是求2n 方的余數,均可使用位操作的方法來代替。
(2) 平方運算
N=Pow(3,2) 可以改為N=3*3
說明:在有內置硬體乘法器的單片機中(如51 系列),乘法運算比求平方運算快得多, 因為浮點數
的求平方是通過調用子程序來實現的,乘法運算的子程序比平方運算的子程序代碼短,執行速度快。
(3) 用位移代替乘法除法
N=M*8 可以改為N=M<<3
N=M/8 可以改為N=M>>3
說明:通常如果需要乘以或除以2n,都可以用移位的方法代替。如果乘以2n,都可以生成左移
的代碼,而乘以其它的整數或除以任何數,均調用乘除法子程序。用移位的方法得到代碼比調用乘除法子
程序生成的代碼效率高。實際上,只要是乘以或除以一個整數,均可以用移位的方法得到結果。如N=M*9
可以改為N=(M<<3)+M;
(4) 自加自減的區別
例如我們平時使用的延時函數都是通過採用自加的方式來實現。
void DelayNms(UINT16 t)
{
UINT16 i,j;
for(i=0;i<t;i++)
for(j=0;i<1000;j++)
}
可以改為
void DelayNms(UINT16 t)
{
UINT16 i,j;
for(i=t;i>=0;i--)
for(j=1000;i>=0;j--)
}
說明:兩個函數的延時效果相似,但幾乎所有的C 編譯對後一種函數生成的代碼均比前一種代碼少1~3
個位元組,因為幾乎所有的MCU 均有為0 轉移的指令,採用後一種方式能夠生成這類指令。
4. while 與do...while 的區別
void DelayNus(UINT16 t)
{
while(t--)
{
NOP();
}
}
可以改為
void DelayNus(UINT16 t)
{
do
{
NOP();
}while(--t)
}
說明:使用do…while 循環編譯後生成的代碼的長度短於while 循環。
5. register 關鍵字
void UARTPrintfString(INT8 *str)
{
while(*str && str)
{
UARTSendByte(*str++)
}
}
可以改為
void UARTPrintfString(INT8 *str)
{
register INT8 *pstr=str;
while(*pstr && pstr)
{
UARTSendByte(*pstr++)
}
}
說明:在聲明局部變數的時候可以使用register 關鍵字。這就使得編譯器把變數放入一個多用途的寄存
器中,而不是在堆棧中,合理使用這種方法可以提高執行速度。函數調用越是頻繁,越是可能提高代碼的
速度,注意register 關鍵字只是建議編譯器而已。
6. volatile 關鍵字
volatile 總是與優化有關,編譯器有一種技術叫做數據流分析,分析程序中的變數在哪裡賦值、在
哪裡使用、在哪裡失效,分析結果可以用於常量合並,常量傳播等優化,進一步可以死代碼消除。一般來
說,volatile 關鍵字只用在以下三種情況:
a) 中斷服務函數中修改的供其它程序檢測的變數需要加volatile(參考本書高級實驗程序)
b) 多任務環境下各任務間共享的標志應該加volatile
c) 存儲器映射的硬體寄存器通常也要加volatile 說明,因為每次對它的讀寫都可能由不同意義
總之,volatile 關鍵字是一種類型修飾符,用它聲明的類型變數表示可以被某些編譯器未知的因素
更改,比如:操作系統、硬體或者其它線程等。遇到這個關鍵字聲明的變數,編譯器對訪問該變數的代碼
就不再進行優化,從而可以提供對特殊地址的穩定訪問。
7. 單片機c語言編程100個實例
51單片機C語言編程實例 基礎知識:51單片機編程基礎 單片機的外部結構: 1. DIP40雙列直插; 2. P0,P1,P2,P3四個8位準雙向I/O引腳;(作為I/O輸入時,要先輸出高電平) 3. 電源VCC(PIN40)和地線GND(PIN20); 4. 高電平復位RESET(PIN9);(10uF電容接VCC與RESET,即可實現上電復位) 5. 內置振盪電路,外部只要接晶體至X1(PIN18)和X0(PIN19);(頻率為主頻的12倍) 6. 程序配置EA(PIN31)接高電平VCC;(運行單片機內部ROM中的程序) 7. P3支持第二功能:RXD、TXD、INT0、INT1、T0、T1 單片機內部I/O部件:(所為學習單片機,實際上就是編程式控制制以下I/O部件,完成指定任務) 1. 四個8位通用I/O埠,對應引腳P0、P1、P2和P3; 2. 兩個16位定時計數器;(TMOD,TCON,TL0,TH0,TL1,TH1) 3. 一個串列通信介面;(SCON,SBUF) 4. 一個中斷控制器;(IE,IP) 針對AT89C52單片機,頭文件AT89x52.h給出了SFR特殊功能寄存器所有埠的定義。 C語言編程基礎: 1. 十六進製表示位元組0x5a:二進制為01011010B;0x6E為01101110。 2. 如果將一個16位二進數賦給一個8位的位元組變數,則自動截斷為低8位,而丟掉高8位。 3. ++var表示對變數var先增一;var—表示對變數後減一。 4. x |= 0x0f;表示為 x = x | 0x0f; 5. TMOD = ( TMOD & 0xf0 ) | 0x05;表示給變數TMOD的低四位賦值0x5,而不改變TMOD的高四位。 6. While( 1 ); 表示無限執行該語句,即死循環。語句後的分號表示空循環體,也就是{;} 在某引腳輸出高電平的編程方法:(比如P1.3(PIN4)引腳) 代碼 1. #include <AT89x52.h> //該頭文檔中有單片機內部資源的符號化定義,其中包含P1.3 2. void main( void ) //void 表示沒有輸入參數,也沒有函數返值,這入單片機運行的復位入口 3. { 4. P1_3 = 1; //給P1_3賦值1,引腳P1.3就能輸出高電平VCC 5. While( 1 ); //死循環,相當 LOOP: goto LOOP; 6. } 注意:P0的每個引腳要輸出高電平時,必須外接上拉電阻(如4K7)至VCC電源。 在某引腳輸出低電平的編程方法:(比如P2.7引腳) 代碼 1. #include <AT89x52.h> //該頭文檔中有單片機內部資源的符號化定義,其中包含P2.7 2. void main( void ) //void 表示沒有輸入參數,也沒有函數返值,這入單片機運行的復位入口 3. { 4. P2_7 = 0; //給P2_7賦值0,引腳P2.7就能輸出低電平GND 5. While( 1 ); //死循環,相當 LOOP: goto LOOP; 6. } 在某引腳輸出方波編程方法:(比如P3.1引腳) 代碼 1. #include <AT89x52.h> //該頭文檔中有單片機內部資源的符號化定義,其中包含P3.1 2. void main( void ) //void 表示沒有輸入參數,也沒有函數返值,這入單片機運行的復位入口 3. { 4. While( 1 ) //非零表示真,如果為真則執行下面循環體的語句 5. { 6. P3_1 = 1; //給P3_1賦值1,引腳P3.1就能輸出高電平VCC 7. P3_1 = 0; //給P3_1賦值0,引腳P3.1就能輸出低電平GND 8. } //由於一直為真,所以不斷輸出高、低、高、低……,從而形成方波 9. } 將某引腳的輸入電平取反後,從另一個引腳輸出:( 比如 P0.4 = NOT( P1.1) ) 代碼 1. #include <AT89x52.h> //該頭文檔中有單片機內部資源的符號化定義,其中包含P0.4和P1.1 2. void main( void ) //void 表示沒有輸入參數,也沒有函數返值,這入單片機運行的復位入口 3. { 4. P1_1 = 1; //初始化。P1.1作為輸入,必須輸出高電平 5. While( 1 ) //非零表示真,如果為真則執行下面循環體的語句 6. { 7. if( P1_1 == 1 ) //讀取P1.1,就是認為P1.1為輸入,如果P1.1輸入高電平VCC 8. { P0_4 = 0; } //給P0_4賦值0,引腳P0.4就能輸出低電平GND 2 51單片機C語言編程實例 9. else //否則P1.1輸入為低電平GND 10. //{ P0_4 = 0; } //給P0_4賦值0,引腳P0.4就能輸出低電平GND 11. { P0_4 = 1; } //給P0_4賦值1,引腳P0.4就能輸出高電平VCC 12. } //由於一直為真,所以不斷根據P1.1的輸入情況,改變P0.4的輸出電平 13. } 將某埠8個引腳輸入電平,低四位取反後,從另一個埠8個引腳輸出:( 比如 P2 = NOT( P3 ) ) 代碼 1. #include <AT89x52.h> //該頭文檔中有單片機內部資源的符號化定義,其中包含P2和P3 2. void main( void ) //void 表示沒有輸入參數,也沒有函數返值,這入單片機運行的復位入口 3. { 4. P3 = 0xff; //初始化。P3作為輸入,必須輸出高電平,同時給P3口的8個引腳輸出高電平 5. While( 1 ) //非零表示真,如果為真則執行下面循環體的語句 6. { //取反的方法是異或1,而不取反的方法則是異或0 7. P2 = P3^0x0f //讀取P3,就是認為P3為輸入,低四位異或者1,即取反,然後輸出 8. } //由於一直為真,所以不斷將P3取反輸出到P2 9. } 注意:一個位元組的8位D7、D6至D0,分別輸出到P3.7、P3.6至P3.0,比如P3=0x0f,則P3.7、P3.6、P3.5、P3.4四個引腳都輸出低電平,而P3.3、P3.2、P3.1、P3.0四個引腳都輸出高電平。同樣,輸入一個埠P2,即是將P2.7、P2.6至P2.0,讀入到一個位元組的8位D7、D6至D0。 第一節:單數碼管按鍵顯示 單片機最小系統的硬體原理接線圖: 1. 接電源:VCC(PIN40)、GND(PIN20)。加接退耦電容0.1uF 2. 接晶體:X1(PIN18)、X2(PIN19)。注意標出晶體頻率(選用12MHz),還有輔助電容30pF 3. 接復位:RES(PIN9)。接上電復位電路,以及手動復位電路,分析復位工作原理 4. 接配置:EA(PIN31)。說明原因。 發光二極的控制:單片機I/O輸出 將一發光二極體LED的正極(陽極)接P1.1,LED的負極(陰極)接地GND。只要P1.1輸出高電平VCC,LED就正向導通(導通時LED上的壓降大於1V),有電流流過LED,至發LED發亮。實際上由於P1.1高電平輸出電阻為10K,起到輸出限流的作用,所以流過LED的電流小於(5V-1V)/10K = 0.4mA。只要P1.1輸出低電平GND,實際小於0.3V,LED就不能導通,結果LED不亮。 開關雙鍵的輸入:輸入先輸出高 一個按鍵KEY_ON接在P1.6與GND之間,另一個按鍵KEY_OFF接P1.7與GND之間,按KEY_ON後LED亮,按KEY_OFF後LED滅。同時按下LED半亮,LED保持後松開鍵的狀態,即ON亮OFF滅。 代碼 1. #include <at89x52.h> 2. #define LED P1^1 //用符號LED代替P1_1 3. #define KEY_ON P1^6 //用符號KEY_ON代替P1_6 4. #define KEY_OFF P1^7 //用符號KEY_OFF代替P1_7 5. void main( void ) //單片機復位後的執行入口,void表示空,無輸入參數,無返回值 6. { 7. KEY_ON = 1; //作為輸入,首先輸出高,接下KEY_ON,P1.6則接地為0,否則輸入為1 8. KEY_OFF = 1; //作為輸入,首先輸出高,接下KEY_OFF,P1.7則接地為0,否則輸入為1 9. While( 1 ) //永遠為真,所以永遠循環執行如下括弧內所有語句 10. { 11. if( KEY_ON==0 ) LED=1; //是KEY_ON接下,所示P1.1輸出高,LED亮 12. if( KEY_OFF==0 ) LED=0; //是KEY_OFF接下,所示P1.1輸出低,LED滅 13. } //松開鍵後,都不給LED賦值,所以LED保持最後按鍵狀態。 14. //同時按下時,LED不斷亮滅,各佔一半時間,交替頻率很快,由於人眼慣性,看上去為半亮態 15. } 數碼管的接法和驅動原理 一支七段數碼管實際由8個發光二極體構成,其中7個組形構成數字8的七段筆畫,所以稱為七段數碼管,而餘下的1個發光二極體作為小數點。作為習慣,分別給8個發光二極體標上記號:a,b,c,d,e,f,g,h。對應8的頂上一畫,按順時針方向排,中間一畫為g,小數點為h。 我們通常又將各二極與一個位元組的8位對應,a(D0),b(D1),c(D2),d(D3),e(D4),f(D5),g(D6),h(D7),相應8個發光二極體正好與單片機一個埠Pn的8個引腳連接,這樣單片機就可以通過引腳輸出高低電平控制8個發光二極的亮與滅,從而顯示各種數字和符號;對應位元組,引腳接法為:a(Pn.0),b(Pn.1),c(Pn.2),d(Pn.3),e(Pn.4),f(Pn.5),g(Pn.6),h(Pn.7)。 如果將8個發光二極體的負極(陰極)內接在一起,作為數碼管的一個引腳,這種數碼管則被稱為共陰數碼管,共同的引腳則稱為共陰極,8個正極則為段極。否則,如果是將正極(陽極)內接在一起引出的,則稱為共陽數碼管,共同的引腳則稱為共陽極,8個負極則為段極。 以單支共陰數碼管為例,可將段極接到某埠Pn,共陰極接GND,則可編寫出對應十六進制碼的七段碼表位元組數據
8. 單片機編程步驟
一、什麼是 nec 單片機
隨著大范疇集成電路的顯現和發展,將計算機的cpu、ram、rom、定時/數器和多種i/o介面集成在一片晶元上,組成晶元級的計較機,因此單片機早期的含義稱為單片微型計較機,直譯為單片機。單片機是一種集成在電路晶元,是採用超大范疇集成電路技能把具有數據處理本事的中心處理器CPU隨機存儲器RAM、只讀存儲器ROM、多種I/O口和間斷系統、 定時器 / 計時器 等成果(大要還包括表現驅動電路、脈寬調制電路、模擬多路轉換器、A/D轉換器等電路)集成到一塊矽片上構成的一個小而完竣的計算機系
二、nec單片機的操縱教程詳解
1、在智能儀器儀表中的操縱:在各類儀器儀表中引入單片機,使儀器儀表智能化,進步測試的自動化程度和精度,簡化儀器儀表的硬體結構,進步其性能價格比。
2、在機電一體化中的操縱:機電一體化產品是指集呆板、微電子技能、計較機技能於一本,具有智能化特徵的電子產品。
3、在實時過程式控制制中的操縱:用單片機實時進行數據處理和控制,使系統保持最佳事變狀態,進步系統的事變從命和產品的品格。
4、在人類生活中的操縱:目前國外各種家用電器已普通採用單片機代替傳統的控制電路。
5、在此外方面的操縱:單片機除以上各方面的操縱,它還遍布操縱於辦公自動化范圍、商業營銷范圍、汽車及通信、計較機外部裝備、暗昧控制等各范圍中。
以上就是為大家整理的關於單片機含義及其具體操縱教程的全部內容了。此外小編還額外為大家整理了單片機的優點:低電壓、低功耗、集成度高、可靠性高、體積小、控製成果強等。希望通過這篇文章能夠給想要了解單片機相關知識的朋友帶來一些幫助。另外大家如果想了解更多單片機的知識可以通過圖書查閱、網路查閱等方式。
9. 單片機c語言編程
單片機的外部結構:
DIP40雙列直插;
P0,P1,P2,P3四個8位準雙向I/O引腳;(作為I/O輸入時,要先輸出高電平)
電源VCC(PIN40)和地線GND(PIN20);
高電平復位RESET(PIN9);(10uF電容接VCC與RESET,即可實現上電復位)
內置振盪電路,外部只要接晶體至X1(PIN18)和X0(PIN19);(頻率為主頻的12倍)
程序配置EA(PIN31)接高電平VCC;(運行單片機內部ROM中的程序)
P3支持第二功能:RXD、TXD、INT0、INT1、T0、T1
單片機內部I/O部件:(所為學習單片機,實際上就是編程式控制制以下I/O部件,完成指定任務)
四個8位通用I/O埠,對應引腳P0、P1、P2和P3;
兩個16位定時計數器;(TMOD,TCON,TL0,TH0,TL1,TH1)
一個串列通信介面;(SCON,SBUF)
一個中斷控制器;(IE,IP)
針對AT89C52單片機,頭文件AT89x52.h給出了SFR特殊功能寄存器所有埠的定義。教科書的160頁給出了針對MCS51系列單片機的C語言擴展變數類型。
C語言編程基礎:
十六進製表示位元組0x5a:二進制為01011010B;0x6E為01101110。
如果將一個16位二進數賦給一個8位的位元組變數,則自動截斷為低8位,而丟掉高8位。
++var表示對變數var先增一;var—表示對變數後減一。
x |= 0x0f;表示為 x = x | 0x0f;
TMOD = ( TMOD & 0xf0 ) | 0x05;表示給變數TMOD的低四位賦值0x5,而不改變TMOD的高四位。
While( 1 ); 表示無限執行該語句,即死循環。語句後的分號表示空循環體,也就是{;}
在某引腳輸出高電平的編程方法:(比如P1.3(PIN4)引腳)
#include <AT89x52.h> //該頭文檔中有單片機內部資源的符號化定義,其中包含P1.3
void main( void ) //void 表示沒有輸入參數,也沒有函數返值,這入單片機運行的復位入口
{
P1_3 = 1; //給P1_3賦值1,引腳P1.3就能輸出高電平VCC
While( 1 ); //死循環,相當 LOOP: goto LOOP;
}
注意:P0的每個引腳要輸出高電平時,必須外接上拉電阻(如4K7)至VCC電源。
在某引腳輸出低電平的編程方法:(比如P2.7引腳)
#include <AT89x52.h> //該頭文檔中有單片機內部資源的符號化定義,其中包含P2.7
void main( void ) //void 表示沒有輸入參數,也沒有函數返值,這入單片機運行的復位入口。
{
P2_7 = 0; //給P2_7賦值0,引腳P2.7就能輸出低電平GND
While( 1 ); //死循環,相當 LOOP: goto LOOP;
}
在某引腳輸出方波編程方法:(比如P3.1引腳)
#include <AT89x52.h> //該頭文檔中有單片機內部資源的符號化定義,其中包含P3.1
void main( void ) //void 表示沒有輸入參數,也沒有函數返值,這入單片機運行的復位入口
{
While( 1 ) //非零表示真,如果為真則執行下面循環體的語句
{
P3_1 = 1; //給P3_1賦值1,引腳P3.1就能輸出高電平VCC
P3_1 = 0; //給P3_1賦值0,引腳P3.1就能輸出低電平GND
} //由於一直為真,所以不斷輸出高、低、高、低……,從而形成方波
}
將某引腳的輸入電平取反後,從另一個引腳輸出:( 比如 P0.4 = NOT( P1.1) )
#include <AT89x52.h> //該頭文檔中有單片機內部資源的符號化定義,其中包含P0.4和P1.1
void main( void ) //void 表示沒有輸入參數,也沒有函數返值,這入單片機運行的復位入口
{
P1_1 = 1; //初始化。P1.1作為輸入,必須輸出高電平
While( 1 ) //非零表示真,如果為真則執行下面循環體的語句
{
if( P1_1 == 1 ) //讀取P1.1,就是認為P1.1為輸入,如果P1.1輸入高電平VCC
{ P0_4 = 0; } //給P0_4賦值0,引腳P0.4就能輸出低電平GND
else //否則P1.1輸入為低電平GND
//{ P0_4 = 0; } //給P0_4賦值0,引腳P0.4就能輸出低電平GND
{ P0_4 = 1; } //給P0_4賦值1,引腳P0.4就能輸出高電平VCC
} //由於一直為真,所以不斷根據P1.1的輸入情況,改變P0.4的輸出電平
}
將某埠8個引腳輸入電平,低四位取反後,從另一個埠8個引腳輸出:( 比如 P2 = NOT( P3 ) )
#include <AT89x52.h> //該頭文檔中有單片機內部資源的符號化定義,其中包含P2和P3
void main( void ) //void 表示沒有輸入參數,也沒有函數返值,這入單片機運行的復位入口
{
P3 = 0xff; //初始化。P3作為輸入,必須輸出高電平,同時給P3口的8個引腳輸出高電平
While( 1 ) //非零表示真,如果為真則執行下面循環體的語句
{ //取反的方法是異或1,而不取反的方法則是異或0
P2 = P3^0x0f //讀取P3,就是認為P3為輸入,低四位異或者1,即取反,然後輸出
} //由於一直為真,所以不斷將P3取反輸出到P2
}
注意:一個位元組的8位D7、D6至D0,分別輸出到P3.7、P3.6至P3.0,比如P3=0x0f,則P3.7、P3.6、P3.5、P3.4四個引腳都輸出低電平,而P3.3、P3.2、P3.1、P3.0四個引腳都輸出高電平。同樣,輸入一個埠P2,即是將P2.7、P2.6至P2.0,讀入到一個位元組的8位D7、D6至D0。