首先,在org 0000h
org 0030h
之間你應該加條語句 JMP start
其次,你在開始程序的時候,應該設置哈堆棧.
再次,你用JC跳轉的時候,結束子程序的時候你不應該用RET,你直接用跳轉語句JMP跳轉到你需要的地方,因為JC不是CALL語句,它不需要返回.你直接跳到start處.當執行完tab1,tab2這樣的程序後.
改正這幾個問題就可以成功了,應該
⑵ 單片機 用C語言怎麼編程!
每一種單片機都有一套自己的C編譯器,你可以直接用,也可以掛載到其他的編譯環境中
比如
Wave6000
等
51系列的
推薦用keilV8
Microchip系列的推薦用HT-PICC
編譯環境用MPLAB
然後編程代碼部分你寫好之後,編譯,此時會生成一些文件,如*.hex
,*.bin
……
然後把.hex
文件
利用燒寫器燒寫到單片機裡面
這樣單片機就可以按照編譯的程序執行了
單片機的種類不一樣,程序代碼也略有區別
⑶ 單片機實驗 編寫程序
單片機實驗,其實這就是典型的流水燈電路,P1口接8個流水燈,每個燈點亮1秒。用定時器T1定時50ms,中斷20次就為1秒,可用_crol_()移位函數實現。模擬效果如下圖所示。
⑷ 單片機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。
⑸ 單片機c語言實例
基於MCS-51系列單片機AT89S51的八路搶答器
基於MCS-51系列單片機AT89S51的八路搶答器
前言
隨著現代電子電路的快速發展,以及電子行業對現有電子工程技術的不斷需求,特別是對實際操作實踐的電子人才的需求越來越多,所以加強學生動手能力、重視實踐應該是電子發展需求的必然趨向。實踐動手能力的培養是一種綜合能力,這種能力當然是在一定難度的前提下完成的,通過一定數量的實踐才能逐步形成的。因此在培養實踐能力的同時,要通過實踐來不斷的發現問題和解決問題的途徑和方法,從而提高實踐能力。
近年來,隨著單片機檔次的不斷提高,功能的不斷完善,其應用日趨成熟、應用領域日趨擴大,特別是工業測控、尖端武器和日用家電等領域更是因為有了單片機而生輝增色。單片機應用技術已成為一項新的工程應用技術。本次實習設計的題目為基於單片機的搶答器。
在本次的課程設計中我主要負責了該系統的印製電路板PCB的製作
一、方案論證
方案一:系統各部分採用中小規模集成數字電路,用機械開關按鈕作為控制開關,完成搶答輸入信號的觸發。該方案的特點是中小規模集成電路應用技術成熟,性能可靠,能方便地完成選手搶答的基本功能,但是由於系統功能要求較高,所以電路連接集成電路相對較多,而且過於復雜,並且製作過程工序比較煩瑣,使用不太方便。
方案二:該系統採用MCS-51系列單片機AT89S51作為控制核心,該系統可以完成運算控制、信號識別以及顯示功能的實現。由於用了單片機,使其技術比較成熟,應用起來方便、簡單並且單片機周圍的輔助電路也比較少,便於控制和實現。整個系統具有極其靈活的可編程性,能方便地對系統進行功能的擴張和更改性。 CS-51單片機特點如下:
1> 可靠性好:單片機按照工業控制要求設計,抵抗工業雜訊干擾優於一般的CPU ,程序指令和數據都可以燒寫在ROM許多信號通道都在同一晶元,因此可靠性高。
2> 易擴充:單片機有一般電腦所必須的器件,如三態雙向匯流排,串並行的輸入及輸出引腳,可擴充為各種規模的微電腦系統
3> 控制功能強:單片機指令除了輸入輸出指令,邏輯判斷指令外還有更豐富的條件分支跳躍指令。原理框圖如1-1所示;
圖1-1
方案比較及其選用依據,顯然方案二比方案一簡單的多,不但從性能上優於方案一,而且在使用上及其功能的實現上都較方案一簡潔,並且由於單片機具有優越的高集成電路性,使其工作速度更快、效率更高。另外AT89S51單片機採用12MHz的晶振,提高了信號的測量精度,並且使該系統可以通過軟體改進來擴張功能。而方案一採用了中小規模集成電路,有其復雜的電路性能,從而可能會使信號的輸入輸出產生延時及不必要的誤差。依此依據選擇方案二比較適合。
二、原理分析
1. 本電路採用單片機AT89C51作為控制晶元,單片機的P0口外接八個發光二極體,每個發光二極體分別作為八位選手的信號指示燈。並在各個外接電路上並接開關按鍵,按鍵另一端接地。發光二極體採用共陽極接法,由於P0口為高電平呈輸入狀態,當有按鍵按下時,P0口呈低電平與按鍵對應的發光二極體滿足點亮條件點亮。在程序編程上採用查詢,查詢P0口P0。0到P0。7的八個埠呈低電平,即查詢是哪個選手先按鍵,然後將選手號碼的位元組數據送至串列口輸出並在數碼管上顯現出來。
2. 蜂鳴器是利用三極體處於開關狀態是的導通與截止工作,在三極體導通時蜂鳴器工作,三極體截止時蜂鳴器不工作。三極體採用8550 PNP型基極接於P1。2口置其低電平時三極體導通,置其高電平時三極體截止。
3. 數碼管採用共陽極七段顯示,其內部發光二極體為共陽極接高電平,當對應發光二極體一端為低電平時發光二極體點亮,顯示的數字或字元由送入的位元組數據控制,位元組數據的輸出採用串形口工作模式0,8位串列位元組數據的輸出通過RXD埠送出,TXD端用於送出同步移位脈沖,作為外接器件的同步移位信號。數據的發送是在TI=0的情況下,由一寫發送緩沖器的指令開始CPU執行完該指令,串列口即將8位數據從RXD端送出,同時TXD端發出同步移位脈沖。8位數據發送完畢後由硬體置位TI=1,通過查詢TI位來確定是否發送完一組數據,TI=1表示發送緩沖器已空,當要發送下一組數據時用軟體使TI清零,然後即可發送下一組數據。
4. 軟體設計分析首先在程序的開始為選手設置了一段違規程序,該程序的作用是為了防止選手在主持人沒有按下搶答鍵時,有的選手已經提前搶答了,本次搶答為無效搶答,並有報警和記錄下該位選手的選號,做違規處理,如果選手超出了在規定的提前搶答次數,則該選手將被取消以後的搶答資格。如果在主持按下搶答鍵時再搶答,該次搶答被視為有效搶答,在主持按下回答問題的鍵時選手就可以在規定的時間內回答問題了
圖1-2
<1> 選手查詢程序:
ORG 0000H
START:CLR A
MOV A,#0FFH
MOV P0,A
LOP:JNB P2。4,LP
JNB P0。0,SA1
JNB P0。1,SA2
JNB P0。2,SA3
JNB P0。3,SA4
JNB P0。4,SA5
JNB P0。5,SA6
JNB P0。6,SA7
JNB P0。7,SA8
SJMP LOP
SA1:AJMP SB1
SA2:AJMP SB2
SA3:AJMP SB3
SA4:AJMP SB4
SA5:AJMP SB5
SA6:AJMP SB6
SA7:AJMP SB7
SA8:AJMP SB8
LP:MOV R0,#9
LOP1:LCALL LED
LCALL DEL
JNB P0。0,SIP1
JNB P0。1,SIP2
JNB P0。2,SIP3
JNB P0。3,SIP4
JNB P0。4,SIP5
JNB P0。5,SIP6
JNB P0。6,SIP7
JNB P0。7,SIP8
DEC R0
CJNE R0,#0,LOP1
MOV R0,#0
LCALL LED
LCALL DEL
SJMP LOP
SIP1:AJMP DIP1
SIP2:AJMP DIP2
SIP3:AJMP DIP3
SIP4:AJMP DIP4
SIP5:AJMP DIP5
SIP6:AJMP DIP6
SIP7:AJMP DIP7
SIP8:AJMP DIP8
SB1:MOV R2,#1
LCALL LED1
LCALL DE
SJMP LP1
SB2:MOV R2,#2
LCALL LED1
LCALL DE
SJMP LP1
SB3:MOV R2,#3
LCALL LED1
LCALL DE
SJMP LP1
SB4:MOV R2,#4
LCALL LED1
LCALL DE
SJMP LP1
SB5:MOV R2,#5
LCALL LED1
LCALL DE
SJMP LP1
SB6:MOV R2,#6
LCALL LED1
LCALL DE
SJMP LP1
SB7:MOV R2,#7
LCALL LED1
LCALL DE
SJMP LP1
SB8:MOV R2,#8
LCALL LED1
LCALL DE
SJMP LP1
LP1:JNB P2。4,LOP2
SJMP LP1
DIP1:MOV R2,#1
LCALL LED1
LCALL DE
SJMP LH1
DIP2:MOV R2,#2
LCALL LED1
LCALL DE
SJMP LH1
DIP3:MOV R2,#3
LCALL LED1
LCALL DE
SJMP LH1
DIP4:MOV R2,#4
LCALL LED1
LCALL DE
SJMP LH1
DIP5:MOV R2,#5
LCALL LED1
LCALL DE
SJMP LH1
DIP6:MOV R2,#6
LCALL LED1
LCALL DE
SJMP LH1
DIP7:MOV R2,#7
LCALL LED1
LCALL DE
SJMP LH1
DIP8:MOV R2,#8
LCALL LED1
LCALL DE
SJMP LH1
LH1:JNB P2。4,LOOP
SJMP LH1
LOP2:MOV A,#11H
MOV SBUF,A
JNB TI,$
CLR TI
LCALL DEL
AJMP LOP
<2> 串列輸出程序:
該部分程序的設計利用了單片機的串列模式0輸出,該輸出方式佔用IO口少。可以省去許多IO口作為功能的擴展使用。在該模式下,我們採用了輸出查詢的方式,就是要藉助發送標志TI,當程序執行到發送標志位時,查詢其標志位TI的值,只要TI的值是0程序就繼續查詢,知道查詢到TI為1時才結束,然後在進入下一組數據的發送。由於串列輸出時送進去的數都是十進制數,以致計算機不能識別,所以還要把送進去的十進制數轉化成而進制數,這樣才能輸出。因此在輸出程序前必須有拆字程序,把原來送進去的十進制數轉化成二進制數,然後在輸出並通過數碼管顯示出來。但是如果在顯示選手選號與顯示選手回答問題所用的到計同用一段串列輸出程序時就會造成程序的混亂,所以在此處設計了兩段初始值不同的顯示程序,從而可能增加了程序的煩瑣化。
LED1:MOV A,R2
MOV B,#10
DIV AB
MOV R1,A
MOV R3,B
MOV A,R1
MOV DPTR,#TAB
MOVC A,@A+DPTR
MOV SBUF,A
JNB TI,$
CLR TI
MOV A,R3
MOVC A,@A+DPTR
MOV SBUF,A
JNB TI,$
CLR TI
RET。
LED:MOV A,R0
MOV B,#10
DIV AB
MOV R1,A
MOV R3,B
MOV A,R1
MOV DPTR,#TAB
MOVC A,@A+DPTR
MOV SBUF,A
JNB TI,$
CLR TI
MOV A,R3
MOVC A,@A+DPTR
MOV SBUF,A
JNB TI,$
CLR TI
RET
DE:CLR P1。2
LCALL DEL01
SETB P1。2
LCALL DEL01
RET
TAB:DB 11H,0D7H,32H,92H,0D4H,98H,18H,0D3H,10H,90H
RET
END
<3>倒計時程序
該程序為選手回答問題時的30秒倒計時程序,其中前25秒為正常的倒計時,在後5秒倒計時時伴隨有報警聲,用於提示選手回答問題的剩餘時間。如果該選手在正常的倒計時內沒有完成問題的回答,那麼倒計時將被清零。
LOOP:MOV R0,#30
LPP:LCALL LED
LCALL DEL
JNB P2。4,LOP2
DEC R0
CJNE R0,#5,LPP
MOV R0,#5
LPP1:JNB P2。4,LOP2
LCALL LED
LCALL DE
DEC R0
CJNE R0,#0,LPP1
MOV R0,#0
LCALL LED
LCALL DEL
LJMP START
<4>延時程序
該系統設計了兩段延時程序,一段1秒延時,是為了30秒倒計時調用和程序中一秒延時所用;另一段為0。5秒延時,用於報警。程序的設計中報警時間為一秒,但是由於在硬體的設計時只設計了一個按鍵,這樣就會造成連續按鍵時會使所設定的報警聲不斷的響,這是設計中不允許的,所以在軟體編程時設計了一個0。5秒的延時,被報警時所調用,這樣就使報警聲能很清楚地區分出來了
DEL:MOV R6,#20 DEL01:MOV R6,#10
DEL1:MOV R5,#100 DEL11:MOV R5,#100
DEL2:MOV R4,#250 DEL21:MOV R4,#250
DJNZ R4,$ DJNZ R4,$
DJNZ R5,DEL2 DJNZ R5,DEL21
DJNZ R6,DEL1 DJNZ R6,DEL11
RET RET
<5>報警程序
該段程序主要是用於本系統中的所有報警使用,報警時間延時為1秒鍾。
DE:CLR P1。2
LCALL DEL01
SETB P1。2
LCALL DEL01
RET
三、製作過程
五、參考文獻
曾峰,鞏海洪,曾波,電子工業出版社,印刷電路板(PCB)設計與製作 2005.8
梅海鳳,王艷秋,張軍,汪毓鐸,清華大學出版社 單片機原理與介面技術 2004.2
北京交通大學出版社
第二個文獻:基於51單片機八路搶答器設計程序及電路圖
基於51單片機八路搶答器設計程序及電路圖
說明:本人的這個設計改進後解決了前一個版本中1號搶答優先的問題,並增加了錦囊的設置,當參賽選手在回答問題時要求使用錦囊,則主持人按下搶答開始鍵,計時重新開始。
;八路搶答器電路請看下圖是用ps模擬的,已經測試成功
<單片機八路搶答器電路圖>
;============================================================
;================單片機八路搶答器程序 =====================
;================ 51hei =======================
;================ 2008 年 5月 =======================
;============================================================
OK EQU 20H;搶答開始標志位
RING EQU 22H;響鈴標志位
ORG 0000H
AJMP MAIN
ORG 0003H
AJMP INT0SUB
ORG 000BH
AJMP T0INT
ORG 0013H
AJMP INT1SUB
ORG 001BH
AJMP T1INT
ORG 0040H
MAIN: MOV R1,#30;初設搶答時間為30s
MOV R2,#60;初設答題時間為60s
MOV TMOD,#11H;設置未定時器/模式1
MOV TH0,#0F0H
MOV TL0,#0FFH;越高發聲頻率越高,越尖
MOV TH1,#3CH
MOV TL1,#0B0H;50ms為一次溢出中斷
SETB EA
SETB ET0
SETB ET1
SETB EX0
SETB EX1;允許四個中斷,T0/T1/INT0/INT1
CLR OK
CLR RING
SETB TR1
SETB TR0;一開始就運行定時器,以開始顯示FFF.如果想重新計數,重置TH1/TL1就可以了
;=====查詢程序=====
START: MOV R5,#0BH
MOV R4,#0BH
MOV R3,#0BH
ACALL DISPLAY;未開始搶答時候顯示FFF
JB P3.0,NEXT;ddddddd
ACALL DELAY
JB P3.0,NEXT;去抖動,如果"開始鍵"按下就向下執行,否者跳到非法搶答查詢
ACALL BARK;按鍵發聲
MOV A,R1
MOV R6,A;送R1->R6,因為R1中保存了搶答時間
SETB OK;搶答標志位,用於COUNT只程序中判斷是否查詢搶答
MOV R7,#01H ;讀搶答鍵數據信號標志,這里表示只讀一次有用信號
MOV R3,#0AH;搶答只顯示計時,滅號數
AJMP COUNT;進入倒計時程序,"查詢有效搶答的程序"在COUNT裡面
NEXT: JNB P1.0,FALSE1
JNB P1.1,FALSE2
JNB P1.2,FALSE3
JNB P1.3,FALSE4
JNB P1.4,FALSE5
JNB P1.5,FALSE6
JNB P1.6,FALSE7
JNB P1.7,FALSE8
AJMP START
;=====非法搶答處理程序=====
FALSE1: MOV R3,#01H
AJMP ERROR
FALSE2: MOV R3,#02H
AJMP ERROR
FALSE3: MOV R3,#03H
AJMP ERROR
FALSE4: MOV R3,#04H
AJMP ERROR
FALSE5: MOV R3,#05H
AJMP ERROR
FALSE6: MOV R3,#06H
AJMP ERROR
FALSE7: MOV R3,#07H
AJMP ERROR
FALSE8: MOV R3,#08H
AJMP ERROR
;=====INT0(搶答時間R1調整程序)=====
INT0SUB:MOV A,R1
MOV B,#0AH
DIV AB
MOV R5,A
MOV R4,B
MOV R3,#0AH
ACALL DISPLAY;先在兩個時間LED上顯示R1
JNB P3.4,INC0;P3.4為+1s鍵,如按下跳到INCO
JNB P3.5,DEC0;P3.5為-1s鍵,如按下跳到DECO
JNB P3.1,BACK0;P3.1為確定鍵,如按下跳到BACKO
AJMP INT0SUB
INC0: MOV A,R1
CJNE A,#63H,ADD0;如果不是99,R2加1,如果加到99,R1就置0,重新加起。
MOV R1,#00H
ACALL DELAY1
AJMP INT0SUB
ADD0: INC R1
ACALL DELAY1
AJMP INT0SUB
DEC0: MOV A,R1
JZ SETR1;如果R1為0, R1就置99,
DEC R1
ACALL DELAY1
AJMP INT0SUB
SETR1: MOV R1,#63H
ACALL DELAY1
AJMP INT0SUB
BACK0: RETI
;=====INT1(回答時間R2調整程序)=====
INT1SUB:MOV A,R2
MOV B,#0AH
DIV AB
MOV R5,A
MOV R4,B
MOV R3,#0AH
ACALL DISPLAY
JNB P3.4,INC1
JNB P3.5,DEC1
JNB P3.1,BACK1
AJMP INT1SUB
INC1: MOV A,R2
CJNE A,#63H,ADD1
MOV R2,#00H
ACALL DELAY1
AJMP INT1SUB
ADD1: INC R2
ACALL DELAY1
AJMP INT1SUB
DEC1: MOV A,R2
JZ SETR2
DEC R2
ACALL DELAY1
AJMP INT1SUB
SETR2: MOV R2,#63H
ACALL DELAY1
AJMP INT1SUB
BACK1: RETI
;=====倒計時程序(搶答倒計時和回答倒計時都跳到改程序)=====
REPEAT:MOV A,R2 ;使用錦囊時重新計時
MOV R6,A
CLR RING
COUNT: MOV R0,#00H;重置定時器中斷次數
MOV TH1,#3CH
MOV TL1,#0B0H;重置定時器
RECOUNT:MOV A,R6;R6保存了倒計時的時間,之前先將搶答時間或回答時間給R6
MOV B,#0AH
DIV AB;除十分出個位/十位
MOV 30H,A;十位存於(30H)
MOV 31H,B;個位存於(31H)
MOV R5,30H;取十位
MOV R4,31H;取個位
MOV A,R6
SUBB A,#07H
JNC LARGER;大於5s跳到LARGER,小於等於5s會提醒
MOV A,R0
CJNE A,#0AH,FULL;1s中0.5s向下運行
CLR RING
AJMP CHECK
FULL: CJNE A,#14H,CHECK;下面是1s的情況,響並顯示號數並清R0,重新計
SETB RING
MOV A,R6
JZ QUIT;計時完畢
MOV R0,#00H
DEC R6;一秒標志減1
AJMP CHECK
LARGER: MOV A,R0
CJNE A,#14H,CHECK;如果1s向下運行,否者跳到查"停/顯示"
DEC R6;計時一秒R6自動減1
MOV R0,#00H
CHECK: JNB P3.1,QUIT;如按下停止鍵退出
JNB OK,CHECKK ;只在回答倒計時才有效
AJMP NEXTT
CHECKK:JNB P3.0,REPEAT ;判斷是否使用錦囊
NEXTT: ACALL DISPLAY
JB OK,ACCOUT;如果是搶答倒計時,如是則查詢搶答,否者跳過查詢繼續倒數(這里起到鎖搶答作用)
AJMP RECOUNT
ACCOUT:
MOV A,36H
JNB ACC.0,TRUE1
JNB ACC.1,TRUE2
JNB ACC.2,TRUE3
JNB ACC.3,TRUE4
JNB ACC.4,TRUE5
JNB ACC.5,TRUE6
JNB ACC.6,TZ1
JNB ACC.7,TZ2
AJMP RECOUNT
TZ1:JMP TRUE7
TZ2:JMP TRUE8
QUIT: CLR OK;如果按下了"停止鍵"執行的程序
CLR RING
AJMP START
;=====正常搶答處理程序=====
TRUE1: ACALL BARK
MOV A,R2
MOV R6,A;搶答時間R2送R6
MOV R3,#01H
CLR OK;因為答題的計時不再查詢搶答,所以就鎖了搶答
AJMP COUNT
TRUE2:ACALL BARK
MOV A,R2
MOV R6,A
MOV R3,#02H
CLR OK
AJMP COUNT
TRUE3:ACALL BARK
MOV A,R2
MOV R6,A
MOV R3,#03H
CLR OK
AJMP COUNT
TRUE4:ACALL BARK
MOV A,R2
MOV R6,A
MOV R3,#04H
CLR OK
AJMP COUNT
TRUE5:ACALL BARK
MOV A,R2
MOV R6,A
MOV R3,#05H
CLR OK
AJMP COUNT
TRUE6: ACALL BARK
MOV A,R2
MOV R6,A
MOV R3,#06H
CLR OK
AJMP COUNT
TRUE7:ACALL BARK
MOV A,R2
MOV R6,A
MOV R3,#07H
CLR OK
AJMP COUNT
TRUE8:ACALL BARK
MOV A,R2
MOV R6,A
MOV R3,#08H
CLR OK
AJMP COUNT
;=====犯規搶答程序=====
ERROR: MOV R0,#00H
MOV TH1,#3CH
MOV TL1,#0B0H
MOV 34H,R3;犯規號數暫存與(34H)
HERE: MOV A,R0
CJNE A,#06H,FLASH;0.3s向下運行->滅並停響
CLR RING
MOV R3,#0AH
MOV R4,#0AH
MOV R5,#0AH;三燈全滅
AJMP CHECK1
FLASH: CJNE A,#0CH,CHECK1;下面是0.8s的情況,響並顯示號數並清R0,重新計
SETB RING
MOV R0,#00H
MOV R3,34H;取回號數
MOV R5,#0BH
MOV R4,#0BH;顯示FF和號數
AJMP CHECK1
CHECK1: JNB P3.1,QUIT1
ACALL DISPLAY
AJMP HERE
QUIT1: CLR RING
CLR OK
AJMP START
;=====顯示程序=====
DISPLAY:MOV DPTR,#DAT1;查表顯示程序,利用P0口做段選碼口輸出/P2低三位做位選碼輸出,
MOV A,R3
MOVC A,@A+DPTR
MOV P2,#0feH
MOV P0,A
ACALL DELAY2
MOV DPTR,#DAT2
MOV A,R5
MOVC A,@A+DPTR
MOV P2,#0fdH
MOV P0,A
ACALL DELAY2
MOV A,R4
MOVC A,@A+DPTR
MOV P2,#0fbH
MOV P0,A
ACALL DELAY2
RET
DAT1:DB 00h,06h,5bh,4fh,66h,6dh,7dh,07h,7fh,6fh,00H,71H
;"滅","1","2","3","4","5","6","7","8","9","滅","F"
DAT2:DB 3fh,06h,5bh,4fh,66h,6dh,7dh,07h,7fh,6fh,00H,71H
;第一個為零,其他與上相同,因為十位如果為零顯示熄滅
;====加減時間延時(起到不會按下就加N個數)======
DELAY1: MOV 35H,#08H
LOOP0: ACALL DISPLAY
DJNZ 35H,LOOP0
RET
;=====延時4236個機器周期(去抖動用到)=====
DELAY: MOV 32H,#12H
LOOP: MOV 33H,#0AFH
LOOP1: DJNZ 33H,LOOP1
DJNZ 32H,LOOP
RET
;=====延時4236個機器周期(顯示用到)=====
DELAY2: MOV 32H,#43H
LOOP3: MOV 33H,#1EH
MOV A,R7 ;每隔60~70個機器周期讀一次P1口,全為1時為無效數據,繼續讀,有一個不為1時,轉到正常搶答處理
JNZ AAAA1 ;沒讀到有效數據時繼續轉到AAAA1
LOOP2: DJNZ 33H,LOOP2
DJNZ 32H,LOOP3
RET
;=====讀搶答按鍵數據口程序=====
;由於在讀搶答數據口的時候,單片機首先進入倒計時程序,再調用顯示程序,最後才檢測按鍵口
;然而在檢測按鍵口時動態掃描要調用三次(4ms)延時程序.這樣就會導致讀數據口出現滯後,造成1號優先最高.8號最低.
;故採用在延時子程序中加了讀數據口程序.保證了靈敏度和可靠性
AAAA1: MOV A,P1
CJNE A,#0FFH,AA1 ;當不全為1時的數據為有效數據
AA0: MOV 36H,A ;將有效數據送到36H暫存
AJMP LOOP2
AA1: DEC R7
AJMP AA0
;=====發聲程序=====
BARK: SETB RING
ACALL DELAY1
ACALL DELAY1
CLR RING;按鍵發聲
RET
;=====TO溢出中斷(響鈴程序)=====
T0INT: MOV TH0,#0ECH
MOV TL0,#0FFH
JNB RING,OUT;
CPL P3.6;RING標志位為1時候P3.6口不短取反使喇叭發出一定頻率的聲音
OUT: RETI
;=====T1溢出中斷(計時程序)=====
T1INT: MOV TH1,#3CH
MOV TL1,#0B0H
INC R0
RETI
END
僅供參考。
⑹ 幾道單片機的編程題
//第一題:給10分喲
/* 晶振12MHz,T0為模式1,產生1ms方波,那麼半周期為500us, 65536-500=65036=0XFE0C,則TH0=0xFE, TL0=0x0C */
#include "regx51.h"
void T0_ISR() interrupt 1
{
TH0=0xFE;
TL0=0x0c;
P1_0=~P1_0; //每500us取反一次,形成周期為1ms的方波
}
Main()
{
ET0=1; //允許T0中斷
TMOD=0x01; //設置T0工作模式1
P1_0=0;
TH0=0xFE;
TL0=0x0c;
TR0=1; //T0運行
EA=1;
while(1)
{};
}
//第二題
unsigned int rom, *p
char i;
Main()
{
p=0x30;
rom=*p;
i=1;
while(i<=10)
{
p++;
if (rom>*p)
{rom=*p}
i++;
}
}
⑺ 怎樣學習單片機編程,單片機編程實例
1,首先要學習C語言基礎,就相當於80%會單片機了,因為現在所有8/16/32位(51系列,MSP430系列,ARM系列)都是使用C語言。
2,聽起來單片機比較陌生,不是因為不懂,而是不知道方法和流程。現簡單說說,僅供參考;
3,先看內核8051的單片機:台灣宏晶的STC89C51-DIP40/或其它如新茂,到網上買一個開發板,價格不會超過200元。
4,看一下單片機功能:包換內部FLASH、RAM、TIMER、INT、ADC、USB、ISP/IAR等。
5,編譯環境、編程軟體KEIL。
6,打開開發板的例子程序,在KEIL編譯,下載到板,看結果和說明是不是相符,達到這樣效果時,心裡肯定很激動,這時真正學會了單片機,成功了。
7,然後再學會看電路圖,電路圖其實很簡單,就是一根線從一個地方連接到另一個地方,寫代碼時,只記住單片機是哪一個管腳,然後對它寫代碼即可
⑻ 簡單 單片機編程!~!~~~
1.
mov a,#0 ;將A清零
clr c ;清進位標志位
mov a,r1 ;取低位元組數據
add a,r7 ;低位元組數據相加
mov 60h,a ;存低位結果
mov a,r0 ;取高位字字
addc a,r6 ;未高位和並加上低位的進位
mov 61h,a ;存高位結果
2.80C52 內部12分頻,故將 6M/12 = 0.5M 得到頻率,然後將頻率換為
一個機器周期的時間 T = 1/ (0.5M) = 2 * e -6
即為2us,一個機器周期的時間 為2 us;
DELAY:MOV R7,#0F6H ; 該指令執行為 2 T 設標號為 A指令
LP: MOV R6,#0FAH ;該指令執行為 2 T 設標號為 B指令
DJNZ R6,$ ;該指令執行為 2 T 設標號為 C指令
DJNZ R7,LP ;該指令執行為 2 T 設標號為 D指令
RET
B指令將 250 傳給 R6, C 指令中 的 "$" 表示本條指令的地址,所以一直在執行 C指令,
該所用時間 為 2T ,共為 250次, 250* 2T為C指令所執行的時間 ,
D指令中R7為 246,他會執行 B ,C ,D 三條指令,所以,每次要 2T + 250* 2T +2T 的時間 ,
共為 246 *( 2T + 250* 2T +2T ) 再加上A指令的2T 時間 所以共為:
246 *( 2T + 250* 2T +2T ) + 2T = 247972 us 在單片機中記為 250 ms的延時
3.
個人感覺 題目有些問題,51在做16位除法的時候 比較復雜一點
雖然可以做出來,我簡單的將其最8位處理
mov r0,#50h
mov r7,#10
mov a,#0
loop: add a,@r0
inc r0
djnz r7,loop
mov b ,#10
div ab
mov 5ah,a
4.
MOV R6,#0FAH
mov r7,#10
lp: DJNZ R6,$ ; 1 ms延時
DJNZ R7,LP ; 10 次
RET
約為,10ms,一般情況,十幾us的偏差是正常的。
注意,這是在你的剛說的 晶振6MHZ 的前提下的。
⑼ 單片機編程 什麼是送位選,能不能舉個例子
單片機編程所謂的送位選,一般是指多數碼管顯示時,採用動態掃描方式驅動,由於單一時刻只能有一個數碼管發光,送出使這個數碼管發光的位,就叫送位選。
舉個例子:
P1口D0到D7由低位到高位順序控制8個數碼管,低電平有效,為了使所有數碼管看起來都是亮的,就要輪流送位選信號,可以使用如下辦法:
led=0xfe;//led變數已定義,在此送位選初值
刷新函數中:
P1=led;//送位選
led=led<<1;//准備下一位
led=led | 0x01;//低位置1
if(led==0xff)led=0xfe;//已完成一個循環重新開始
⑽ 單片機編程
#include<reg51.h>
#defineucharunsignedchar
uchartab[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x71};//0到9
ucharnum=0,cnt=0,disn=26,inter=0,lp=0;
ucharled[]={1,2,3,4};
voiddealdat(uchara)
{
led[0]=disn%10;
led[1]=disn/10;
switch(a)
{
case0:led[2]=10;led[3]=0;led[3]=0;led[3]=0;break;
case1:led[2]=0;led[3]=10;led[3]=0;led[3]=0;break;
case2:led[2]=0;led[3]=0;led[3]=10;led[3]=0;break;
case3:led[2]=0;led[3]=0;led[3]=0;led[3]=10;break;
default:break;
}
}
voidext0()interrupt0
{
inter++;
inter%=3;
switch(inter)
{
case0:disn=26;break;
case1:disn=29;break;
case2:disn=43;break;
default:break;
}
}
voidt0isr()interrupt1
{
TH0=(65536-5000)/256;
TL0=(65536-5000)%256;
cnt++;
if(cnt>=60)
{
cnt=0;
lp++;
lp%=4;
dealdat(lp);
}
switch(num)
{
case0:P2=0x01;break;
case1:P2=0x02;break;
case2:P2=0x04;break;
case3:P2=0x08;break;
default:break;
}
P0=~tab[led[num]];
num++;
num&=0x03;
cnt++;
if(cnt>100)
{
cnt=0;
disn++;
disn%=4;
dealdat(disn);
}
}
main()
{
TMOD=0x11;
TH0=(65536-5000)/256;
TL0=(65536-5000)%256;
TR0=1;
ET0=1;
EX0=1;
IT0=1;
EA=1;
while(1);
}