⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 单片机多任务的简单实践 .txt

📁 会变语言实现的一些程序
💻 TXT
字号:
单片机多任务的简单实践 
    作者:郧县公安局 梅松 442500 于2007-10-15上传   

--------------------------------------------------------------------------------
   多任务和中断联系紧密,这里我们以mcs-51单片机作为实验对象来实现简单的多任务,这里举个例子,中断采用时钟中断任务数量为2,虽然次例子任务数量较少,但以此思路进行扩展不难实现更多任务。

   微型计算机系统的运行可以简单理解为cpu经过初始化后便成为了一个循环系统。驱动12864LCD和A/D转换都是msc-51单片机比较常见的任务,这里便是将这两个任务结合起来:把A/D转换得到的数字信号在12864LCD以波形的方式显示出来。为了实现这两个任务需要设置变量来表示每个任务的工作状态,这里选择一个8位变量的低2位来表示每个任务是否在运行中。地址为23的变量AD_OPT就是这个8位变量,它得第7位表示主循环程序是否将采集到得数据取走(数据1为是0为否)第8位表示采集到得数据是否可用(1为是0为否)。由于主循环占用cpu资源较多,所以采集采用中断方式。初始化时为了使采集得以进行先置第7位为1。具体程序代码见下:

   
   ;* 控制器:KS0107 *
   ;* LCD型号:TS12864A-2或兼容型号 *
   ;* MCU:AT89S5* ,晶体频率:11.0592MHz *
   ;* 取模方式:纵向字节倒序 *
   ;* CS1和CS2为高电平有效 *
   ;***************硬件端口定义***********
      RS   EQU P2.0   ;即DI;12864液晶信号
      RW   EQU P2.1   ;12864液晶信号
      E   EQU P2.2   ;12864液晶信号
      CS1   EQU P2.3   ;12864液晶信号
      CS2   EQU P2.4   ;12864液晶信号
      RST   EQU P2.5   ;12864液晶信号
      LVCC   EQU P2.6   ;12864背景灯地址
      AD_CLK   EQU P1.0   ;AD0832时钟
      AD_DI   EQU P1.1   ;AD0832转换数据
      AD_CS   EQU P3.4   ;AD0832片选
      COM   EQU 20H      ;12864指令数据寄存器
      DAT   EQU 21H      ;12864显示数据寄存器
      x   equ   22h   ;屏x直
      AD_OPT   EQU 23H      ;AD采集数据状态
               ;#0<-①0<-②0<-③0<-④ 0<-⑤0<-⑥0<-⑦0<-⑧B位
               ;⑦主程序已经取走数据1为是0为否
               ;⑧数据是否可用?  1为是0为否
      AD_DAT   EQU 24H      ;AD采集到数据
   ;**********************************初始入口地址 
   ORG   0000H 
      LJMP  MAIN 
   ORG   0003H   ;外部中断0 
      RETI
   ORG   000BH   ;定时器/计数器0溢出
      LJMP   TIMER
   ORG   0013H   ;外部中断1
      RETI
   ORG   001BH   ;定时器/计数器1溢出
      RETI
   ORG   0023H   ;串行囗中断 
      RETI
    
   ORG  0030H 
   ;*********************************时间中断
   TIMER:
      PUSH ACC
      PUSH PSW
      MOV ACC,R1
      PUSH   ACC

      LCALL   AD_CONV

      POP   ACC
      MOV   R1,ACC
      POP PSW
      POP ACC 
      RETI
   ;---------------------------------------------------------
   AD_CONV:               ;ADC0832初始化   INT0
      MOV    A,AD_OPT
      ANL   A,#00000010B
      JZ   AD_RET      ;A为0说明主程序尚未去走数据则直接返回



         MOV    A,#00H      ;先清0
         MOV    P0,#0FFH
        SETB   AD_CS     ;一个转换周期开始
         CLR      AD_CLK
         CLR      AD_CS      ;CS置0,片选有效
         SETB   AD_DI     ;DI置1,起始位
         SETB   AD_CLK     ;第一个脉冲
         CLR      AD_DI     ;在负跳变之前加一个DI反转操作
         CLR      AD_CLK
         SETB   AD_DI     ;DI置1,设为单通道
         SETB   AD_CLK     ;第二个脉冲
         CLR      AD_DI     ;***
         CLR      AD_CLK     ;
         CLR      AD_DI      ;DI置0,选择通道0
         SETB   AD_CLK     ;第三个脉冲
         SETB   AD_DI     ;***
         CLR      AD_CLK
         NOP
         SETB   AD_CLK    ; 第四个脉冲
         MOV      R1,#08H    ;计数器初值,读取8位数据,
   AD_READ:  CLR      AD_CLK    ;下降沿
         MOV      C,AD_DI   ;读取DO端数据
         RLC      A       ;C移入A,高位在前
         SETB   AD_CLK    ;下一个脉冲
         DJNZ   R1,AD_READ  ;没读完继续
         SETB   AD_CS
         MOV      AD_DAT,A     ;转换结果发给AD_DAT
   ;以下设置标志位
      ORL   AD_OPT,#00000001B   ;置数据可用位为1
      ANL   AD_OPT,#11111101B   ;置主取位为  0
   AD_RET:
      RET 

   ;*********************************主程序入口地址
   MAIN:
       MOV   SP,#60H
      MOV   TMOD,#01H
      MOV   TH0,#3CH 
      MOV   TL0,#0A0H
      SETB   EA         ;开总中断允许
      SETB   ET0         ;开定时/计数器0允许
      SETB   TR0         ;定时/计数器0开始运行

      ORL   AD_OPT,#00000010B   ;置主取位为1

       CLR RST
       NOP
       NOP
       SETB RST
       CLR  LVCC  ;打开背景灯
       LCALL LCD_INIT
       LCALL CLEAR_ALL      ;清整个屏幕
   ;**********************************************以上是软件初始化
   HEARE:
      MOV   R0,#000H
   main1:   MOV   x,R0
      LCALL   CHECK_USE
   mov   a,x
   anl   a,#01000000B
   jnz   main_r
      LCALL LEFT
   jmp   main2
   main_r:   LCALL RIGHT
      
   main2:   ORL   AD_OPT,#00000010B   ;置主取位为1
      ANL   AD_OPT,#11111110B   ;置数据可用位为  0
      INC   R0
      CJNE  R0, #127,main1

   LJMP HEARE
   ;********************************
   LCD_INIT:
       MOV COM,#3FH;显示开
       LCALL LEFT_COMM  ;左半屏写指令子程序
       LCALL RIGHT_COMM  ;右半屏写指令子程序
   ;---------------------------------------------------------
       MOV COM,#0C0H;第一行 
       LCALL LEFT_COMM  ;左半屏写指令子程序
       LCALL RIGHT_COMM  ;右半屏写指令子程序
   ;----------------------------------------------------------           MOV COM,#0B8H;第一页 
       LCALL LEFT_COMM  ;左半屏写指令子程序
       LCALL RIGHT_COMM  ;右半屏写指令子程序
   ;----------------------------------------------------------
       MOV COM,#40H;第一列
       LCALL LEFT_COMM  ;左半屏写指令子程序
       LCALL RIGHT_COMM  ;右半屏写指令子程序
      ret
   ;****************************************** ****以下是子程序
   CHECK_USE:;判断数据是否可用不可用在子程序中循环
      PUSH   ACC
   C_U_TM:   MOV    A,AD_OPT
      ANL   A,#00000001B
      JZ   C_U_TM      ;A为0说明数据可用位为0,ad数据不可用,循环测试直到数据可用
      POP   ACC
       RET
   CHECK_BUSY:  MOV  P0,#0FFH  ;检测12864液晶屏状态  空闲返回,否则在此子程序中循环
       SETB  E
       MOV  A,P0
       CLR  E
       JB  ACC.7,CHECK_BUSY
       RET
   SEND_COMMD:  CLR  RS    ;发送命令到p0口
       SETB  RW
       LCALL  CHECK_BUSY
       CLR  RW
       MOV  P0,COM
       SETB  E
       NOP
       CLR  E
       RET
   SEND_DATE:  CLR  RS    ;发送数据到p0口
       SETB  RW
       LCALL  CHECK_BUSY
       SETB  RS
       CLR  RW
       MOV  P0,DAT
       SETB  E
       NOP
       CLR  E
       RET
   LEFT_COMM:  SETB CS1    ;左半屏写指令子程序
       LCALL SEND_COMMD
       CLR CS1
       RET 
   LEFT_DATE:  SETB CS1    ;左半屏写数据子程序 
       LCALL SEND_DATE 
       CLR CS1 
       RET
   RIGHT_COMM:  SETB CS2    ;右半屏写指令子程序
       LCALL SEND_COMMD
       CLR CS2
       RET 
   RIGHT_DATE:  SETB CS2    ;右半屏写数据子程序 
       LCALL SEND_DATE 
       CLR CS2 
       RET

   LEFT: 
      MOV   A,R0   ;主循环用到了r0
      PUSH   ACC


      MOV   R0,#0B8H      
   L_CLR_QUEUE:  MOV   COM,R0   
       LCALL  LEFT_COMM      
      mov   a,x
      anl   a,#00111111B
      add   a,#01000000B
      MOV   COM,A
       LCALL  LEFT_COMM      
   MOV   DAT,#00H    
       LCALL  LEFT_DATE      
       INC   R0    
       CJNE  R0, #0C0H,L_CLR_QUEUE   
      MOV A,AD_DAT
      PUSH   ACC
      ANL   A,#11100000B
      SWAP   A
      RR   A
      MOV   R0,#008H
      XCH   A,R0
      SETB   C
      SUBB   A,R0
      MOV   R0,#0B8H
      ADD   A,R0
      MOV   COM,A
       LCALL LEFT_COMM    ;左半屏写指令子程序 
      mov   a,x
      anl   a,#00111111B
      add   a,#01000000B
      MOV   COM,A
       LCALL LEFT_COMM   ;左半屏写指令子程序 
      POP   ACC
      ANL   A,#00011100b
      RR   A
      RR   A
      DEC   A
      MOV    R0,A
      MOV   A,#040H
   L_LOOP:   RR   A
      DJNZ   R0,L_LOOP
      MOV   DAT,A
       LCALL LEFT_DATE    ;左半屏写数据子程序
      POP   ACC
      MOV    R0,A
      RET

   RIGHT:   MOV   A,R0
      PUSH   ACC

      MOV   R0,#0B8H      
   R_CLR_QUEUE:  MOV   COM,R0   
       LCALL  RIGHT_COMM      
      mov   a,x
      anl   a,#00111111B
      add   a,#01000000B
      MOV   COM,A
       LCALL  RIGHT_COMM      
   MOV   DAT,#00H    
       LCALL  RIGHT_DATE      
       INC   R0    
       CJNE  R0, #0C0H,R_CLR_QUEUE   



      MOV A,AD_DAT
      PUSH   ACC
      ANL   A,#11100000B
      SWAP   A
      RR   A
      MOV   R0,#008H
      XCH   A,R0
      SETB   C
      SUBB   A,R0
      MOV   R0,#0B8H
      ADD   A,R0
      MOV   COM,A
       LCALL RIGHT_COMM    ;左半屏写指令子程序 
      mov   a,x
      anl   a,#00111111B
      add   a,#01000000B
      MOV   COM,A
       LCALL RIGHT_COMM   ;左半屏写指令子程序 
      POP   ACC
      ANL   A,#00011100b
      RR   A
      RR   A
      DEC   A
      MOV    R0,A
      MOV   A,#040H
   R_LOOP:   RR   A
      DJNZ   R0,R_LOOP
      MOV   DAT,A
       LCALL RIGHT_DATE    ;左半屏写数据子程序
      POP   ACC
      MOV    R0,A
      RET

   CLEAR_ALL:   MOV   R1,#0B8H      ;清显示屏   
   CLEAR_TMP1:  MOV   COM,R1   
       LCALL  LEFT_COMM      
       LCALL  RIGHT_COMM       
        MOV   COM,#40H    
       LCALL  LEFT_COMM      
       LCALL  RIGHT_COMM
       MOV   R0, #64 
   CLEAR_TMP2: MOV   DAT,#00H    
       LCALL  LEFT_DATE      
       LCALL  RIGHT_DATE       
       DJNZ  R0,CLEAR_TMP2
       INC   R1    
       CJNE  R1, #0C0H,CLEAR_TMP1   
       RET
   END

   由于程序未经过优化,所以显得有些冗余,您若有比较好的想法意见建议请和我联系:e-mail:332779423@qq.com 

   2007年9月29日


--------------------------------------------------------------------------------
 欢迎访问AoGo汇编小站:http://www.aogosoft.com 下一篇>>>  

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -