汇编写的无线解码程序,求教下各位朋友

2020-02-08 12:11发布

逻辑上找不出什么问题,也没陷如什么死循环,但是读到的数据总是0XFF,开始怀疑是定时器的设置有问题,导致延时长度不够,中断总是在数据线高电平期间产生,但是用示波器看了波形以后发现,中断延时的设置应该是正确的,用设置断点的方式,发现的确是延时中断产生后的数据线总是高电平,实在想不出哪里出了问题,求教下各位朋友,先谢谢了。
编码器件是HX2262
接收器件EM78P163N+315M超再生接收模块,接收模块收到的信号用示波器确认过,没有问题。
程序如下:
INCLUDE "EM78P163N.INC"
    WILE_CHECK_S_NUM == R1A
    WILE_READ_NUM    == R1B
    WILE_DATA        == R1C
    WILE_READ_NUM3   == R1D
    WILE_HEAD        == 0X13
    WILE_BITDA       == PORT6.2
    TCC0             == 56
    TCC_INT_SIGN     == R3F.1
    CLOSE_TCC MACRO;关闭TCC溢出中断
        IOR IOCF
        AND A,@0XFE
        IOW IOCF
    ENDM
    OPEN_TCC MACRO;开启TCC溢出中断
        IOR IOCF
        OR A,@1
        IOW IOCF
    ENDM
    MOV MACRO REG1,REG2
        MOV A,REG2
        MOV REG1,A
    ENDM
    MOV MACRO REG,@LITERAL
        MOV A,@LITERAL
        MOV REG,A
    ENDM
    ORG 0
    ADD A,@0XFF
    ADD A,@0XFF
    ADD A,@0XFF
    JMP MAIN
    ORG 0X09
    BS TCC_INT_SIGN
    CLR RF
    RETI
    ORG 0X10
MAIN:
    DISI;关闭全局中断
    ;引脚初始化
    MOV A,@0;P5置为输出1
    IOW P5CR
    MOV A,@0XFF
    MOV PORT5,A
    MOV A,@0X44;P6.2,P6.6置为输入,其他P6脚置为输出1,P6.0,P6.1上拉使能.
    IOW P6CR
    MOV A,@0XFF
    MOV PORT6,A
    MOV A,@0XF4
    IOW PHCR
    ;寄存器初始化
    MOV A,@0X0A;设置定时器为1:8预分频
    CONTW
    ENI;使能全局中断
    CALL WILE_CHECK_S
    CALL WILE_READ
    BC PORT5.0
    /*MOV A,@0XFF
    SUB R13,A
    JBC Z
    BC PORT6.4
    SUB R14,A
    JBC Z
    BC PORT6.5
    SUB R15,A
    JBC Z
    BC PORT6.6*/
    MOV A,@0
    SUB A,R1C
    JBC Z
    BC PORT5.1
    MOV A,@0XFF
    SUB A,R1C
    JBC Z
    BC PORT5.2
    MOV A,@0B01010101
    SUB A,R1C
    JBC Z
    BC PORT5.3
LOOP:
    JMP LOOP     
;**无线解码子程序**
;同步位检测
WILE_CHECK_S:
    ;CALL WILE_CHECK0
    ;JBC TCC_INT_SIGN
    ;JMP WILE_CHECK_S
    MOV A,@10
    MOV WILE_CHECK_S_NUM,A
    BC TCC_INT_SIGN
    MOV TCC,@0;定时器初值置0
    CLR RF;清除中断标志位
    OPEN_TCC;开启TCC溢出中断
WILE_CHECK_S1:
    JBC WILE_BITDA
    JMP WILE_RECHECK_S;数据线电平为高,返回重检测同步位.
    JBC TCC_INT_SIGN
    JMP WILE_CHECK_S0;TCC_INT_SIGN=1
    JMP WILE_CHECK_S1;TCC_INT_SIGN=0,返回返回判断数据线电平.
WILE_CHECK_S0:
    BC TCC_INT_SIGN;清0 TCC_INT_SIGN
    DJZ WILE_CHECK_S_NUM;计数值减为0则跳至程序结尾准备结束
    JMP WILE_CHECK_S1;计数值不为0则返回判断数据线电平.
    JMP WILE_CHECK_S_END
WILE_CHECK_S_END:
    CLOSE_TCC
    RET
WILE_RECHECK_S:
    MOV TCC,@0
    BC TCC_INT_SIGN
    MOV WILE_CHECK_S_NUM,@10
    JMP WILE_CHECK_S1
;读取1字节
WILE_READ:
    MOV WILE_READ_NUM,@8
WILE_READ0:
    ;高电平长短检测:短脉冲-TCC_INT_SIGN=0,长脉冲-TCC_INT_SIGN=1.
WILE_CHECK0:;等待数据线被置为低电平
    BC TCC_INT_SIGN;清0 TCC溢出中断产生标志
    JBC WILE_BITDA
    JMP WILE_CHECK0
WILE_CHECK1:;等待数据线上升沿
    JBS WILE_BITDA
    JMP WILE_CHECK1
    MOV TCC,@TCC0;定时器初值置为50
    CLR RF;清除中断标志位
    OPEN_TCC;开启TCC溢出中断
WILE_CHECK2:;等待TCC溢出中断
    JBS TCC_INT_SIGN
    JMP WILE_CHECK2
    CLOSE_TCC;关闭TCC溢出中断   
    JBC WILE_BITDA
    JMP WITE_SET_C
    BC C
    BC PORT6.6
    JMP WILE_RD1BIT
WITE_SET_C:
    BS C
    BC PORT6.7
WILE_RD1BIT:
    RLC WILE_DATA
    DJZ WILE_READ_NUM
    JMP WILE_READ0
    MOV A,WILE_DATA   
    RET
;连续读取3字节
WILE_READ3:
    MOV WILE_READ_NUM3,@3
    MOV R4,@WILE_HEAD
    CALL WILE_CHECK_S
WILE_READ30:
    CALL WILE_READ
    MOV R0,A
    DJZ WILE_READ_NUM3
    JMP WILE_READ3_GO
    JMP WILE_READ3_END
WILE_READ3_GO:
    INC R4
    JMP WILE_READ30
WILE_READ3_END:
    RET
友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
该问题目前已经被作者或者管理员关闭, 无法添加新回复
6条回答
HYLG
1楼-- · 2020-02-08 13:17
你的汇编俺看不懂也懒得看,呵呵,贴个我用MEGA48汇编的程序.
MEGA48解码OK后将地址和数据字节从串口发送给PC通过串口调试观察.

#include <m48def.inc> ;单片机内部各种外设设备的相关寄存器定义

.def        rfadlo                =r10        ;
.def        rfadhi                =r11        ;
.def        rfda                =r12        ;
.def        lowcnt                =r20        ;低电平计数器
.def        highcnt                =r21        ;高电平计数器
.def        cycnt                =r22        ;循环计数器
.def        bitcnt                =r23        ;位计数器

.equ        rfflag                =gpior0
;GPIOR0
.equ        pinsta                =2        ;

.equ        rfpin                =pind        ;
.equ        rfin                =2        ;
.equ        rfout                =1        ;

.dseg

;rfadlo:                .byte        1       
;rfadhi:                .byte        1
;rfda:                        .byte        1

.CSEG ;

.ORG 0X0000 ;
        RJMP RESET ;

.ORG $01A

reset:
        LDI         R16,                HIGH(RAMEND) ;
        OUT         SPH,                R16 ;
        LDI         R16,                LOW(RAMEND) ;
        OUT         SPL,                R16 ;

        ;ram_init
        ldi        xh,                high(SRAM_START)
        ldi        xl,                low(SRAM_START)
       
        clr        r16
        ldi        r24,                low(512)
        ldi        r25,                high(512)
raminit10:
        inc        r16
        st        x+,                r16
       
        sbiw        r25:r24,        1
       
        brne        raminit10
       
        clr        r6
        clr        r7
        clr        r8
        clr        lowcnt
        clr        highcnt
        clr        bitcnt
        clr        cycnt
        clr        r16
        out        gpior0,                r16

port_init:        ;端口初始化
        ldi        r16,                0b11111011
        out        ddrd,                r16
       
usart_init:
        ldi         r16,                6        ;定义波特率为9600(8M51,6M37,4M25,1M6,)
        sts         UBRR0L,                r16
        ldi         r16,                (1<<TXEN0)
            sts         UCSR0B,                r16
        ldi         r16,                (1<<usbs0)|(3<<ucsz00)
        sts         ucsr0c,                r16
       
/*=======================================
程序循环体开始
=======================================*/
LOOP:
        nop                                ;1cycle
        nop                                ;1cycle
        nop                                ;1cycle
        nop                                ;1cycle
        nop                                ;1cycle
        rcall        rfpro                        ;3cycle
/*=======================================
程序循环体结束
=======================================*/
LOOPE:
        RJMP         LOOP                         ;2cycle

;时基1微秒,如果电平没变化,循环检测一次需25个周期即25微秒
;循环计数器=6为窄脉冲=18为宽脉冲=184为同步位
rfpro:
        nop                                ;1cycle
        nop                                ;1cycle
        inc        cycnt                        ;1cycle
        in        r16,                rfpin        ;1cycle
        andi        r16,                0b00000100;保留引脚位1cycle
        in        r17,                gpior0        ;1cycle
        andi        r17,                0b00000100;保留引脚状态位1cycle
        cp        r16,                r17        ;1cycle
        brne        rfpro010                ;1cycle               
        cpi        cycnt,                100        ;1cycle
        brsh        rfpro001                ;1cycle
        ret                                ;电平与上次相同退出4cycle
rfpro001:
        clr        cycnt
        rjmp        rp023
        ret
rfpro010:
        com        r17                        ;电平不同取反并保存1cycle                        
        andi        r17,                0b00000100;保留引脚状态位1cycle
        bst        r17,                pinsta        ;1cycle
        in        r16,                gpior0        ;1cycle
        bld        r16,                pinsta        ;1cycle
        out        gpior0,                r16        ;1cycle
       
        sbic        gpior0,                pinsta        ;pinsta=1为低电平向高电平变化
        rjmp        rfpro020                ;如果是高电平向低电平变化跳转
        mov        highcnt,        cycnt
        clr        cycnt
        ret
rfpro020:
        mov        lowcnt,                cycnt
        clr        cycnt
        cp        lowcnt,                highcnt
        brlo        rp021
        clc
        rjmp        rp022
rp021:        sec
rp022:        rol        r8
        rol        r7
        rol        r6
        ret
rp023:        clr        bitcnt
        cp        rfadlo,                r6
        breq        rp024
        rjmp        rp030
rp024:        cp        rfadhi,                r7
        breq        rp025
        rjmp        rp030
rp025:        mov        r16,                rfda
        cpi        r16,                0
        brne        rp026
        rjmp        rp030
rp026:        cp        rfda,                r8
        breq        rp027
        rjmp        rp030
rp027:        sbi        portd,                7
        rcall        datatx       
        clr        r16
        clr        r17
dd0:       
        dec        r16
        brne        dd0
        dec        r17
        brne        dd0
        cbi        portd,                7
        ret
rp030:        ldi        r16,                $55
        mov        rfadlo,                r16
        mov        rfadhi,                r16
        mov        rfda,                r8
rp031:
        ret       

datatx:
        mov        r16,                rfadlo
        rcall        usart_tx
        mov        r16,                rfadhi
        rcall        usart_tx
        mov        r16,                rfda
        rcall        usart_tx

        ret

;usart发送一个字节子程序
usart_tx:
        push        r17
usart_tx010:       
        lds        r17,                ucsr0a
        sbrs         r17,                udre0
        rjmp         usart_tx010                ;将数据放入缓冲器,发送数据
        sts         udr0,                r16
       
        pop        r17
        ret
zyp568
2楼-- · 2020-02-08 14:43
回复【1楼】HYLG
-----------------------------------------------------------------------

呵呵,谢谢LS的朋友,原因大概找到了,刚用示波器比较了定时中断的高电平长度,确实比无线信号的“短”信号的高电平长度要短,虽然就短了一点点。
wangyj173
3楼-- · 2020-02-08 18:14
也谢过汇编的解码程序,后来还是改成了C,C编译后250字节,只需要用到定时器中断100us处理一次
zyp568
4楼-- · 2020-02-09 00:10
用汇编控制比较精确,C语言有点依赖于编译器。
问题已经解决了,还是不够仔细,察觉了问题又自己否决了,耽误了不少时间。
topdog
5楼-- · 2020-02-09 03:10
 精彩回答 2  元偷偷看……
zyp568
6楼-- · 2020-02-09 03:25
回复【5楼】topdog
-----------------------------------------------------------------------

呵呵,主要是用的义隆单片机,手边只有个借来的烧录器,没有仿真器,用汇编可以利用ADD A,0XFF来节省点芯片,另外调试时也直观一点。话说这义隆也太黑了,ADP064转接板,就1小块PCB+1条双排弯针居然要75块。。。

一周热门 更多>