矿石收音机论坛

 找回密码
 加入会员

QQ登录

只需一步,快速开始

搜索
查看: 2929|回复: 23

请教串口通信

[复制链接]
     
发表于 2021-3-23 09:59:33 | 显示全部楼层 |阅读模式
本帖最后由 chencncjy 于 2021-3-23 10:01 编辑

SINT:        PUSH        DPL
                PUSH        DPH
                PUSH        A
                MOV         DPH,78H
                MOV                DPL,77H
                MOVX        A,@DPTR
                CLR                 TI       
                MOV                SBUF,A
                MOV                A,DPH
                CJNE                A,76H,END1
                MOV                A,DPL
                CJNE                A,75H,END1
                CLR                ES
                CLR                ET1
                CLR                TR1
ESCOM:        POP                A
                POP                DPH
                POP                DPL
                REIT sint.png
END1:        INC                77H
                MOV                A,77H
                JNZ                END2
                INC                 78H       
END2:        SJMP                ESCOM
SINT_SEVERS.png
SINT_2.png
     
发表于 2021-3-23 11:07:23 | 显示全部楼层
建议用C.

回复 支持 1 反对 0

使用道具 举报

     
发表于 2021-3-23 11:36:21 | 显示全部楼层
很抽象的东西,举个不恰当的例子说明
你正在写字,这时手机有电话打进来,接完电话后又续继写字,那么,接电话的过程就是“中断”,接完电话继续写未写完的字就是“返回断点”。
回复 支持 反对

使用道具 举报

     
 楼主| 发表于 2021-3-24 09:09:13 | 显示全部楼层
mov99 发表于 2021-3-23 11:36
很抽象的东西,举个不恰当的例子说明
你正在写字,这时手机有电话打进来,接完电话后又续继写字,那么,接 ...

你是做了定性的说明,道理是不难解,就是这个汇编来说,请指点一下
回复 支持 反对

使用道具 举报

     
发表于 2021-3-24 11:51:20 | 显示全部楼层
本帖最后由 mov99 于 2021-3-24 13:26 编辑
chencncjy 发表于 2021-3-24 09:09
你是做了定性的说明,道理是不难解,就是这个汇编来说,请指点一下


指点不敢当,51单片机我也是初学,共同探讨吧
如果方便请把完整的代码贴出来,按截图1的代码,只会在原地死循环。
123465.jpg

再猜一下
从代码看,好像是以查询的方式判断串口是否完成了发送,如果是就要先对串口的工作模式初始化
比如:

; 初始化串口(未启用中断)

SerialIniti:
          mov    SCON,#0x40       ; 串口工作方式1(8位可变UART波特率)
          mov    PCON,#0x0        ; 波特率不加倍
         
          mov    TMOD,#0x20       ; T1为波特率发生器,工作方式2(自动重新装载),T0为16位定时器/计数器
          mov    TH1,#0xFD        ; 波特率9600(Fosc=11.0592MHz)
          mov    TL1,#0xFD        ; 重载寄存器赋值
          setb   TR1              ; 启动T1
          ret
回复 支持 反对

使用道具 举报

     
发表于 2021-3-24 20:57:21 | 显示全部楼层
本帖最后由 mov99 于 2021-3-24 21:02 编辑

完整代码,未经验证,仅供参考

MARKCON   equ    0x20             ; 自定义标记寄存器
SIGN      bit    MARKCON.0        ; USART完成发送标记
;--------------------------------------------------------------------
          org    0x0              ; 存放代码起地址
          ljmp   TRANS            ; 跳转到主代码
          org    0x1B             ; 定时器1溢出中断入口
          ljmp   TINT
          org    0x23             ; 串行口中断入口
          ljmp   SINT
;--------------------------------------------------------------------
; 主代码

          org    0x100            ; 存放主代码起地址         
TRANS:    mov    SP,#0x63         ; 堆栈指针(64H起)
          call   SerialIniti      ; 调用初始化子代码
          mov    IE,#0x90         ; ES=1使能串口中断,EA=1全局中断允许
         
CHIEFLY:  mov    R0,#0x30         ; 预发送内容起地址->R0
          mov    R5,#0x5          ; 共发送5字节
          mov    SBUF,@R0         ; R0所指单元的内容->SBUF
         
LOOP:     call   Dealy50ms        ; 其它相关(在此用延时代替)
          jbc    SIGN,CHIEFLY     ; 完成发送?是,清标记并跳转到下一轮发送
          ljmp   LOOP             ; 否,到延时
;--------------------------------------------------------------------
; 服务中断

SINT:     push   ACC              ; 压栈(现场保护)
          push   PSW
         
          jnb    TI,COEMINT       ; 串口发送中断?否,到出栈
          clr    TI               ; 是,清标志
          djnz   R5,UPLOAD        ; 计数器减1,已发送5字?否,继续
          setb   SIGN             ; 是,置标记
          sjmp   COEMINT          ; 到出栈
         
UPLOAD:   inc    R0               ; 地址指针加1,指向下一单元
          mov    SBUF,@R0         ; R0所指单元的内容->SBUF
          sjmp   COEMINT          ; 到出栈
;---------------------------------
TINT:     push   ACC
          push   PSW
          jnb    ET1,COEMINT      ; 定时器1中断?
          clr    ET1              ; 是,清标志
          ; 其它相关
         
COEMINT:  pop    PSW              ; 出栈(恢复)
          pop    ACC
          reti                    ; 结束中断,返回断点
;--------------------------------------------------------------------
; 延时50ms

Dealy50ms:
          mov    R6,#0x61         ; (Fosc=11.0592MHz)
TO_DEL:   mov    R7,#0xEC
          djnz   R7,$
          djnz   R6,TO_DEL
          ret
;--------------------------------------------------------------------
; 初始化(含串口)

SerialIniti:
          mov    SCON,#0x40       ; 串口工作方式1(8位可变USART波特率)
          mov    PCON,#0x0        ; 波特率不加倍
         
          mov    TMOD,#0x20       ; T1为波特率发生器,工作方式2(自动重新装载),T0为16位定时器/计数器
          mov    TH1,#0xFD        ; 波特率9600(Fosc=11.0592MHz)
          mov    TL1,#0xFD        ; 重载寄存器赋值
          setb   TR1              ; 启动T1
         
          mov    0x30,#0x55       ; 预发送内容 55h.66h.77h.88h.99h
          mov    0x31,#0x66
          mov    0x32,#0x77
          mov    0x33,#0x88
          mov    0x34,#0x99

          mov    MARKCON,#0x0     ; 清标记寄存器
          ret
;--------------------------------------------------------------------
          end
回复 支持 反对

使用道具 举报

     
 楼主| 发表于 2021-3-25 09:01:22 | 显示全部楼层
mov99 发表于 2021-3-24 11:51
指点不敢当,51单片机我也是初学,共同探讨吧
如果方便请把完整的代码贴出来,按截图1的代码,只会在 ...

这断代码前面的假设是,(78H)=20H,(77H)=00H,为首地址;(76H)=20H,(75H)=20H为末地址,
                MOV SBUF,78H                ;向SBUF中发送,启动串口发送
WAIT1:        JNB   TI,WAIT1                ;从这里触发了串口的中断进入中断服务
                CLR         TI
                MOV                 SBUF,77H
WAIT2:        JNB                TI,WAIT2
                CLR                TI               
                SETB         ES
....
SINT:        PUSH                        ..
                MOV                 DPH,78H
                MOV                 DPL,77H
                MOVX           A,@DPTR
                CLR                 TI       
                MOV                 SBUF,A
                CJNE                A,76H,END1

END1:        INC                 77H                        ;77H单元自增1
                MOV                 A,77H
                JNZ                ED2
                INC                 78H
END2:        SJMP                ESCOM

ESCOM:        POP                ..
                REIT

这里我不理解的是,MOV SBUF,78H, 向‘SBUF’传了数据,启动了发送,传完数据 ,触发了中断,
在中断服务中,有INC 77H,和INC 78H ,中断服务中循环执行的,还是就执行一次;
如果中断服务中只进行了一次,回到‘JNB  TI,WAIT1’,往下执行。我认为只进行一次,如何通过INC  77H自增到20H
回复 支持 反对

使用道具 举报

     
发表于 2021-3-25 11:46:31 | 显示全部楼层
本帖最后由 mov99 于 2021-3-25 11:48 编辑
chencncjy 发表于 2021-3-25 09:01
这断代码前面的假设是,(78H)=20H,(77H)=00H,为首地址;(76H)=20H,(75H)=20H为末地址,
                MO ...


再猜一下哈
根据代码加了注释(仅供参考),自己判断代码怎么运行

          MOV     SBUF,78H        ; 向SBUF中发送,启动串口发送

WAIT1:    JNB     TI,WAIT1        ; 查询,完成发送?否,再查,跳转到WAIT1
          CLR     TI              ; 是,清中断标志
          MOV     SBUF,77H        ; 77H->SBUF
WAIT2:    JNB     TI,WAIT2        ; 查询,完成发送?否,再查,跳转到WAIT2
          CLR     TI              ; 是,清中断标志
          SETB    ES              ; 使能串口中断(全局中断是否开放不详)

; 长驱直入服务中断

SINT:     PUSH    ACC             ; 压栈(现场保护)
          PUSH    PSW

          MOV     DPH,78H         ; 读外部RAM地址高8位
          MOV     DPL,77H         ; 读外部RAM地址低8位
          MOVX    A,@DPTR         ; 以DPTR为地址指针的外部RAM内容->累加器A
          CLR     TI              ; 清串口中断标志
          MOV     SBUF,A          ; 累加器A中的内容->SBUF,串口发送
          CJNE    A,76H,END1      ; 累加器A与76H内容相等?否,跳转的END1.(若相等,执行下一指令,仍然到END1,猜不出想做什么)

END1:     INC     77H             ; 是(A=76H),读外部RAM地址低8位+1
          MOV     A,77H           ; 77H内容->累加器A
          JNZ     ED2             ; 查询,累加器A的内容等于零?,否,跳转到ED2(然后在出栈)
          INC     78H             ; 是,读外部RAM地址高8位地址+1(进位)
END2:     SJMP    ESCOM           ; 跳转到出栈

ESCOM:    POP    PSW              ; 出栈(恢复)
          POP    ACC
          REIT                    ; 结束中断,返回断点.(如果是长驱直入服务中断,将导致运行混乱而进入不断复位的死循环)

个人建议:只有奇思妙想远远不够,在51开发环境可软件仿真,一套51最小系统开发板十几元,准备一套,事半公倍
回复 支持 反对

使用道具 举报

     
 楼主| 发表于 2021-3-25 14:43:19 | 显示全部楼层
mov99 发表于 2021-3-25 11:46
再猜一下哈
根据代码加了注释(仅供参考),自己判断代码怎么运行

看的出,您对汇编学的应用自如,谢谢你在百忙之中抽时间回!谢谢
回复 支持 反对

使用道具 举报

     
发表于 2021-3-25 17:58:02 | 显示全部楼层
chencncjy 发表于 2021-3-25 14:43
看的出,您对汇编学的应用自如,谢谢你在百忙之中抽时间回!谢谢

共同探讨
回复 支持 反对

使用道具 举报

     
 楼主| 发表于 2021-3-26 08:59:53 | 显示全部楼层
chencncjy 发表于 2021-3-25 14:43
看的出,您对汇编学的应用自如,谢谢你在百忙之中抽时间回!谢谢

请教你一个问题

                ORG  0000H
                LJMP         START

                ORG 0030H
START:        ....
                END

"ORG 0030H",我认为是不会执行的,这名的目的是什么
回复 支持 反对

使用道具 举报

     
发表于 2021-3-26 10:00:59 | 显示全部楼层
本帖最后由 iffi123 于 2021-3-26 10:02 编辑
chencncjy 发表于 2021-3-26 08:59
请教你一个问题

                ORG  0000H


这是指定代码存放地址,ORG 0000H下面不有个跳转到START的指令吗, START存放在0030H开始的地址空间
回复 支持 反对

使用道具 举报

     
发表于 2021-3-27 09:56:32 | 显示全部楼层
看楼主对伪指令一头雾水
回复 支持 反对

使用道具 举报

     
发表于 2021-3-27 11:39:00 | 显示全部楼层
本帖最后由 mov99 于 2021-3-27 11:40 编辑
chencncjy 发表于 2021-3-26 08:59
请教你一个问题

                ORG  0000H

共同探讨
ORG 是伪指令,不会被单片机执行,用来通知或告诉编译器,存放代码的起始地址
最常用的伪指令还有:

END   代码结束
EQU   定义常数, 比如:ABC1  EQU  0x20    ; 定义ABC1地址为20H('0x'十六进制数)
BIT   位地址命名,比如:XYZ  BIT  ABC1.0  ; 定义ABC1的第0bit为XYZ
DB    连续的存储区装载字节型数据,比如:
font16x16  EQU   0x1000     ; 定义font16x16
;-------------------------------------------------------------------
           org    font16x16  ; 定义存放font16x16字符起始地址为0x1000
DB 0x00,0x00,0xF0,0x10,0x08,0x21,0x08,0x21,0x08,0x21,0x08,0x21,0xF0,0x1F,0x00,0x00;
回复 支持 反对

使用道具 举报

     
发表于 2021-3-28 07:30:21 | 显示全部楼层
uⅤ4仿调形同鸡肋,与proteus联调才是正道
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 加入会员

本版积分规则

小黑屋|手机版|矿石收音机 ( 蒙ICP备05000029号-1 )

蒙公网安备 15040402000005号

GMT+8, 2024-4-28 22:34

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表