淺談單片機中C語言與彙編語言的轉換

来源:http://www.cnblogs.com/OctoptusLian/archive/2016/12/26/6224065.html
-Advertisement-
Play Games

做了一單片機設計,要用C語言與彙編語言同時實現,現將這次設計的感受和收穫,還有遇到的問題寫下,歡迎感興趣的朋友交流想法,提出建議。 單片機設計:基於51單片機的99碼表設計 軟體環境:Proteus8.0 + Keil4 要求:1,開關按一下,數位管開始計時。2,按兩下,數位管顯示靜止。3,按三下, ...


做了一單片機設計,要用C語言與彙編語言同時實現,現將這次設計的感受和收穫,還有遇到的問題寫下,歡迎感興趣的朋友交流想法,提出建議。

單片機設計:基於51單片機的99碼表設計

軟體環境:Proteus8.0 + Keil4

要求:1,開關按一下,數位管開始計時。2,按兩下,數位管顯示靜止。3,按三下,數位管數值清零。

C語言程式如下:

 1 #include<reg51.h>
 2 #define uint unsigned int
 3 #define uchar unsigned char
 4 uchar shi,ge,aa,keycount=0,temp;
 5 sbit anjian=P1^7;
 6 uchar code table[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};
 7 void display(shi,ge);
 8 void key ();
 9 void init();
10 void delay(uint z);
11 /*-----主程式-----*/
12 void main()
13 {
14     init();        //初始化
15     while(1)
16     {    
17         key ();
18         if(keycount==1)
19          TR0=1;        //開中斷
20           if(keycount==2)
21            TR0=0;
22          if(keycount==3)
23         {    
24             temp=0;
25             keycount=0;
26         }
27         if(aa==10){aa=0;
28          if(temp<=99)
29             {                
30                 temp++;display(shi,ge);
31             }
32             else
33             temp=0;}
34     }
35 }
36 
37 
38 /*------初始化程式-------*/
39 void init()
40 {    
41     keycount=0;
42     temp=0;
43     TMOD=0x01;
44     TH0=(65536-50000)/256;
45     TL0=(65536-50000)%256;
46     EA=1;
47     ET0=1;
48     //TR0=0;        
49 }
50 /*-----定時器中斷-----*/
51 void timer0() interrupt 1
52 {
53     TH0=(65536-50000)/256;
54     TL0=(65536-50000)%256;
55     aa++;    
56 }
57 /*-----顯示子程式-----*/
58 void display(shi,ge)
59 {    
60     shi=temp/10;
61     ge=temp%10;
62     P0=table[shi];;delay(70);
63     P2=table[ge]; ;delay(70);
64 }
65 /*-----按鍵檢測子程式-----*/
66 void key ()
67 {
68     if(anjian==0)
69     {
70         delay(5);        //消抖
71         if(anjian==0)
72         keycount++;
73     }
74      //while(anjian==0);    
75     //display(shi,ge);        //等待按鍵彈起
76 }
77 /*-----延時子程式-----*/
78 void delay(uint z)        //延時約1ms
79 {
80     uint x,y;
81     for(x=z;x>0;x--)
82         for(y=100;y>0;y--);
83 }        

 電路模擬結果如下:

好了,那麼接下來我們就開始C語言——>彙編語言之旅^_^

(1)C語言1-10行改為

 1 ORG        0000H      //彙編起始偽指令,功能是規定程式存儲器中源程式或數據塊存放的起始地址
 2 ajmp        STAR     //ajmp無條件跳轉指令
 3 ORG        000bh
 4 ajmp       timer0                
 5 anjian        equ         P1.7     //位定義
 6 keycount     equ      40h
 7 shi             equ         41h
 8 gewei         equ         42h
 9 aa             equ         43h
10 temp        equ         44h
11 tab:         db          3fh,6h,5bh,4fh,66h      //建表
12             db          6dh,7dh,7h,7fh,6fh      

 

(2)C語言中的初始化函數 12-14行和39-49行改為

1 STAR:      
2     acall init  //子程式近程調用指令,功能是主程式調用子程式,調用子程式的範圍為2kb
 1 init:
 2      mov keycount,#0  //keycount=0
 3      mov temp,#0      //temp=1
 4      mov tmod,#01h      //TMOD=0x01
 5      mov TH0,#60
 6      mov TL0,#176
 7      setb EA   //位置位指令,對操作數所指出的位進行置1操作
 8      setb ET0
 9      setb TR0
10      ret

acall為子程式近程調用指令,返回用ret。

(3)C語言中15-35行是個while迴圈,邏輯比較繁瑣,註意了!

 1 START:          
 2     acall display  
 3     inc   temp  //加1指令,將操作數所指定的單元或寄存器中的內容加1
 4     acall delay70  //近程調用delay70
 5 x8:     mov r0,keycount
 6      cjne r0,#2,F1     //cjne比較跳轉指令,若r0=2則跳轉到x8,否則跳轉到F1。
 7      ajmp x8
 8 F1:     mov r0,temp
 9      cjne r0,#99,START     //若r0<99時,重覆迴圈,否則temp=0
10       mov temp,#0
11      ajmp START    
12 F9:        
13         acall key                 
14         mov r0,keycount
15         cjne r0,#0,F2  //keycount=0順序執行,否則跳轉到F1
16         CLR P1.3      //清0
17         SETB TR0    
18        
19 F2:      mov r0,keycount     //第二次按鍵
20       cjne r0,#2,F2
21       clr TR0
22       reti                  
23       mov r0,keycount           //第三次按鍵
24       cjne r0,#3,F3
25       mov temp,#0
26       mov keycount,#0

inc 增量指令,功能是將操作數所指定的單元或寄存器中的內容加1,其結果返還回原操作數單元中。

clr 位複位,功能是對操作數所指出的位進行清“0”操作。

或者在中斷函數中

 1 timer0:
 2 w1:    
 3     acall key
 4     mov TH0,#60
 5     mov TL0,#176
 6     cpl p1.0    
 7     JB keycount,x2
 8     ajmp x3 
 9 x2:     
10      ajmp START
11      clr  p1.0
12      ajmp w1
13      ajmp w1
14 
15 x3:      mov r0,keycount
16       cjne r0,#3,w1     //若r0=3則順序執行,否則跳轉到w1
17       mov temp,#0
18       mov keycount,#0        
19       ret

 

(4)C語言58-64行display函數改為

 1 display:        
 2      mov a,temp
 3      mov b,#10
 4      div ab  //除法指令,實現兩個八位無符號數的除法操作。
 5      mov r2,A    
 6      mov r3,B
 7      mov dptr,#tab //16位數據傳送使用方式
 8      mov a,r2
 9      movc a,@a+dptr //查表,先將累加器A的內容與數據指針寄存器DPTR的內容相加,再以其結果為地址,將該地址的結果送入A中
10      mov P0,a
11      acall delay70
12      nop  //空指令
13      mov a,r3
14      movc a,@a+dptr
15      mov P2,a
16      nop
17      acall delay70    
18      ret

div為除法指令,功能是實現兩個8位無符號數的除法操作,一般被除數放在累加器A中,除數放在寄存器B中。指令執行後,商放在A中,餘數放在B中。

movc為查表指令,先將累加器A的內容與數據指針寄存器DPTR的內容相加,再以其結果為地址,將該地址的內容送入A中。

nop為空操作指令,它不作任何操作,但要占用一個機器周期(即12個振蕩周期)的時間,常用於延時或等待。(有些程式執行的效果由於延時時間太短,在人眼視覺暫時作用下無法辨認清楚)

此段程式的作用在於將一個兩位數分別分在一個十位上的數位管和一個個位上的數位管顯示。

(5)C語言66-76行key函數改為

1 key:
2         jb anjian,F6  //若anjian=0則順序執行,否則跳轉到F6
3         ACALL delay5
4         inc keycount  //keycount++
5 F6:        
6         ret      

jb為位條件轉移指令,功能是若直接定址的位bit=1,則程式轉移到指定的目標地址去執行,若bit=0,則程式順序執行。

(6)C語言78-83行delay函數改為

 1 delay70: 
 2         mov r6,#70
 3 D2:        mov R7,#248    
 4 d1:        djnz R7,d1     //248*70次
 5         djnz R6,D2
 6         ret
 7         
 8 delay5:    
 9         mov r6,#5  //消抖。
10 F7:     mov R7,#248
11 F8:     djnz r7,F8     //248*5次
12         djnz r6,F7
13         ret

註意:248=2,約等於1ms。delay為延時程式。

 

溫馨提示:在彙編中程式代碼的大小寫不受影響,但在C語言中就有影響了。

思考1:ret 和 reti都是程式返回指令,有什麼區別?

我的回答:ret是子程式返回指令,reti是中斷子程式返回指令。區別在於如果是acall 、lcall指令調用的子程式,返回指令就用ret;如果地址是0003,0013,000B,001B,0023調用的子程式,返回指令就用reti。

 

思考2:mov 20h,#0h 和 setb 20h 都是加1,用什麼區別?

我的回答:mov指令中的20h指位元組,setb中的20h是位。

 

旅途結束!

還記得前段時間我一直糾結於彙編語言中的各種指令的語法和功能,直到一個陽光明媚的中午,我一手拿著已經寫好的兩頁半的C語言代碼,一手拿著一本單片機的彙編指令查詢手冊,開始一行一行的翻譯,可能彙編代碼會在調試中有所錯誤,但基本邏輯是對的。而且這次C——>彙編,使我更加深入地理解了數據在電腦中的存儲與調用。在此期間班主任和同學也給我答疑解惑,相信在以後的道路上,我會更加更深入地理解電腦。越努力,越幸運!

 

 

                                                                                                                                                                                                                                -Zoctopus

                                                                                                                                                                                                                               2016.12.26

 


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • MySQL 系列(三)你不知道的 視圖、觸發器、存儲過程、函數、事務、索引、語句 第一篇:MySQL 系列(一) 生產標準線上環境安裝配置案例及棘手問題解決 第二篇:MySQL 系列(二) 你不知道的資料庫操作 第三篇:MySQL 系列(三)你不知道的 視圖、觸發器、存儲過程、函數、事務、索引、語句 ...
  • MySQL 系列(一) 生產標準線上環境安裝配置案例及棘手問題解決 一、簡介 MySQL是最流行的開放源碼SQL資料庫管理系統,它是由MySQL AB公司開發、發佈並支持的。有以下特點: MySQL是一種資料庫管理系統。 MySQL是一種關聯資料庫管理系統。 MySQL軟體是一種開放源碼軟體。 My ...
  • 開篇小故事 下麵的故事都是真實的,猶如雷同純屬同類,請仔細反思。 故事1:升級硬體 客戶後臺資料庫存在性能問題,查詢特別慢,長時間語句很多。客戶因此而苦惱,咨詢了軟體廠商我該怎麼辦?軟體廠商給出的答案:升級硬體吧,現在的資源不能滿足了! 那麼客戶是什麼硬體配置呢?資料庫什麼體量呢? 答:128的CP ...
  • 隨著技術的發展,IT逐漸面臨越來越多的挑戰,尤其是數據治理方面。而九州通醫葯集團在IT建設方面不畏艱險,自主研發ERP系統、物流系統,在解決企業自身問題的同時還創新投入商業化,為同行業提供服務,樹立標桿形象。 ...
  • 之前介紹了資料庫的增刪改查, 發現忘記了資料庫的一些基本操作, 比如建庫, 建表, 改表等等. 那這裡就來小結一下資料庫sql形式的基本操作. 一、庫操作 1. 建庫 在建庫之前, 可能需要看一下, 資料庫裡面, 已經存在哪些庫, 這樣可以去處理重覆的問題. 這裡之所以會出現newdb, 是因為我已 ...
  • 要對函數進行調試需要安裝插件pldbgapi,當初在windows上面的postgresql實例中執行了一下語句就安裝上了: create extension pldbgapi; 但是在linux中執行該語句時提示沒有這個文件,上網查了好幾個資料,使用德哥的方法。不過在實際操作中還是有出入,這裡做一 ...
  • 系統:centos6.6 下載google身份驗證包google-authenticator-master(其實只是一個.zip文件,在windwos下解壓,然後傳進linux) #cd /data/google-authenticator-master/libpam #yum install li ...
  • 第五節 遠程SSH連接服務與基本排錯 標簽(空格分隔):Linux實戰教學筆記 陳思齊 第1章 遠程連接LInux系統管理 1.1 為什麼要遠程連接Linux系統 ![屏幕快照 2016 12 25 下午10.04.28.png 633.3kB][1] 在實際的工作場景中,虛擬機界面或物理伺服器本地 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...