找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 1765|回复: 3
打印 上一主题 下一主题
收起左侧

MCU编程实践之红外中断定时12864逐步讲解一锅烩

[复制链接]
跳转到指定楼层
楼主
ID:266429 发表于 2020-1-2 21:18 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
这个其实是红外遥控编程过程实验,思路是这样的:
  • 红外接收管采用中断口接收信号;
  • 在中断子程序中,在高低电平的变化时,用计时器来计时其高、低电平维持的时长;
  • 将时长值直接用二进制数显示在12864屏上;
  • us为单位,手工计算各显示数值的时长值(这个可以不做);
  • 根据红外遥控NEC标准,分析该遥控器的引导码及比特码的高低电平时长组成,以此获得引导码和比特码的高低电平时长特征值,
  • 依据得到的引导码和比特码的高低电平时长特征值,再编制程序获得该遥控器的用户码值、各键的键值。
  • 依据得到的用户码值、各键的键值,接下来就可以做遥控控制操作编程了。
    这一套操作下来,你就拥有了获得各种红外遥控器用户码和键值的工具了,然后,你可以给家里的所有红外遥控器做一个一桶姜山的专用遥控器了,然后你可以在网上订印刷板、外壳等的,高档一点的,全屏触摸操作带学习。
    下面一步一步来:

一、12864
该屏下有字符显示和图形显示两种模式,我们选择字符模式。
字符模式下,其最多可显示64个半宽字符,或32个汉字,可混编,分为四排。输入位置为一维座标确定,左上角的座标值为80H
1.初始化
编程时,首先设置其为字符模式,命令代码为10100B(我们这里直接用二进制,方便自己看说明书及更改功能设置)。
字符输入时,我们一般都能看到一个光标,以在屏幕上指示正在输入的位置,这个光标可以开可以关,用命令来设置;输入时我们一般选择光标向右移动、字符从左向右顺序输入(当然,你也可以倒着来,或新输入的字符总是固定在这个位置),相应命令为110B
然后将字符地址内存DDRAM全部清空,将DDRAM的地址计数器值归位。该命令为1B
字符输入后,你可以控制其显示或不显示,光标也一样,所以,我们还要设置其打开,相应命令为1110B。这个命令中,最后一位为0,表示游标位置反白关。
还有一个光标显示移位控制命令,先用10100B吧。
这一步算是完成了,执行后,你应该能看到光标。如果没有,那你的程序就有问题,仔细检查,反正没几行,我遇到的问题,基本就是延时不够,以及该延时的地方没加延时。
下面给出这部分的汇编程序,当然,你也可以用C编。并行输入,P0口为数据口:
        XRS  EQU  0B5H;P35     编程器不认P35,只好直接输入P35的地址值了,下同
    XRW  EQU  0B6H;P36
    XEN  EQU  0B7H;P37
    XPSB EQU            这两个,我的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  这个延时有点长,短了我的这个MCU不认帐,没法
   D1: MOV 31h,#25
   D2: DJNZ 31h,D2
   DJNZ 30h,D1
RET
END
2.输入字符
这个简单,输入座标再输入字符编码,搞定。
至此,屏显编程工作完成。
3.直接以二进制显示一个存储单元中的数值
比如我们要显示10010110B这个值,我们把它先输入到A寄存器中,将这个值一位一位地进行处理并显示在屏幕上。
对于初学者,最好是先将其中任一位的显示程序做通,然后再做这八位输入的程序,这个功能的子程序如下:
XBIT:
        MOV  A,#10010110B
        JB  ACC.0,LOOP1
        LOOP0:MOV XDAT,#30H
        ACALL  XWDAT
        RET
        LOOP1:MOV XDAT,#31H
        ACALL  XWDAT
RET
上面程序中的BACC.0就是最末一位,你可以换成其它位试试能否正确显示。
这个做通了,下面做八位全部显示的。
我们采用移位并循环法,从高位到低位逐位处理,子程序如下:
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
三、中断程序
其实中断的原理蛮简单的,设定相应中断开之后,一旦有中断信号被接收到,即中断口的电平被拉低,则程序就强行发生跳转,这个跳转是程序存储器绝对地址的跳转,不同编号的中断有不同的跳转地址(中断向量),比如INT0,其跳转地址为0003H,即程序跳转到地址为0003H处开始执行。所以,在主程序中,应在0003H地址处写入中断子程序,但要注意因另一个中断的跳转地址为000BH,之间放不了几行程序,所以这里一般是写个跳转指令,跳转到一个专门的子程序来完成中断后的任务:
  ORG  0003H
  LJMP  INT0RED
对于中断,MCU设计有总中断控制开关(符号EA)、相应中断控制开关(符号EX#)、中断的触发方式(IT#),以及各中断的优先级控制(中断优先级寄存器IP中)。这个要根据你编程的需要,先期进行设置,也就是中断的初始化,这个可以在主程序中加一条ACALL  INT0INI
INT0INI:
                SETB  EX0
                CLR  IT0
                SETB  P32  中断口。这个注意要置该端口为高电位
                SETB  EA
        RET        
中断初始化完成了,现在就可以开始接收中断并完成中断后的任务了,下面我们编一段子程序,当收到中断后,在屏幕指定位置显示一个汉字:
INT0RED:
          CLR EX0  关闭该中断允许
                  MOV XCOM,#82H
                  LCALL  XWRI
                  MOV XDAT,#0B1H
                  LCALL  XWDAT
                  MOV  XDAT,#0B2H
                  LCALL  XWDAT
                  SETB  EX0  完成后打开该中断允许
        RET  
  执行后屏幕上只有一个光标,按一下遥控器,应该显示一个汉字。如果没有,则把P32与地短接一下,如果有了,那就是红外接收头或遥控器有问题;如果不是,那么程序有问题。   
另外,这段程序中的字符显示程序部分,规范的做法是做一个子程序,但这里只是检验中断程序,所以简单一点就不做了。
四、计时程序
计时程序的原理也蛮简单,你把它当作一个跑步计时秒表就行了,秒表的使用步骤就是先归零,然后按开始,然后按结束,然后看时间,完成。
秒表也好,MCU的计时也好,其实都是计数,秒表计的是秒数,MCU的讲计时器计的是机器 运行周期数,知道了周期长,弄到了周期数,则时长也就可以知道了。
1.在启动计时功能之前,有一些东西需要先期设置,也就是初始化。
MCU的计时功能,其实只是MCU内的一种功能模块的功能之一,它还有定时功能、计数功能,这一功能模块,称之为定时/计数器,这些功能其实都是基于计数功能来的,它可以计MCU的运行周期数,也可以计端口外部输入的高低电位变化数,无非是计数来源不同。我们这里需要的是计数机器运行周期数,需先将其设置为计时功能,这个在工作方式寄存器TMOD中进行设置。
MCU为每个定时计数器设计了两个字节的内部存储单元,用于存储计数值,高字节符号为TH#,低字节符号为TL#,这两字节的存储单元有四种不同的用法,均在工作方式寄存器TMOD中进行设置。我们这里采用工作方式116位计数器方式。
一般MCU内部都设计有几个定时/计数模块,编号从0开始。我们在设置时,用哪个就设置哪个。具体应用时要查该芯片的手册。一般控制0号和1号的TMOD地址为89H。我们这里用MOV  TMOD,#00000001B
按前面说的,秒表启动前,先将其归零,用在这里,就是将THTL归零。
启动与停止控制在时间控制寄存器TCON中的某一位,可位寻址,符号为TR#TR#=1时启动,TR#=0时停止。
两字节用于计数时,有一个问题,就是它最多只能计数65536个,超出怎么办(也就是溢出)?MCUTCON中有一位就用于反映这事,溢出时它会被自动置1,其符号为TF#。所以,一般情况下,为稳妥起见,我们会在初始化时,将其置0。如果我们在程序中要用到这个TF#值,那么每一次用后都要清0,清0方式有软件清0和硬件清0
下面就是初始化子程序:
T0INI:
MOV  TMOD,#00000001B
MOV  TH0,#00H
MOV  TL0,#00H
CLR  TF0
RET   
2.计量红外遥控器的第一个低电位的时长
我们知道,红外中断的产生就是接收头收到信号后将中断端口拉低为低电平,其最前端也就是引导码是9mu的低电平,我们在一接收到中断信号时就启动计时器,当其端口电平变为高电平时则停止计时,这个计时值是存在TH#TL#中的,然后我们直接把它显示在屏幕上,然后计算看是不是在9毫秒左右(总会有些误差的,原因多种)。
计时子程序如下:
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  
以上功能,实现了引导码9mu段的时长二进制数显示,主程序如下:
ORG 0000H
        AJMP START
        ORG  0003H
                LJMP  INT0RED
        ORG 0100H
        START:
        ACALL XDELAY
        ACALL INT0INI
        ACALL XINIT
        ACALL T0INI
        AJMP $
运行后,按一下遥控器,就会有16位数字显示。
               
再往下,不需要我再写了吧?
                                                                 

评分

参与人数 1黑币 +50 收起 理由
admin + 50 共享资料的黑币奖励!

查看全部评分

分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏 分享淘帖 顶 踩
回复

使用道具 举报

沙发
ID:514317 发表于 2020-1-3 08:23 | 只看该作者
我的直觉告诉我     楼主是高手    使用汇编的都是高手    汇编执行效率高   计算机底层不是汇编就是C   
当时学黑客的时候     学汇编学的脑壳疼    用汇编写个驱动替代原来的底层     可以做到杀人于无形    连系统都检测不到    杀毒软件更不要说了
回复

使用道具 举报

板凳
ID:266429 发表于 2020-1-5 20:53 | 只看该作者
lzzasd 发表于 2020-1-3 08:23
我的直觉告诉我     楼主是高手    使用汇编的都是高手    汇编执行效率高   计算机底层不是汇编就是C   
...

谢谢看得起,我学汇编是因为汇编语言的操纵感特别强,有一种一切尽在掌握中的感觉,不象C有一种知其然不知其所以然的感觉,这种感觉让我暂时放弃了C。
汇编还不算最底层,最底层的是机器码,如果能把机器码弄通了,抛开汇编,管你是多少位的CPU,那都是透明的。

评分

参与人数 1黑币 +20 收起 理由
admin + 20 回帖助人的奖励!

查看全部评分

回复

使用道具 举报

地板
ID:94449 发表于 2020-2-19 18:13 | 只看该作者
汇编的确看不明白,我买的开发板有个C的例程,是把红外的用户码显示在1602显示屏上,我改了下,直接显示在数码管上,发现电视的遥控很正常,空调的同一个键每次按下码都会变。
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表