千家论坛_弱电智能化技术与工程讨论(建筑智能,家居智能,人工智能)

路由交换
收藏本版 (7) |订阅

路由交换 今日: 3703 |主题: 18312|排名: 28 

发新帖
打印 上一主题 下一主题

MSC51汇编代码编写的模拟串口程序。...

[复制链接]
豆儿 发布于: 2003-8-9 09:18 2017 次浏览 5 位用户参与讨论
跳转到指定楼层
[推荐] MSC51汇编代码编写的模拟串口程序。 T2作为波特率控制 UART_RXD 是硬中断0或1口,如果能进入中断,说明该线有一个起始位产生,进入中断后调 用下面的接收程序。退出硬中断之前还需要将硬中断标志重新复位。 UART_TXD 是任何其它IO即可。 UART_SEND: PUSH IE PUSH DPH PUSH DPL PUSH PSW PUSH 00H PUSH ACC CLR EA SETB UART_TXD ;START BIT MOV R0,A CLR TR2 ;TR2置1,计数器2启动,时间计数启动。 MOV A,RCAP2L;计数器2重新装载值 MOV TL2,A ;置计数器2初值 ;T2需要重新装载 MOV A,DPH MOV A,RCAP2H MOV TH2,A MOV A,R0 SETB TR2 ;TR2置1,计数器 JNB TF2,$ CLR TF2 JNB TF2,$ CLR TF2 CLR UART_TXD ;START BIT JNB TF2,$ CLR TF2 JNB TF2,$ CLR TF2 MOV R0,#08H UART_SEND_LOOP: RRC A MOV UART_TXD,C ;8 BIT JNB TF2,$ CLR TF2 JNB TF2,$ CLR TF2 DJNZ R0,UART_SEND_LOOP SETB UART_TXD ;END BIT JNB TF2,$ CLR TF2 JNB TF2,$ CLR TF2 POP ACC POP 00H POP PSW POP DPL POP DPH POP IE RET ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; UART_REC: PUSH IE PUSH DPH PUSH DPL CLR EA CLR TR2 ;TR2置1,计数器2启动,时间计数启动。 MOV A,RCAP2L;计数器2重新装载值 MOV TL2,A ;置计数器2初值 ;T2需要重新装载 MOV A,DPH MOV A,RCAP2H MOV TH2,A JB UART_RXD,$ ;REC SETB TR2 ;TR2置1,计数器2启动,时间计数启动。 JNB TF2,$ CLR TF2 ;0.5 BIT JNB TF2,$ CLR TF2 ;1 BIT JNB TF2,$ CLR TF2 ;1.5 BIT MOV C,UART_RXD MOV ACC.0,C JNB TF2,$ CLR TF2 JNB TF2,$ CLR TF2 ;2.5 MOV C,UART_RXD MOV ACC.1,C JNB TF2,$ CLR TF2 JNB TF2,$ CLR TF2 ;3.5 MOV C,UART_RXD MOV ACC.2,C JNB TF2,$ CLR TF2 JNB TF2,$ CLR TF2 ;4.5 MOV C,UART_RXD MOV ACC.3,C JNB TF2,$ CLR TF2 JNB TF2,$ CLR TF2 ;5.5 MOV C,UART_RXD MOV ACC.4,C JNB TF2,$ CLR TF2 JNB TF2,$ CLR TF2 ;6.5 MOV C,UART_RXD MOV ACC.5,C JNB TF2,$ CLR TF2 JNB TF2,$ CLR TF2 ;7.5 MOV C,UART_RXD MOV ACC.6,C JNB TF2,$ CLR TF2 JNB TF2,$ CLR TF2 ;8.5 MOV C,UART_RXD MOV ACC.7,C JNB TF2,$ CLR TF2 ;9.5 JNB UART_RXD,$ ;等待停止位,并重新复位计数器 SETB UART_RXD POP DPL POP DPH POP IE RET
回复

使用道具 举报

已有5人评论

新浪微博达人勋

千家认证

沙发
asa999 发表于 2005-8-24 17:28:00
SETB TR2 ;TR2置1,计数器 JNB TF2,$ CLR TF2 JNB TF2,$ CLR TF2 楼主知道,JNB是什么指令吗,目前想重新学一次单片机,有好多东西都想不起来了
回复 支持 反对

使用道具 举报

新浪微博达人勋

千家认证

板凳
asa999 发表于 2005-8-24 17:28:00
SETB TR2 ;TR2置1,计数器 JNB TF2,$ CLR TF2 JNB TF2,$ CLR TF2 楼主知道,JNB是什么指令吗,目前想重新学一次单片机,有好多东西都想不起来了
回复 支持 反对

使用道具 举报

新浪微博达人勋

千家认证

地板
豆儿 发表于 2005-8-30 15:12:00

JNB TF2,$

是检测,tF2,是0,就转移

是1 ,则向下执行。

$ 是等等, 也可以算是停机。

回复 支持 反对

使用道具 举报

新浪微博达人勋

千家认证

5#
SupermanTm 发表于 2005-10-16 16:22:00

这个程序是不是更好些呢?

[URL=http://www.mcustudio.com/hwtj/2003427164150.asp]软件重构串行口
[此贴子已经被作者于2005-10-17 15:22:44编辑过]
回复 支持 反对

使用道具 举报

新浪微博达人勋

千家认证

6#
SupermanTm 发表于 2005-10-18 16:01:00
很多时候我们需要不止一个UART串行口的时候,可以用下面的程序直接“创造”一个的; 波特率是:9600bps@11.0592MHz 命名约定: ;前缀 含义 ;on...事件程序入口 ;f....位变量/标志 ;c....常数 ;p....端口定义 ; pTXD BIT P1.2 ; 软件UART的TXD口 ; 软件UART的RXD口固定是INT0端口 ; fByteRx BIT 0 ; 硬件UART接收到一个字节 fByteRx1 BIT 1 ; 软件UART接收到一个字节 fByteTx1 BIT 2 ; 软件UART发送完一个字节(在停止位时刻有效) fFirstBit BIT 3 ; 软件UART发送: 起始位 fStopBit BIT 4 ; 软件UART发送: 停止位 ; TxCount DATA 7FH ; 硬件UART发送字节数 TxPtr DATA 7EH ; 硬件UART发送缓冲区指针 RxBuff DATA 7DH ; 硬件UART接收缓存器 RxPtr DATA 7CH ; 硬件UART接收缓冲区指针(不使用接收缓冲区时置0) ; portbuf DATA 7BH ; 软件UART接收: 采样保持缓存器 TxBuff1 DATA 7AH ; 软件UART发送移位寄存器 ; TxCount1 DATA 79H ; 软件UART发送字节数 TxPtr1 DATA 78H ; 软件UART发送缓冲区指针 RxBuff1 DATA 77H ; 软件UART接收缓存器 RxPtr1 DATA 76H ; 软件UART接收缓冲区指针(不使用接收缓冲区时置0) ; ORG 0 NOP AJMP onStart NOP MOV TL0,#0D4H ; 0.5 bit 加上跳入中断的两个周期和SETB的周期 SETB TR0 iRETN: RETI ; ORG 0BH ; 写不写都是 0BH 的了 MOV portbuf,P3 ; 首先采样, 采样是高实时的! ACALL iRETN ; 已经采样了,就释放中断(允许别的中断) AJMP onRxBit ; ================================================================== ORG 1BH ; 发送波特率发生器 XCH A,TxBuff1 ; A -> TxBuf RRC A ; C -> ACC.7 MOV pTXD,C ; 送出数据 ACALL iRETN ; 实时部分完成,释放中断 SJMP $+1 ; 注意,这里的 $+X 不产生作用的,目标总在0034H! ; ; 因为后面的 JBC 机器码是 10 99 04, 其10 为 SJMP 的操作数! ; ================================================================== ORG 23H ; 硬件串行口程序: 建立标志后在主程序处理! JBC TI,onTxD ; 这句不得更改! (前面的原因) JBC RI,onRxD RETI onTxD: INC TxCount DJNZ TxCount,onTxD1 ; 如果是零则忽略,(防止出错) RETI onTxD1: DJNZ TxCount,onTxD2 RETI ; 已经发完 ; ================================================================== ORG 34H ; 连接在上面的 SJMP $+1 那里 onTxBit: MOV C,ACC.7 ; 恢复 C JBC fStopBit,onTxByte ; 已经是停止位, 一个字节发送完 -> ORL TH0,#0A0H ; 加载波特率, 注意, 必须用 ORL 来加载! JBC fFirstBit,onTxBit1 ; 发送的是第一位 -> CLR ACC.7 ; 以 0 填充, 为后面的判断 JZ onTxBit2 ; 全 0, 8 位已送完! -> XCH A,TxBuff1 ; 未完, 恢复现场 RET ; 不能用 RETI, 前面已经 RETI 过了 onTxBit1: SETB ACC.7 ; 开始时给D7设置1, 让它一直移到右边出去 XCH A,TxBuff1 ; 恢复现场 RET onTxBit2: SETB fStopBit ; 8 位已送完, 下一个是停止位 MOV TH0,A ; 延长停止位 INC A ; 让 TxBuff1 = 1, Keep 住高电平 XCH A,TxBuff1 ; 恢复现场 SETB fByteTx1 ; 通知主程序一个字节已送出 RET ; ------------------------------------------------------------------ onTxByte: MOV A,TxBuff1 ; 恢复 A DJNZ TxCount1,TxBYTEA ; 还需发送, 接着发下一个字节 CLR TR1 ; 没有发送了, 停止波特率发生器 RET ; ================================================================== ; 上面的地址空间不足,写在这里 onTxD2: XCH A,TxPtr ; 很简单的队列操作! 不解释啦 INC A XCH A,R1 MOV SBUF,@R1 SJMP onUARTEnd onRxD: MOV RxBuff,SBUF SETB fByteRx ; 通知主程序有字节被接收 XCH A,RxPtr JZ onRxD1 INC A XCH A,R1 MOV @R1,RxBuff onUARTEnd: XCH A,R1 onRxD1: XCH A,RxPtr RETI ; ================================================================== TxBYTEA: XCH A,TxPtr1 XCH A,R1 MOV TxBuff1,@R1 INC R1 XCH A,R1 XCH A,TxPtr1 ; ------------------------------------------------------------------ TxBYTE: MOV TH0,#0CFH ; 启动波特率发生器 SETB TR1 CLR pTXD ; 发送起始位 SETB fFirstBit ; 告知中断程序这是起始位 CLR fStopBit ; 当然不是停止位啦 RET ; ------------------------------------------------------------------ ; 发送数据的使用方法: ; MOV TxPtr1,#<发送缓冲区首址> ; MOV TxCount1,#<发送的字节数> ; ACALL TxBYTEA ; ; 简单地发送一个字节: ; MOV TxBuff1,<待发送的数据> ; MOV TxCount1,#1 ; ACALL TxBYTE ; ================================================================== ; 软件UART接收: onRxBit: ORL TL0,#0A0H ; 加载波特率 JBC EX0,onRxBit1st ; 起始的半个位, -> XCH A,portbuf ; 保护 A -> portbuf RLC A ; 保护 C -> ACC.0 MOV C,ACC.3 ; 取采样结果 RxD = P3.2(上面移了一位,所以取D3) XCH A,RxBuff1 ; 移进 RxBuff1 RRC A XCH A,RxBuff1 RRC A ; 恢复C(ACC.0->C->ACC.7)ACC.7为结束标志 JNB ACC.7,onRxEnd ; 未足一字节 -> CLR TR0 ; 停止波特率发生器 MOV A,RxPtr1 JZ onRxByte1 ; 指针为空, 不作队列处理 -> INC A ; 指针非空, 指针增量 MOV RxPtr1,A XCH A,R1 ; 写入队列 MOV @R1,RxBuff1 MOV R1,A ; 恢复 R1 onRxByte1: SETB EX0 ; 允许下一次接收 SETB fByteRx1 ; 通知主程序有字节被接收 onRxEnd: MOV A,portbuf ; 恢复 A RET onRxBit1st: MOV RxBuff1,#80H RET ; ================================================================== onStart: ; 程序开始的初始化 CLR A MOV IE,A ; 禁止中断 MOV PSW,A ;... MOV TH1,#0FDh ;<c9600bps> MOV TMOD,#23H ; Timer1 运行(T0@模式3,上下8位各自给接收和发送) MOV SCON,#50H ; 硬件UART MOV PCON,#00H ; 硬件UART 波特率不倍增 MOV TCON,#01H ; EX0 边沿触发(用于捕获起始位) MOV IP,#0BH ; UART 低优先级, EX0,ET0,ET1高优先级 MOV IE,#9BH ; 允许中断 ; ... end
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册 新浪微博登陆 千家通行证登陆

本版积分规则

千家智客微信号
千家智客微信
玩物说商城
玩物说商城