找回密碼
 立即注冊(cè)

QQ登錄

只需一步,快速開始

搜索
查看: 2337|回復(fù): 3
收起左側(cè)

MCU編程實(shí)踐之紅外中斷定時(shí)12864逐步講解一鍋燴

[復(fù)制鏈接]
ID:266429 發(fā)表于 2020-1-2 21:18 | 顯示全部樓層 |閱讀模式
這個(gè)其實(shí)是紅外遙控編程過(guò)程實(shí)驗(yàn),思路是這樣的:
  • 紅外接收管采用中斷口接收信號(hào);
  • 在中斷子程序中,在高低電平的變化時(shí),用計(jì)時(shí)器來(lái)計(jì)時(shí)其高、低電平維持的時(shí)長(zhǎng);
  • 將時(shí)長(zhǎng)值直接用二進(jìn)制數(shù)顯示在12864屏上;
  • us為單位,手工計(jì)算各顯示數(shù)值的時(shí)長(zhǎng)值(這個(gè)可以不做);
  • 根據(jù)紅外遙控NEC標(biāo)準(zhǔn),分析該遙控器的引導(dǎo)碼及比特碼的高低電平時(shí)長(zhǎng)組成,以此獲得引導(dǎo)碼和比特碼的高低電平時(shí)長(zhǎng)特征值,
  • 依據(jù)得到的引導(dǎo)碼和比特碼的高低電平時(shí)長(zhǎng)特征值,再編制程序獲得該遙控器的用戶碼值、各鍵的鍵值。
  • 依據(jù)得到的用戶碼值、各鍵的鍵值,接下來(lái)就可以做遙控控制操作編程了。
    這一套操作下來(lái),你就擁有了獲得各種紅外遙控器用戶碼和鍵值的工具了,然后,你可以給家里的所有紅外遙控器做一個(gè)一桶姜山的專用遙控器了,然后你可以在網(wǎng)上訂印刷板、外殼等的,高檔一點(diǎn)的,全屏觸摸操作帶學(xué)習(xí)。
    下面一步一步來(lái):

一、12864
該屏下有字符顯示和圖形顯示兩種模式,我們選擇字符模式。
字符模式下,其最多可顯示64個(gè)半寬字符,或32個(gè)漢字,可混編,分為四排。輸入位置為一維座標(biāo)確定,左上角的座標(biāo)值為80H。
1.初始化
編程時(shí),首先設(shè)置其為字符模式,命令代碼為10100B(我們這里直接用二進(jìn)制,方便自己看說(shuō)明書及更改功能設(shè)置)。
字符輸入時(shí),我們一般都能看到一個(gè)光標(biāo),以在屏幕上指示正在輸入的位置,這個(gè)光標(biāo)可以開可以關(guān),用命令來(lái)設(shè)置;輸入時(shí)我們一般選擇光標(biāo)向右移動(dòng)、字符從左向右順序輸入(當(dāng)然,你也可以倒著來(lái),或新輸入的字符總是固定在這個(gè)位置),相應(yīng)命令為110B。
然后將字符地址內(nèi)存DDRAM全部清空,將DDRAM的地址計(jì)數(shù)器值歸位。該命令為1B
字符輸入后,你可以控制其顯示或不顯示,光標(biāo)也一樣,所以,我們還要設(shè)置其打開,相應(yīng)命令為1110B。這個(gè)命令中,最后一位為0,表示游標(biāo)位置反白關(guān)。
還有一個(gè)光標(biāo)顯示移位控制命令,先用10100B吧。
這一步算是完成了,執(zhí)行后,你應(yīng)該能看到光標(biāo)。如果沒有,那你的程序就有問題,仔細(xì)檢查,反正沒幾行,我遇到的問題,基本就是延時(shí)不夠,以及該延時(shí)的地方?jīng)]加延時(shí)。
下面給出這部分的匯編程序,當(dāng)然,你也可以用C編。并行輸入,P0口為數(shù)據(jù)口:
        XRS  EQU  0B5H;P35     編程器不認(rèn)P35,只好直接輸入P35的地址值了,下同
    XRW  EQU  0B6H;P36
    XEN  EQU  0B7H;P37
    XPSB EQU ?           這兩個(gè),我的STC8A8K板,已硬件連電位了
    ;XRESET EQU         
    XCOM  EQU 34H
    XDAT  EQU 35H
            
ORG 0000H
        AJMP START
        ORG 0100H
        START:
        ACALL XDELAY
        ACALL XINIT
        AJMP $
        XINIT:
          MOV XCOM,#110000B
          ACALL XWRI
          MOV XCOM,#1H
          ACALL XWRI
          MOV XCOM,#110B
          ACALL XWRI
          MOV XCOM,#1110B
          ACALL XWRI
          MOV XCOM,#10100B
          ACALL XWRI
        RET
               
        XWRI:
          CLR XEN
          CLR XRS
          CLR XRW
          ACALL XDELAY
          MOV P0,XCOM
          SETB XEN
          CLR XEN
          ACALL XDELAY
        RET
         
        XWDAT:
      CLR XEN
      SETB XRS
      CLR XRW
      MOV P0,XDAT
      SETB XEN
      CLR XEN
      ACALL XDELAY
    RET
        
XDELAY: MOV 30h,#40  這個(gè)延時(shí)有點(diǎn)長(zhǎng),短了我的這個(gè)MCU不認(rèn)帳,沒法
   D1: MOV 31h,#25
   D2: DJNZ 31h,D2
   DJNZ 30h,D1
RET
END
2.輸入字符
這個(gè)簡(jiǎn)單,輸入座標(biāo)再輸入字符編碼,搞定。
至此,屏顯編程工作完成。
3.直接以二進(jìn)制顯示一個(gè)存儲(chǔ)單元中的數(shù)值
比如我們要顯示10010110B這個(gè)值,我們把它先輸入到A寄存器中,將這個(gè)值一位一位地進(jìn)行處理并顯示在屏幕上。
對(duì)于初學(xué)者,最好是先將其中任一位的顯示程序做通,然后再做這八位輸入的程序,這個(gè)功能的子程序如下:
XBIT:
        MOV  A,#10010110B
        JB  ACC.0,LOOP1
        LOOP0:MOV XDAT,#30H
        ACALL  XWDAT
        RET
        LOOP1:MOV XDAT,#31H
        ACALL  XWDAT
RET
上面程序中的BACC.0就是最末一位,你可以換成其它位試試能否正確顯示。
這個(gè)做通了,下面做八位全部顯示的。
我們采用移位并循環(huán)法,從高位到低位逐位處理,子程序如下:
X8BIT:
          MOV A,#10010110B
          ACALL XBIT
RET
        XBIT:
          MOV  R2,#08H
          LOOP0:
           RL  A
           JB  ACC.0,LOOP1
           MOV  XDAT,#30H
           ACALL  XWDAT
           DJNZ  R2,LOOP0
            RET
             LOOP1:
             MOV  XDAT,#31H
             ACALL  XWDAT
             DJNZ  R2,LOOP0
        RET
三、中斷程序
其實(shí)中斷的原理蠻簡(jiǎn)單的,設(shè)定相應(yīng)中斷開之后,一旦有中斷信號(hào)被接收到,即中斷口的電平被拉低,則程序就強(qiáng)行發(fā)生跳轉(zhuǎn),這個(gè)跳轉(zhuǎn)是程序存儲(chǔ)器絕對(duì)地址的跳轉(zhuǎn),不同編號(hào)的中斷有不同的跳轉(zhuǎn)地址(中斷向量),比如INT0,其跳轉(zhuǎn)地址為0003H,即程序跳轉(zhuǎn)到地址為0003H處開始執(zhí)行。所以,在主程序中,應(yīng)在0003H地址處寫入中斷子程序,但要注意因另一個(gè)中斷的跳轉(zhuǎn)地址為000BH,之間放不了幾行程序,所以這里一般是寫個(gè)跳轉(zhuǎn)指令,跳轉(zhuǎn)到一個(gè)專門的子程序來(lái)完成中斷后的任務(wù):
  ORG  0003H
  LJMP  INT0RED
對(duì)于中斷,MCU設(shè)計(jì)有總中斷控制開關(guān)(符號(hào)EA)、相應(yīng)中斷控制開關(guān)(符號(hào)EX#)、中斷的觸發(fā)方式(IT#),以及各中斷的優(yōu)先級(jí)控制(中斷優(yōu)先級(jí)寄存器IP中)。這個(gè)要根據(jù)你編程的需要,先期進(jìn)行設(shè)置,也就是中斷的初始化,這個(gè)可以在主程序中加一條ACALL  INT0INI
INT0INI:
                SETB  EX0
                CLR  IT0
                SETB  P32  中斷口。這個(gè)注意要置該端口為高電位
                SETB  EA
        RET        
中斷初始化完成了,現(xiàn)在就可以開始接收中斷并完成中斷后的任務(wù)了,下面我們編一段子程序,當(dāng)收到中斷后,在屏幕指定位置顯示一個(gè)漢字:
INT0RED:
          CLR EX0  關(guān)閉該中斷允許
                  MOV XCOM,#82H
                  LCALL  XWRI
                  MOV XDAT,#0B1H
                  LCALL  XWDAT
                  MOV  XDAT,#0B2H
                  LCALL  XWDAT
                  SETB  EX0  完成后打開該中斷允許
        RET  
  執(zhí)行后屏幕上只有一個(gè)光標(biāo),按一下遙控器,應(yīng)該顯示一個(gè)漢字。如果沒有,則把P32與地短接一下,如果有了,那就是紅外接收頭或遙控器有問題;如果不是,那么程序有問題。   
另外,這段程序中的字符顯示程序部分,規(guī)范的做法是做一個(gè)子程序,但這里只是檢驗(yàn)中斷程序,所以簡(jiǎn)單一點(diǎn)就不做了。
四、計(jì)時(shí)程序
計(jì)時(shí)程序的原理也蠻簡(jiǎn)單,你把它當(dāng)作一個(gè)跑步計(jì)時(shí)秒表就行了,秒表的使用步驟就是先歸零,然后按開始,然后按結(jié)束,然后看時(shí)間,完成。
秒表也好,MCU的計(jì)時(shí)也好,其實(shí)都是計(jì)數(shù),秒表計(jì)的是秒數(shù),MCU的講計(jì)時(shí)器計(jì)的是機(jī)器 運(yùn)行周期數(shù),知道了周期長(zhǎng),弄到了周期數(shù),則時(shí)長(zhǎng)也就可以知道了。
1.在啟動(dòng)計(jì)時(shí)功能之前,有一些東西需要先期設(shè)置,也就是初始化。
MCU的計(jì)時(shí)功能,其實(shí)只是MCU內(nèi)的一種功能模塊的功能之一,它還有定時(shí)功能、計(jì)數(shù)功能,這一功能模塊,稱之為定時(shí)/計(jì)數(shù)器,這些功能其實(shí)都是基于計(jì)數(shù)功能來(lái)的,它可以計(jì)MCU的運(yùn)行周期數(shù),也可以計(jì)端口外部輸入的高低電位變化數(shù),無(wú)非是計(jì)數(shù)來(lái)源不同。我們這里需要的是計(jì)數(shù)機(jī)器運(yùn)行周期數(shù),需先將其設(shè)置為計(jì)時(shí)功能,這個(gè)在工作方式寄存器TMOD中進(jìn)行設(shè)置。
MCU為每個(gè)定時(shí)計(jì)數(shù)器設(shè)計(jì)了兩個(gè)字節(jié)的內(nèi)部存儲(chǔ)單元,用于存儲(chǔ)計(jì)數(shù)值,高字節(jié)符號(hào)為TH#,低字節(jié)符號(hào)為TL#,這兩字節(jié)的存儲(chǔ)單元有四種不同的用法,均在工作方式寄存器TMOD中進(jìn)行設(shè)置。我們這里采用工作方式116位計(jì)數(shù)器方式。
一般MCU內(nèi)部都設(shè)計(jì)有幾個(gè)定時(shí)/計(jì)數(shù)模塊,編號(hào)從0開始。我們?cè)谠O(shè)置時(shí),用哪個(gè)就設(shè)置哪個(gè)。具體應(yīng)用時(shí)要查該芯片的手冊(cè)。一般控制0號(hào)和1號(hào)的TMOD地址為89H。我們這里用MOV  TMOD,#00000001B。
按前面說(shuō)的,秒表啟動(dòng)前,先將其歸零,用在這里,就是將THTL歸零。
啟動(dòng)與停止控制在時(shí)間控制寄存器TCON中的某一位,可位尋址,符號(hào)為TR#,TR#=1時(shí)啟動(dòng),TR#=0時(shí)停止。
兩字節(jié)用于計(jì)數(shù)時(shí),有一個(gè)問題,就是它最多只能計(jì)數(shù)65536個(gè),超出怎么辦(也就是溢出)?MCUTCON中有一位就用于反映這事,溢出時(shí)它會(huì)被自動(dòng)置1,其符號(hào)為TF#。所以,一般情況下,為穩(wěn)妥起見,我們會(huì)在初始化時(shí),將其置0。如果我們?cè)诔绦蛑幸玫竭@個(gè)TF#值,那么每一次用后都要清0,清0方式有軟件清0和硬件清0。
下面就是初始化子程序:
T0INI:
MOV  TMOD,#00000001B
MOV  TH0,#00H
MOV  TL0,#00H
CLR  TF0
RET   
2.計(jì)量紅外遙控器的第一個(gè)低電位的時(shí)長(zhǎng)
我們知道,紅外中斷的產(chǎn)生就是接收頭收到信號(hào)后將中斷端口拉低為低電平,其最前端也就是引導(dǎo)碼是9mu的低電平,我們?cè)谝唤邮盏街袛嘈盘?hào)時(shí)就啟動(dòng)計(jì)時(shí)器,當(dāng)其端口電平變?yōu)楦唠娖綍r(shí)則停止計(jì)時(shí),這個(gè)計(jì)時(shí)值是存在TH#TL#中的,然后我們直接把它顯示在屏幕上,然后計(jì)算看是不是在9毫秒左右(總會(huì)有些誤差的,原因多種)。
計(jì)時(shí)子程序如下:
JTRED1:
SETB  TR0
JB P32,$
CLR  TR1
RET
顯示子程序如下:
INT0RED:
   CLR EX0
                  SETB TR0
                  JNB P3.2,$
                          CLR TR0
                        MOV A,TH0
      ACALL X8BIT
    MOV A,TL0
    ACALL X8BIT        
                  SETB EX0
        RET
                INT0INI:
                SETB EX0
                CLR  IT0
                SETB  P3.2
                SETB EA
                RET  
以上功能,實(shí)現(xiàn)了引導(dǎo)碼9mu段的時(shí)長(zhǎng)二進(jìn)制數(shù)顯示,主程序如下:
ORG 0000H
        AJMP START
        ORG  0003H
                LJMP  INT0RED
        ORG 0100H
        START:
        ACALL XDELAY
        ACALL INT0INI
        ACALL XINIT
        ACALL T0INI
        AJMP $
運(yùn)行后,按一下遙控器,就會(huì)有16位數(shù)字顯示。
               
再往下,不需要我再寫了吧?
                                                                 

評(píng)分

參與人數(shù) 1黑幣 +50 收起 理由
admin + 50 共享資料的黑幣獎(jiǎng)勵(lì)!

查看全部評(píng)分

回復(fù)

使用道具 舉報(bào)

ID:514317 發(fā)表于 2020-1-3 08:23 | 顯示全部樓層
我的直覺告訴我     樓主是高手    使用匯編的都是高手    匯編執(zhí)行效率高   計(jì)算機(jī)底層不是匯編就是C   
當(dāng)時(shí)學(xué)黑客的時(shí)候     學(xué)匯編學(xué)的腦殼疼    用匯編寫個(gè)驅(qū)動(dòng)替代原來(lái)的底層     可以做到殺人于無(wú)形    連系統(tǒng)都檢測(cè)不到    殺毒軟件更不要說(shuō)了
回復(fù)

使用道具 舉報(bào)

ID:266429 發(fā)表于 2020-1-5 20:53 | 顯示全部樓層
lzzasd 發(fā)表于 2020-1-3 08:23
我的直覺告訴我     樓主是高手    使用匯編的都是高手    匯編執(zhí)行效率高   計(jì)算機(jī)底層不是匯編就是C   
...

謝謝看得起,我學(xué)匯編是因?yàn)閰R編語(yǔ)言的操縱感特別強(qiáng),有一種一切盡在掌握中的感覺,不象C有一種知其然不知其所以然的感覺,這種感覺讓我暫時(shí)放棄了C。
匯編還不算最底層,最底層的是機(jī)器碼,如果能把機(jī)器碼弄通了,拋開匯編,管你是多少位的CPU,那都是透明的。

評(píng)分

參與人數(shù) 1黑幣 +20 收起 理由
admin + 20 回帖助人的獎(jiǎng)勵(lì)!

查看全部評(píng)分

回復(fù)

使用道具 舉報(bào)

ID:94449 發(fā)表于 2020-2-19 18:13 | 顯示全部樓層
匯編的確看不明白,我買的開發(fā)板有個(gè)C的例程,是把紅外的用戶碼顯示在1602顯示屏上,我改了下,直接顯示在數(shù)碼管上,發(fā)現(xiàn)電視的遙控很正常,空調(diào)的同一個(gè)鍵每次按下碼都會(huì)變。
回復(fù)

使用道具 舉報(bào)

本版積分規(guī)則

小黑屋|51黑電子論壇 |51黑電子論壇6群 QQ 管理員QQ:125739409;技術(shù)交流QQ群281945664

Powered by 單片機(jī)教程網(wǎng)

快速回復(fù) 返回頂部 返回列表