逻辑上找不出什么问题,也没陷如什么死循环,但是读到的数据总是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
友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
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
-----------------------------------------------------------------------
呵呵,谢谢LS的朋友,原因大概找到了,刚用示波器比较了定时中断的高电平长度,确实比无线信号的“短”信号的高电平长度要短,虽然就短了一点点。
问题已经解决了,还是不够仔细,察觉了问题又自己否决了,耽误了不少时间。
-----------------------------------------------------------------------
呵呵,主要是用的义隆单片机,手边只有个借来的烧录器,没有仿真器,用汇编可以利用ADD A,0XFF来节省点芯片,另外调试时也直观一点。话说这义隆也太黑了,ADP064转接板,就1小块PCB+1条双排弯针居然要75块。。。
一周热门 更多>