怎樣下載單片機(jī)參數(shù)
代碼下載到單片機(jī)中的方法有兩種,一種在通過ISP(在線下載)下載到單片機(jī),另外一種比較常見的是通過編程器把代碼燒錄到單片機(jī)。
只要把匯編指令都寫出來了,你就可以到指令表中找到每一條指令所對應(yīng)的機(jī)器碼,然后你只要在機(jī)器碼后面加上操作數(shù)即可,比如,把一個(gè)30H單元送入A累加器;指令是這樣的:MOV A , 30H .那么你可以在指令表中查到執(zhí)行這條指的機(jī)器碼是1110 0101,但是由于這條指令后面的那個(gè)30H單元的數(shù)是根據(jù)你的要求在不斷的變的,機(jī)器沒規(guī)定你只能用30H單元,所以這個(gè)30的操作數(shù)必須由你填,它們和在一塊兒,這條指令的機(jī)器碼是:1110 0101 0011 0000用十六進(jìn)制來表示:E530,很明顯前兩位E5是機(jī)器指定的,而后兩位30是你自己加進(jìn)去的。共是十六位,占用兩個(gè)字節(jié)……。 你說的LED燈閃爍,不知是指的流水燈還是一只發(fā)光二極管在不停地閃爍?但不管是哪一種,有一點(diǎn)很重要。你在編寫此程序時(shí)必須要考慮延時(shí),因?yàn)?1單片機(jī)的晶體振蕩器最低頻率可能是6M(具體數(shù)值我已記不清了)。也就是說單片機(jī)的每一個(gè)機(jī)器周期所占用的時(shí)間僅2微秒,如果你不考慮延時(shí)的話,那么你設(shè)計(jì)的那盞燈,它閃爍的結(jié)果是;亮2微秒,熄2微秒,也就是說每一秒鐘要亮暗50萬次,肉眼看這盞燈根本就不會(huì)有熄滅的時(shí)候,只是比不閃的燈暗了一半。我們生活中用的白熾燈,每秒鐘亮暗100次,你能感覺出燈泡有熄滅的時(shí)候嗎?更何況那是50萬次??! 比如設(shè)計(jì)流水燈的程序,不妨可以這樣考慮它的算法。計(jì)數(shù)寄存器的高八位加上低八位,合起來也只有十六位,它能數(shù)的數(shù)最大也就是65535,就算單片機(jī)用的是最低的6M的晶體振蕩器,一個(gè)機(jī)器周期是12個(gè)機(jī)器節(jié)拍,所以,每一個(gè)機(jī)器周期占用2微秒時(shí)間,從0數(shù)到65535,僅用了131070微秒就數(shù)完了,約130毫秒,如果就按這個(gè)延時(shí)去改變燈的亮暗時(shí)間,那么這盞燈每秒鐘要亮暗3、4次,肉眼雖然能夠看到燈有熄滅的時(shí)間了。但是眼睛看這樣的燈總不會(huì)那么舒服,所以至少應(yīng)讓它延時(shí)到1秒鐘亮暗一次。為了計(jì)算方便,就讓計(jì)數(shù)器數(shù)100毫秒的時(shí)間吧!等計(jì)數(shù)器數(shù)到100毫秒后,就讓它再數(shù)一次,然后再數(shù)一次……,等它數(shù)滿5次后,這就是500毫秒(半秒鐘),然后,我們再去改變燈的亮暗狀態(tài)。 這個(gè)程序可以這樣來編: MOV A ,#0FEH ;最低位設(shè)為0 MOV P1, A ;點(diǎn)亮最低位燈 MOV TCON,#10H ;T1為方式1,定時(shí) BEGIN: MOV R7 ,#05H ;設(shè)循環(huán)5次 STAR: MOV TH1 #3CH ;計(jì)數(shù)器數(shù)100毫秒 MOV TL1 #AFH SETB TR1 ;開始計(jì)數(shù) ROU: JBC TF1 SE ;100毫秒到否? SJMP ROU ;等待到100毫秒 SE: CLR TR1 ;關(guān)閉計(jì)數(shù)器 DJNZ R7 STAR ;5次循環(huán)到否? RL A ;把0向左移一位 MOV P1 ,A ;改下一只燈亮 SJMP BEGIN 51的單片機(jī)
ORG 0000H MAIN:MOV R2,#2 L1:MOV R3,#200 L2:MOV R4,#200 L3:NOP NOP DJNZ R4,L3 DJNZ R3,L2 DJNZ R2,L1 CPL P1.7 JMP MAIN END
Medwin編寫C51匯編
八只LED燈做流水燈實(shí)驗(yàn) 單片機(jī)在上電初始后,其各端口輸出為高電平。如果我們現(xiàn)在想讓接在P1.0口的LED1亮,那么我們只要把P1.0口的電平變?yōu)榈碗娖骄涂梢粤恕O胱孡ED1滅,LED0亮,只需將P1.0升高,P1.1變低,LED1就熄滅LED2隨后既點(diǎn)亮!依始類推如下所示8只LED變會(huì)一亮一暗的做流水燈了. P1.0低、P1.0高、P1.1低、P1.1高、P1.2低、P1.2高、P1.3低、P1.3高、P1.4低、P1.4高、P1.5低、P1.5高、P1.6低、P1.6高、P1.7低、P1.7高、返回到開始、程序結(jié)束。 我們不能說P1.1你變低,它就變低了。因?yàn)閱纹瑱C(jī)聽不懂我們的漢語的,只能接受二進(jìn)制的“1、0......”代碼。我們又怎樣來用二進(jìn)制語議論使單片機(jī)按我們的意思去工作呢?為了讓單片機(jī)工作,只能將程序?qū)憺槎M(jìn)制代碼交給其執(zhí)行;早期單片機(jī)開發(fā)人員就是使用人工編寫的二進(jìn)制代碼交給單片機(jī)去工作的。今天,我們不必用煩人的二進(jìn)制去編寫程序,完全可以將我們?nèi)菀桌斫獾摹俺绦蛘Z言”通過“翻譯”軟件“翻譯”成單片機(jī)所需的二進(jìn)制代碼,然后交給單片機(jī)去執(zhí)行。這里的“程序語言”目前主要有匯編和C兩種;在這里我們所說的“翻譯”軟件,同行們都叫它為“編譯器”,將“程序語言”通過編譯器產(chǎn)生單片機(jī)的二進(jìn)制代碼的過程叫編譯。前面說到,要想使LED1變亮,只需將對應(yīng)的單片機(jī)引腳電平變?yōu)榈碗娖骄涂梢粤恕,F(xiàn)在讓我們將上面提到的8只LED流水燈實(shí)驗(yàn)寫為匯編語言程序。
“漢語”語言 匯編語言 開始: star: P1.0低 clr p1.0 P1.0高 setb p1.0 P1.1低 clr p1.1 P1.1高 setb p1.1 P1.2低 clr p1.2 P1.2高 setb p1.2 P1.3低 clr p1.3 P1.3高 setb p1.3 P1.4低 clr p1.4 P1.4高 setb p1.4 P1.5低 clr p1.5 P1.5高 setb p1.5 P1.6低 clr p1.6 P1.6高 setb p1.6 P1.7低 clr p1.7 P1.7高 setb p1.7 返回到開始 ljmp star 結(jié)束 end
這里用到了四條匯編指令:clr、 setb、 ljmp 、end;
clr:是將其后面指定的位清為0; setb:是將其后面指定的位置成1; ljmp:是無條件跳轉(zhuǎn)指令,意思是:跳轉(zhuǎn)到指定的標(biāo)號(hào)處繼續(xù)運(yùn)行。 end:是一條告訴編譯器:程序到此結(jié)束的偽指令。偽指令只告訴編譯器此程序到此有何 要求或條件,它不參與和影響程序的執(zhí)行。這里需要說明的是,按匯編語法要求,所編制的程序(下稱源程序)之格式和書寫要求必須依下列原則: 1、源程序必須為純文本格式文件,如用Windows“附件”中的“記事本”編寫的文本文件;2、源程序的擴(kuò)展名應(yīng)是 *.ASM; 3、一行只能寫一條語句,以回車作為本句的結(jié)束,每一語句行長度應(yīng)少于80個(gè)字符(即40個(gè)漢字)。 4、每行的格式應(yīng)為:標(biāo)號(hào): 命令 參數(shù) ;注釋 即一行由四部份組成,各部份的順序不能搞錯(cuò),依實(shí)際要求可以缺省其中的一部份或幾部份,甚至全部省去,即空白行。需要使用標(biāo)號(hào)時(shí)標(biāo)號(hào)后面必須有“:”(冒號(hào)),而命令語句和參數(shù)之間必須用空格分開,如果命令有多個(gè)參數(shù),則參數(shù)與參數(shù)之間必須用“,”(逗號(hào))分開,需要注釋時(shí)注釋前必須用“;”(分號(hào)),“;”后面的語句可以寫任何字符,包括漢字用于解釋前面的匯編語句,它將不參與匯編,不生成代碼。由于匯編程序?qū)ξ覀冞€不直觀,所以在編寫源程序時(shí),應(yīng)當(dāng)養(yǎng)成多寫注釋的習(xí)慣,這樣有助于今后源程序的閱讀和維護(hù)。 標(biāo)號(hào)是標(biāo)志程序中某一行的符號(hào)名,編譯后標(biāo)號(hào)的數(shù)值就是標(biāo)號(hào)所在行代碼的地址。在宏匯編ASM51中標(biāo)號(hào)的長度不受限制,但標(biāo)號(hào)中不能包含‘:’或其它的一些特殊符號(hào),也不能用漢字,可以用數(shù)字作標(biāo)號(hào),但必須用字母開頭。當(dāng)標(biāo)號(hào)作參數(shù)用(如標(biāo)號(hào)作轉(zhuǎn)移地址),在命令后面出現(xiàn)時(shí),必須舍去‘:’(如上面程序中的 LJMP STAR中的 STAR 是不能再有:)。 每行只能有一個(gè)標(biāo)號(hào),一個(gè)標(biāo)號(hào)只能用在一處,如果有兩行用了同一個(gè)標(biāo)號(hào),則匯編時(shí)就會(huì)出錯(cuò)。由于標(biāo)號(hào)的長度沒有限制,可以用有意義的英文或漢語拼音來說明行,使源程序讀起來更方便。 源程序中的字母不區(qū)分大小寫,也就是說 star 和 STAR 是一樣的,請不要用大小寫方式去區(qū)分不同的標(biāo)號(hào): 流水燈實(shí)驗(yàn)詳解二 上一節(jié)的實(shí)驗(yàn)最后沒有得到“流水”顯示的效果,主要是單片機(jī)執(zhí)行每條指令的時(shí)間很短,我們?nèi)庋蹮o法看到LED的熄滅與點(diǎn)亮。單片機(jī)內(nèi)部能按部就班的自動(dòng)工作,正是在系統(tǒng)時(shí)鐘的作用下,內(nèi)部各邏輯硬件產(chǎn)生各種所需脈沖信號(hào)而實(shí)現(xiàn)的。這個(gè)時(shí)鐘信號(hào)(既晶體振蕩信號(hào))的周期稱“振蕩周期”。我們這個(gè)實(shí)驗(yàn)中晶體使用的是12MHZ. 在單片機(jī)中,要處理最短周期的一條指令需要由12個(gè)振蕩周期(既晶振振蕩周期)組成的,這個(gè)叫“機(jī)器周期”。 8051核的單片機(jī),大多數(shù)指令只用一個(gè)機(jī)器周期(既單周期),也有雙周期和四周期的指令。本實(shí)驗(yàn)中用到的SETB P.x和CLR P.x均屬于單周期指令,也就是說,執(zhí)行一句 SETB P.x 用時(shí)僅1uS(微秒),CLR P.x 也是1uS;難怪我們前面的程序不能看到流水效果。 現(xiàn)在,將程序改動(dòng)一下,在每點(diǎn)亮一個(gè)LED后,讓程序干點(diǎn)別的事,也就是讓它等一會(huì)再將該LED熄滅,繼續(xù)執(zhí)行下面的程序: DDW: ;程序開始 CLR P1.0 ;LED1亮 ACALL DELAY ;調(diào)用延時(shí)子程序 SETB P1.0 ;LED1滅 CLR P1.1 ;換燈,同上 ACALL DELAY SETB P1.1 CLR P1.2 ACALL DELAY SETB P1.2 CLR P1.3 ACALL DELAY SETB P1.3 CLR P1.4 ACALL DELAY SETB P1.4 CLR P1.5 ACALL DELAY SETB P1.5 CLR P1.6 ACALL DELAY SETB P1.6 CLR P1.7 ACALL DELAY SETB P1.7 LJMP DDW ;返回到開始循環(huán) DELAY: ;延時(shí)子程序 MOV R1,#50 AD10: MOV R2,#100 AD11: MOV R3,#100 DJNZ R3,$ DJNZ R2,AD11 DJNZ R1,AD10 RET ;延時(shí)子程序結(jié)束,返回到調(diào)用處的下一句 END 請將上面的程序保存為 1LED.asm,進(jìn)行編譯,并燒寫到AT89S51中,之后將89S51安裝到套件的實(shí)驗(yàn)部份插座上實(shí)驗(yàn),這回顯示的就是“流水燈”的效果了!?回過頭,讓我們看看延時(shí)子程序是怎樣工作的:單片機(jī)內(nèi)部有不少寄存器,這些寄存器在單片機(jī)通電時(shí),你可以給他寫入數(shù)據(jù)(是單片機(jī)按你程序要求寫的數(shù)據(jù),而不是編程器寫的),當(dāng)?shù)诙谓o他寫入新數(shù)據(jù)時(shí),前次的數(shù)據(jù)就被新數(shù)據(jù)覆蓋;當(dāng)然也可以從寄存器中讀取數(shù)據(jù)。當(dāng)單片機(jī)沒有電源供給時(shí),寄存器內(nèi)部的數(shù)據(jù)也隨即消失;這些寄存器人們叫他RAM,而用編程器將我們編寫的程序燒寫到單片機(jī)中的存儲(chǔ)器叫ROM;現(xiàn)在,我們應(yīng)該清楚:RAM是讓程序去使用的,ROM是我們編寫的程序存放的地方! 前面說過,單片機(jī)內(nèi)部有不少RAM,本實(shí)驗(yàn)用的AT89C51有多少寄存器?我們現(xiàn)在不必關(guān)心,現(xiàn)在只須知道單片機(jī)內(nèi)部有名叫R0~R7 的這8個(gè)寄存器。這8個(gè)寄存器每個(gè)都由8個(gè)單獨(dú)的位寄存器組成,最大存放數(shù)據(jù)為二進(jìn)制的 1111 1111,十六進(jìn)制 = FF,十進(jìn)制 = 255。在使用時(shí)注意不要大于其有效范圍。上面延時(shí)程序中,先用到 MOV R1,#50 ,MOV是移動(dòng)的意思,該句是將50這個(gè)十進(jìn)制數(shù)放到R1中;50是立即數(shù),按匯編語言要求前面要加“#”號(hào),匯編語言還規(guī)定,十六進(jìn)制數(shù)后面要加“?H”,十六進(jìn)制數(shù)的高位是字母時(shí)在字母前面還要加“0”,例如:#0F8H;二進(jìn)制數(shù)后面加“B”,例如:#11110000B。十進(jìn)制不加,例如:#100。延時(shí)程序的第二、三句為: MOV R2,#100 ;MOV R3,#100 ;這兩句意思同前。第四句中DJNZ R3,$ 的意思是將 R3 里面的數(shù)減 1 后如果 R3 不等于 0 則跳到后面指定的程序位置,這里的“$”既要跳轉(zhuǎn)的程序位置,“$”代表當(dāng)前語句處,也就是說,R3不等于 0,程序返回再次執(zhí)行本句。如果R3 減 1 后等于0,程序結(jié)束本句,繼續(xù)執(zhí)行下面的語句。延時(shí)程序的最后一句是RET ,意思是退出本子程序,返回到調(diào)用本子程序處的下一句。根據(jù)上面的解釋,一進(jìn)入延時(shí)子程序首先為R1, R2, R3 寄存器裝入我們需要的數(shù)據(jù),然后先對R3 進(jìn)行減數(shù),每次減 1 ,R3 減完后減R2 ,減R2 時(shí)就費(fèi)事啦,因?yàn)镽2 每減 1 后不為 0 需要跳轉(zhuǎn)到AD11 標(biāo)號(hào)處執(zhí)行下面的語句,此時(shí)R3 再次裝入數(shù)據(jù)100,并且還要再次對R3 進(jìn)行減數(shù)......,R2 減完后減R1,減R1的過程你研究研究看看。 每執(zhí)行 DJNZ ?Rn,rel (Rn 指 R0~R7,rel 指轉(zhuǎn)移地址)指令一次,需要2個(gè)機(jī)器周期,單片機(jī)需耗時(shí)2uS(指本實(shí)驗(yàn)),若忽略裝數(shù)等語句,延時(shí)子程序從開始到結(jié)束,單片機(jī)共耗時(shí)100*100*50*2nS,既1000000uS=1秒!若加上裝數(shù)等語句的耗時(shí),延時(shí)時(shí)間大于1秒。 到此,我們做的流水燈已成功,原理大致也明白啦,若你自認(rèn)為這一課你完全明白了,那請你將“流水燈”的流向改變一下,也可以改為兩邊向內(nèi)流,內(nèi)部向外流......,我想你一定能用前面學(xué)到的方法實(shí)現(xiàn)這些功能??赡苡行└呤终f,前面的編程方法是最最笨的!,不錯(cuò)!但玩單片機(jī)初期不必講究語言的簡練,只要能完成預(yù)先要求就好,這是初學(xué)者要知道的。那么還有更好的編程思路嗎?有!請繼續(xù)學(xué)習(xí)下節(jié)課
做流水燈實(shí)驗(yàn)詳解三
在上節(jié)課中讓 LED 流水是去逐個(gè)控制P1端口的每個(gè)位來實(shí)現(xiàn)的,那么我們在程序一開始就給P1口送一個(gè)數(shù),這個(gè)數(shù)本身就讓P1.0先低,其他位為高,然后讓這個(gè)數(shù)據(jù)向高位移動(dòng)不就實(shí)現(xiàn)“流水”效果啦?的確如此!可惜,8051沒有讓P1數(shù)據(jù)移動(dòng)的指令,但有對累加器ACC中數(shù)據(jù)左移或右移的指令,ACC是8051單片機(jī)內(nèi)部算術(shù)邏輯單元中的一個(gè)“寄存器”(這里叫他寄存器是不正確的,但你可以先這樣理解,ACC在指令中常寫為A),他在數(shù)據(jù)傳輸和數(shù)據(jù)處理過程中作用十分重要,ACC為8位。他可與片內(nèi)所有單字節(jié)寄存器交換數(shù)據(jù),實(shí)際上P1和其他端口在單片機(jī)中也是一個(gè)寄存器。這樣我們可以將需移動(dòng)的數(shù)據(jù)先放到ACC中,讓其移動(dòng),然后將ACC移動(dòng)后的數(shù)據(jù)再轉(zhuǎn)送到P1口,這樣同樣可以實(shí)現(xiàn)“流水”效果。
程序如下:DDW: ;開始 MOV ACC,#0FEH ;ACC中先裝入LED1熄滅的數(shù)據(jù)(即二進(jìn)制的 1111 1110) MOV P1,ACC ;將ACC的數(shù)據(jù)送P1口 MOV R0,#7 ;因上句送到?p1口的數(shù)據(jù)就熄滅了一位,所以將數(shù)據(jù)再移動(dòng)7次就完成一個(gè)8位流水過程 LOOP: ;數(shù)據(jù)移動(dòng)循環(huán) Rl A ;將ACC中的數(shù)據(jù)左移一位 MOV P1,A ;把ACC移動(dòng)過的數(shù)據(jù)送p1口顯示 ACALL DELAY ;調(diào)用延時(shí) DJNZ R0,LOOP ;沒有移動(dòng)夠7次繼續(xù)移動(dòng) LJMP DDW ;移動(dòng)完7次后跳到開始重來,以達(dá)到循環(huán)流動(dòng)效果 DELAY: ;延時(shí)子程序,就是上節(jié)課中的延時(shí)子程序 MOV R1,#50 ADl0: MOV R2,#100 ADl1: MOV R3,#100 DJNZ R3,$ DJNZ R2,AD11 DJNZ R1,AD10 RET ;延時(shí)子程序結(jié)束,返回到調(diào)用處的下一句 END ;本匯編程序到此結(jié)束
接下來,將上述程序編譯,并燒寫到前面我們的實(shí)驗(yàn)芯片中,流水效果與第二節(jié)課的一樣。 其實(shí)8051單片機(jī)有111條指令,這111條指令好比以前我們使用數(shù)字傳呼機(jī)時(shí)的“短語代碼”一樣,可以用幾個(gè)“短語代碼”去表示一句完整、通順的語句段落。有的指令常用,有的指令不常用,只要遵守語法規(guī)則,你可以用這些指令“組合”成你想象到的任何程序。當(dāng)然,有時(shí)一條指令可以替代很多條指令,這樣會(huì)使程序簡捷,費(fèi)碼減少,在編寫較大程序時(shí)可以讓程序存儲(chǔ)器放得下你需要的代碼。這也是單片機(jī)高手所追求的。當(dāng)然,在程序存儲(chǔ)器空間不成問題時(shí),你不這樣做但也可以達(dá)到預(yù)期的功能,這也不算錯(cuò)。 單片機(jī)內(nèi)部還有很多“部件”我們只是用到什么說什么,很不系統(tǒng)。但是我也不想系統(tǒng)的介紹這些,因系統(tǒng)介紹單片機(jī)結(jié)構(gòu)和指令的書很多,何況寫的遠(yuǎn)比我好,因此,希望你在看本講座的過程中,還要結(jié)合正規(guī)的教材學(xué)習(xí)其更多的指令和“部件”。
這是我在別的地方找過來的,希望對你有所幫助。
我用的是WAVE6000編譯的。
提交
超越傳統(tǒng)直覺,MATLAB/Simulink助力重型機(jī)械的智能化轉(zhuǎn)型
新大陸自動(dòng)識(shí)別精彩亮相2024華南國際工業(yè)博覽會(huì)
派拓網(wǎng)絡(luò)被Forrester評為XDR領(lǐng)域領(lǐng)導(dǎo)者
智能工控,存儲(chǔ)強(qiáng)基 | ??低晭砭手黝}演講
展會(huì)|Lubeworks路博流體供料系統(tǒng)精彩亮相AMTS展會(huì)