帮忙,a_to_b,两块单片机间通信不成功?


A机向B机发送信息,B机收到后进行解码,若所得的数据与本机号相同,则作出反应(即B 机的P3.7口点亮一个发光二极管)。具体功能如下所实!

但我做了很久也没有成功,希望有高人出手!

;===================发射程序===================================
;所用系统51单片机,fosc=11.0592Mhz
;功能:P3.6,p3.7安装发射键,当有按键按下时,通过p1.0
;发送数据,P3.6键按下时发射01010001,而P3.7发射01010010
;发射数据前先发送引导码,引导码由4.96ms低电平与4.96ms高电平组成
;0码由0.64ms低电平与0.64ms高电平组成
;1码由0.64ms低电平与1.860ms高电平组成
;==============================================================


;=====================解码程序=================================================
;所用系统51单片机,fosc=11.0592Mhz
;时间2008—10
;以脉宽为0.64ms低电平、0.64ms高电平、周期为1.28ms的组合表示二进制的“0”。
;以脉宽为0.64ms低电平、1.860ms高电平、周期为2.5ms的组合表示二进制的“1”。
;解码的关键是如何识别“0”和“1”,从位的定义我们可以发现“0”、“1”均以0.64ms的低电平开始,
;不同的是高电平的宽度不同,“0”为0.64ms,“1”为1.86ms, 所以必须根据高电平的宽度区别“0”和“1”。
;如果从0.64ms低电平过后,开始延时,0.64ms以后,若读到的电平为低,说明该位为“0”,反之则为“1”,
;为可靠起见,延时必须比0.64ms长些,但又不能超过1.28ms,否则如果该位为“0”,读到的已是下一位高电平,
;因此取(1.28ms+0.64ms)/2=0.96ms最为可靠,一般取0.96ms左右即可。
;根据发射的格式,程序应该等待 4.96ms 的起始码和 4.96ms 的结果码完成后才能读码
;============================================================================




代码如下:
;===================发射程序===================================
;所用系统51单片机,fosc=11.0592Mhz
;功能:P3.6,p3.7安装发射键,当有按键按下时,通过p1.0
;发送数据,P3.6键按下时发射01010001,而P3.7发射01010010
;发射数据前先发送引导码,引导码由4.96ms低电平与4.96ms高电平组成
;0码由0.64ms低电平与0.64ms高电平组成
;1码由0.64ms低电平与1.860ms高电平组成
;==============================================================
ORG 0000H
SJMP MAIN
ORG 0030H
;------主程序-------------------
MOV P3,#0FFH
MAIN: JNB P3.6,KEY0
JNB P3.7,KEY1
SJMP MAIN
KEY0: LCALL DELAY_1 ;防抖动
JB P3.6,MAIN
JNB P3.6,$ ;等待按键松开
LCALL ACTION_0
LJMP MAIN ;发送完毕
KEY1: LCALL DELAY_1 ;防抖动
JB P3.7,MAIN
JNB P3.7,$ ;等待按键松开
LCALL ACTION_1
LJMP MAIN ;发送完毕
;------动作-----------------
ACTION_0:
CLR P1.0
NOP
SETB P1.0
NOP
CLR P1.0 ;引导码
LCALL DELAY_1
SETB P1.0
LCALL DELAY_1

LCALL CODE0 ;操作码01010001
LCALL CODE1
LCALL CODE0
LCALL CODE1
LCALL CODE0
LCALL CODE0
LCALL CODE0
LCALL CODE1
LJMP MAIN
ACTION_1:
CLR P1.0
NOP
SETB P1.0
NOP
CLR P1.0 ;引导码
LCALL DELAY_1
SETB P1.0
LCALL DELAY_1
LCALL CODE0 ;操作码01010001
LCALL CODE1
LCALL CODE0
LCALL CODE1
LCALL CODE0
LCALL CODE0
LCALL CODE1
LCALL CODE0
LJMP MAIN



;-----------0-------------------------------------
CODE0: CLR p1.0
LCALL DELAY_2
SETB P1.0
LCALL DELAY_2
RET
;-----------1-------------------------------------
CODE1: CLR P1.0
LCALL DELAY_2
SETB P1.0
LCALL DELAY_3
RET
;---------DELAY4960uS-----------------------------
DELAY_1: MOV R4,#10 ;延时子程序1,延时4960微秒
D1:  MOV R5,#225
     DJNZ R5,$
     DJNZ R4,D1
     RET
;---------DELAY0.64MS-----------------------------
DELAY_2: MOV R4,#10 ;延时子程序2,延时640微秒
D2:  MOV R5,#27
     DJNZ R5,$
     DJNZ R4,D2
    RET
;---------DELAY1860uS-----------------------------
DELAY_3: MOV R4,#10 ;延时子程序3,延时1860微秒
D3: MOV R5,#83
DJNZ R5,$
DJNZ R4,D3
RET
;---------DELAY1S---------------------------------
DELAY_4: MOV R4,#20 ;延时子程序4,延时10000微秒
D4: MOV R5,#250
DJNZ R5,$
DJNZ R4,D4
RET

        END




;=====================解码程序====================================================================
;所用系统51单片机,fosc=11.0592Mhz
;时间2008—10
;以脉宽为0.64ms低电平、0.64ms高电平、周期为1.28ms的组合表示二进制的“0”。
;以脉宽为0.64ms低电平、1.860ms高电平、周期为2.5ms的组合表示二进制的“1”。
;解码的关键是如何识别“0”和“1”,从位的定义我们可以发现“0”、“1”均以0.64ms的低电平开始,
;不同的是高电平的宽度不同,“0”为0.64ms,“1”为1.86ms, 所以必须根据高电平的宽度区别“0”和“1”。
;如果从0.64ms低电平过后,开始延时,0.64ms以后,若读到的电平为低,说明该位为“0”,反之则为“1”,
;为可靠起见,延时必须比0.64ms长些,但又不能超过1.28ms,否则如果该位为“0”,读到的已是下一位高电平,
;因此取(1.28ms+0.64ms)/2=0.96ms最为可靠,一般取0.96ms左右即可。
;根据发射的格式,程序应该等待 4.96ms 的起始码和 4.96ms 的结果码完成后才能读码
;=================================================================================================
ORG 0000H
SJMP MAIN
ORG 0030H
MAIN: MOV P1,#0FFH
JB P1.0,$  ;等待控制信号出现
MOV R6,#4
LOOP0: LCALL DELAY_1
JB P1.0,EXIT ;若在960us若出现高电平则退出解码
DJNZ R6,LOOP0  ;重复4次,目的是检测在 4800微秒内如果出现高电平就退出解码程序
JNB P1.0,$ ;等待高电平避开 4.96 毫秒低电平引导脉冲
LCALL DELAY_2
LOOP1: MOV R1,#8
JB P1.0,$ ;等待低电平(数据码)避开 4.96 毫秒低电平引导脉冲
NOP
NOP
LOOP2: JNB P1.0,$ ;等待第一个数据的高电平
LCALL DELAY_1 ;高电平开始后用960微秒的时间延时去判断信号此时的高低电平状态
MOV C,P1.0 ;把P1.0的电平情况保存入C
JNC LOOP3 ;若C为低电平,则跳转
LCALL DELAY_3 ;检测到高电平1的话延时1毫秒等待脉冲高电平结束
LOOP3: RRC A
DJNZ R1,LOOP2 ;是否接收完8位数据
CJNE A,#10001010B,EXIT   ;比较,是否本机地址
DONE: CLR P3.7
LJMP    EXIT
EXIT: LJMP MAIN
;------延时子程序------
DELAY_1: MOV R4,#20 ;延时子程序1,延时960微秒
D1:  MOV R5,#20
NOP
     DJNZ R5,$
     DJNZ R4,D1
    RET
DELAY_2: MOV R4,#10 ;延时子程序2,延时4500微秒
D2:  MOV R5,#200
     DJNZ R5,$
     DJNZ R4,D2
     RET
DELAY_3: MOV R4,#2;延时程序3,延时>1000微秒
D3:MOV R5,#255
    DJNZ R5,$
    DJNZ R4,D3
    RET
END

a_to_b.rar
(2008-10-04 21:50:36, Size: 28.9 KB, Downloads: 3)


我也来说两句 查看全部回复

最新回复

  • budhy (2008-10-04 22:16:50)

    QUOTE:

    原帖由 cnsuccess 于 2008-10-4 21:50 发表
    A机向B机发送信息,B机收到后进行解码,若所得的数据与本机号相同,则作出反应(即B 机的P3.7口点亮一个发光二极管)。具体功能如下所实!
    ...
    看了你的程序,原来你不用单片机的 UART。
    这样的项目虽然有一定的实验价值,但完全没有实际应用价值。我劝你还是用 UART 吧。
  • zhl45 (2008-10-05 14:02:13)


    看看!
    试试!
  • cnsuccess (2008-10-06 15:25:04)

    QUOTE:

    原帖由 budhy 于 2008-10-4 22:16 发表


    看了你的程序,原来你不用单片机的 UART。
    这样的项目虽然有一定的实验价值,但完全没有实际应用价值。我劝你还是用 UART 吧。
    我之所以没有用UART,是因为实际应用时是用无线收发模块进行20米左右的无线控制用的!如果用UART口,加上无线模块后就根本无法工作了!这个模块传输速率很小!
  • thx02334 (2008-10-06 16:06:23)

    汇编的我 不太懂啊
  • budhy (2008-10-06 16:07:31)

    QUOTE:

    原帖由 cnsuccess 于 2008-10-6 15:25 发表



    我之所以没有用UART,是因为实际应用时是用无线收发模块进行20米左右的无线控制用的!如果用UART口,加上无线模块后就根本无法工作了!这个模块传输速率很小! ...
    虽然用是用无线收发模块,仍然还要用 UART 再加上 FSK (Frequency Shift Keying)线路,让UART 的逻辑电平转变成电波频率。