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

📄 gscm6.asm.asm

📁 《单片机应用系统设计与产品开发》配套源码
💻 ASM
📖 第 1 页 / 共 3 页
字号:
                        mov       r5,#00h; 清BCD码高字节寄存
                        mov       dptr,#ai_task_bin_bcd_lab
                        mov       r6,#00h; 复位ai_task_bin_bcd_lab表指针
                        mov       r1,AiTaskWord
                        mov       a,@r1
                        mov       r3,a; r3—移位寄存器
ai_task_bin_bcd_loop:   mov       a,r3
                        rrc       a
                        mov       r3,a
                        jnc       ai_task_bit_is0; 该位为0,转
                        mov       a,r6
                        movc      a,@a+dptr; 取权低位
                        add       a,r4; BCD码低位和
                        da        a
                        mov       r4,a
                        inc       r6; ai_task_bin_bcd_lab表指针+1
                        mov       a,r6
                        movc      a,@a+dptr; 取权高位
                        addc      a,r5; BCD码高位和
                        da        a
                        mov       r5,a
                        inc       r6; ai_task_bin_bcd_lab表指针+1
                        sjmp      ai_task_byte_ok_ma
ai_task_bit_is0:        inc       r6; ai_task_bin_bcd_lab表指针+2
                        inc       r6
ai_task_byte_ok_ma:     cjne      r6,#16d,ai_task_this_byte; 字节未完,转
                        inc       r1
                        mov       a,@r1
                        mov       r3,a; 高字节bin码进移位寄存器
ai_task_this_byte:      cjne      r6,#24d,ai_task_bin_bcd_loop; 12位未完,转
;bin—BCD转换结束
                        mov       a,#SendDataBuffer02-SendDataBuffer32+02h
                        add       a,AiTaskWord
                        mov       r0,a; 指向SendDataBuffer02中模拟量值
                        clr       ea; 关中断,同步更新
                        mov       a,r4
                        mov       @r0,a; 更新南京上报模拟量数据
                        inc       r0
                        mov       a,r5
                        mov       @r0,a
                        setb      ea
                        mov       AiTaskWord,#00h; 清除任务标记
                        ljmp      do_task_verify
;二进制权值表
;每行4个压缩BCD码依次为十_个_千_百
ai_task_bin_bcd_lab:    db        01h,00h
                        db        02h,00h
                        db        04h,00h
                        db        08h,00h
                        db        16h,00h
                        db        32h,00h
                        db        64h,00h
                        db        28h,01h
                        db        56h,02h
                        db        12h,05h
                        db        24h,10h
                        db        48h,20h
;数字量输出反馈的格式转换部分作业
do_task_verify:         mov       a,DoTaskWord
                        jb        acc.7,do_task; 转,数字量部分作业
                        ljmp      go_to_sleep
do_task:                mov       r1,#SendDataBuffer32+03h
                        mov       r0,#SendDataBuffer02+03h
do_task_move_loop:      mov       a,@r1
                        mov       @r0,a; 更新南京上报DI数据
                        inc       r1
                        inc       r1
                        inc       r0
                        inc       r0
                        cjne      r1,#SendDataBuffer32+09h,do_task_move_loop
                        mov       TaskBitReg,#00h
                        mov       a,@r1; 取数字量输出反馈值
                        jnb       acc.0,do_task_off0
                        setb      TaskBitReg.0
do_task_off0:           jnb       acc.1,do_task_off1
                        setb      TaskBitReg.2
do_task_off1:           jnb       acc.2,do_task_off2
                        setb      TaskBitReg.4
do_task_off2:           jnb       acc.3,do_task_off3
                        setb      TaskBitReg.6
do_task_off3:           mov       r0,#SendDataBuffer02+09h
                        mov       @r0,TaskBitReg; 更新南京上报DO0数据
                        mov       TaskBitReg,#00h
                        mov       a,@r1
                        jnb       acc.4,do_task_off4
                        setb      TaskBitReg.0
do_task_off4:           jnb       acc.5,do_task_off5
                        setb      TaskBitReg.2
do_task_off5:           jnb       acc.6,do_task_off6
                        setb      TaskBitReg.4
do_task_off6:           jnb       acc.7,do_task_off7
                        setb      TaskBitReg.6
do_task_off7:           mov       r0,#SendDataBuffer02+0bh
                        mov       @r0,TaskBitReg; 更新南京上报DO1数据
                        mov       DoTaskWord,#00h; 清除任务标记
;时时更新串口通信地址
                        mov       dptr,#DS12887
                        movc      a,@a+dptr; a不必清0
                        cpl       a
                        mov       UartNoReg,a
;
go_to_sleep:            orl       pcon,#01h; cpu进入空闲方式
                        nop
                        ljmp      main_loop
;陷阱
                        nop
                        nop
                        call      pc_out_error
;主程序结束
;==============================================================================


;==============================================================================
;定时器0中断程序开始
;读取数字量输入,数字量输出反馈;关烟感复位;控制部分指示灯;外部中断1正常运行标记
;本中断程序使用工作寄存组2
;r1—数据指针(局部自动)
timer0_int:             clr       ea; 关中断
                        push      acc
                        push      psw
                        push      dpl
                        push      dph
                        clr       p3.3; 喂狗线置0
                        mov       th0,#TH0_NUM; 定时器0置初值,10ms
                        mov       tl0,#TL0_NUM
                        setb      rs1; 使用工作寄存组2
                        clr       rs0
;数字量输入
                        mov       DoTaskWord,#80h
                        mov       dptr,#DI0-1
                        mov       r1,#SendDataBuffer32+01h
                                  ; 发送数据缓冲区32中DIU0板识别字前一地址
d_in_loop:              inc       dptr
                        inc       r1; 跳过"板识别字"信息
                        inc       r1; 指向下一个
                        movx      a,@dptr
                        cpl       a; 数字量输入反相
                        mov       @r1,a
                        mov       a,dpl
                        cjne      a,#02h,d_in_loop
                        inc       dptr; 指向DO245
                        inc       r1; 跳过DOU"板识别字"信息
                        inc       r1
                        movx      a,@dptr
                        mov       @r1,a
;关烟感复位
                        djnz      FogResetCounter,cpu_led_ctrl
                        orl       Do574Reg,#80h
                        mov       a,Do574Reg
                        mov       dptr,#DO574
                        movx      @dptr,a; 关烟感复位
                        mov       dptr,#DS12887+10h
                        movx      @dptr,a; 保存输出状态
;控制各指示灯
cpu_led_ctrl:           djnz      CpuFlashCounter,uart_led_ctrl
                        mov       CpuFlashCounter,#CPU_FLASH_COUNTER_NUM
;插入喂狗控制(500ms执行一次)
                        jnb       GoGoodFlag,starve_dog
                        clr       GoGoodFlag; 信号收到
                        jnb       Timer2GoFlag,starve_dog; 中断2不运行,转
                        jb        StarveDogFlag,starve_dog
                        clr       Timer2GoFlag
                        setb      p3.3; 喂狗
starve_dog:             cpl       p1.3; cpu运行指示灯闪亮
uart_led_ctrl:          djnz      UartOffCounter,timer0_int_over
                        clr       OldUartGoFlag
                        setb      p1.2
;
timer0_int_over:        pop       dph
                        pop       dpl
                        pop       psw
                        pop       acc
                        setb      ea
                        reti
;定时器0中断程序结束
;==============================================================================


;==============================================================================
;错误处理程序开始
;程序指针跑飞处理
pc_out_error:           pop       a
                        pop       a
                        ljmp      main
;执行命令错误处理
doen_jmp_error:         pop       a
                        pop       a
                        ljmp      main
;定时器0跳转错误处理
timer0_int_error:       pop       a
                        pop       a
                        ljmp      main
;错误处理程序结束
;==============================================================================


;==============================================================================
;串口中断程序开始
;接收,解释数据包;回应;执行部分"命令"动作
;本中断程序使用工作寄存组1
;r7—接收/发送控制字                     ;r7—发送/接收控制字
;r6—接收数据(仅指"数据包")长度寄存器    ;r6—接收数据(仅指"数据包")长度寄存器
;r5—已接收数据长度                      ;r5—发送长度寄存器
;r4—已接收部分校验和                    ;r4—已发送部分校验和
;r1—接收数据指针                        ;r3—执行动作控制字
;r0—临时数据指针                        ;r1—当前发送数据指针
;
uart_int:               clr       ea; 关中断
                        push      acc
                        push      psw
                        push      dpl
                        push      dph
                        clr       rs1; 使用工作寄存组1
                        setb      rs0
;串口指示灯控制
                        mov       UartOffCounter,#UART_OFF_COUNTER_NUM
                        jb        OldUartGoFlag,uart_int_no_once
                        setb      OldUartGoFlag
                        clr       p1.2
                        mov       UartFlashCounter,#50h
uart_int_no_once:       djnz      UartFlashCounter,led_no_ctrl
                        mov       UartFlashCounter,#UART_FLASH_COUNTER_NUM
                        cpl       p1.2
led_no_ctrl:            jbc       ri,rece; 接收中断则转
                        clr       ti
                        ljmp      send; 转发送
;接收程序
rece:                   mov       a,r7; r7=Rece_Ctrl
                        rl        a
                        add       a,r7; ×3
                        mov       dptr,#rece_ctrl_lab;
                        jmp       @a+dptr; 转接收功能处理
;陷阱
                        nop
                        nop
                        lcall     pc_out_error
;接收控制散转表
rece_ctrl_lab:          ljmp      rece_00
                        ljmp      rece_01
                        ljmp      rece_02
                        ljmp      rece_03
                        ljmp      rece_04
                        ljmp      rece_05
;
rece_00:                mov       a,sbuf
                        cjne      a,#55h,rece_no_head
                        mov       r7,#01h; 包头,写接收控制字01h
rece_no_head:           ljmp      uart_int_over
;
rece_01:                mov       a,sbuf
                        cjne      a,UartNoReg,address_no; 地址不符合,转
                        mov       r7,#02h; 地址符合,写接收控制字02h,准备接收"长度"
                        ljmp      uart_int_over
address_no:             mov       r7,#00h; 地址不符合,写接收控制字,复位接收"包头"
                        ljmp      uart_int_over
;
rece_02:                mov       a,sbuf
                        anl       a,#07h; 限制"数据长度"<8
                        jnz       rece_02_good
                        mov       r7,#00h; "数据长度"=0,复位接收控制
                        ljmp      uart_int_over
rece_02_good:           mov       r6,a; 存"长度"
                        mov       r5,#00h; 已接收数据长度复位00h
                        mov       r4,#00h; 初始已接收部分校验和
                        mov       r1,#ReceDataBuffer; 初始数据接收指针
                        mov       r7,#03h; 写接收控制字,准备接收"数据包"
                        ljmp      uart_int_over
;
rece_03:                mov       a,sbuf
                        mov       @r1,a; 存接收数据
                        inc       r1; 使指向下一单元
                        add       a,r4; 接收部分校验和累加
                        mov       r4,a; 存校验和
                        inc       r5; 已接收数据长度+1
                        mov       a,r5
                        mov       Reg0,r6
                        cjne      a,Reg0,rece_data_no_over
                        mov       r7,#04h; 写接收控制字,准备接收"校验和"
rece_data_no_over:      ljmp      uart_int_over
;
rece_04:                mov       a,sbuf
                        mov       Reg0,r4
                        cjne      a,Reg0,ReceCheckSum_error; 比较校验和.错,转
                        mov       r7,#05h; 写接收控制字,准备接收"包尾"
                        ljmp      uart_int_over
ReceCheckSum_error:     mov       r7,#00h; 写接收控制字,复位接收"包头"
                        ljmp      uart_int_over
;
rece_05:                mov       a,sbuf
                        cjne      a,#0aah,rece_over_error
                                  ;非正常结束包尾,转
                        clr       ren; 回应中禁止接收
                        setb      p1.5; 485发送允许
                        mov       sbuf,#55h; 发送 "包头(55h)"
                        mov       r7,#01h; 写发送控制字,准备发送"地址"
                        ljmp      uart_int_over
rece_over_error:        mov       r7,#00h; 复位接收控制字,准备接收"包头"
                        ljmp      uart_int_over
;------------------------------------------------------------------------------
;发送程序
send:                   mov       a,r7
                        rl        a
                        add       a,r7; ×3
                        mov       dptr,#send_ctrl_Lab;

⌨️ 快捷键说明

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