两个51单片机串口通信程序?

两个51单片机串口通信程序?,第1张

串行发送程序 Tx.asm :

PCON, #00H 波特率不倍增

SETB TR1 启动定时器T1

MOV IE, #0 禁止任何中断

CALLDLY125 延时125ms

--------------------------------------------

T_X:透传发送字串

ACALL DSPLED P2.0控制LED闪亮

MOV R3, #4 待发送字符个数

MOV DPTR, #TAB_TX数据表首址

TX_LP1:CLR A

MOVCA, @A+DPTR A←数据表的1个字符

CLR TI TI清零,允许发送

MOV SBUF,A 发送1个字符

JNB TI, $ 等待1个字符帧发送结束

DJNZR3, TX_next

CALLDLY500 延时500ms

SJMPT_X 重复发送

TX_next:发送另一字符

INC DPTR 数据表指针移动

SJMPTX_LP1

--------------------------------------------

DSPLED: 开机或复位,P2.0控制LED闪亮6遍

MOV R2, #6 循环次数

LEDLP1:CLR P2.0 LED亮

CALL DLY125 延时125ms

SETB P2.0 LED灭

CALL DLY125

DJNZ R2,LEDLP1循环

RET

----------------------------------------------

DLY125:延时125ms

DLY125A: MOV R5,#250

DLY125B: MOV R6,#250

DJNZ R6,$

DJNZ R5,DLY125B

RET

250*250*2μs=125 000μs =125ms

----------------------------------------------

DLY500:延时500ms

MOV R7,#4

DLY500A: MOV R6,#250

DLY500B: MOV R5,#250

DJNZ R5,$

DJNZ R6,DLY500B

DJNZ R7,DLY500A

RET

4*250*250*2μs=500 000μs =500ms

-------------------------------------------------

TAB_TX: DB 38H,30H,35H,31H, ...

8 0 5 1 ...

----------------------------------------------

END

<p>甲机发送(拨码开关):</p>

<p>ORG 00H</p>

<p>AJMP MAIN</p>

<p>ORG 30H</p>

<p>MAIN: </p>

<p>MOV SCON,#50H 8位发送,接收</p>

<p>MOV TMOD,#20H 定时器1方式2,8 位自动重装。</p>

<p>MOV TH1,#0FAH 11.0592MHz,4800bps</p>

<p>MOV TL1,#0FAH</p>

<p>SETB TR1</p>

<p> </p>

<p>MAIN1:</p>

<p>MOV A,P1</p>

<p>CJNE A,20H,SEND_0</p>

<p>AJMP MAIN1</p>

<p>SEND_0:</p>

<p>ACALL SEND</p>

<p>AJMP MAIN1</p>

<p> </p>

<p>SEND:</p>

<p>MOV 20H,A</p>

<p>MOV SBUF,A</p>

<p>JBC TI,SEND</p>

<p>RET</p>

<p>END</p>

<p> </p>

<p> </p>

<p>乙机接收(LED显示):</p>

<p>ORG 00H</p>

<p>AJMP MAIN</p>

<p>ORG 30H</p>

<p>MAIN: </p>

<p>MOV SCON,#50H 串口工作方式1,允许接收。</p>

<p>MOV TMOD,#20H 定时器1工作方式2,8 位计数,自动重装定时常数</p>

<p>MOV TH1,#0FAH 11.0592MHz,4800bps</p>

<p>MOV TL1,#0FAH</p>

<p>SETB TR1</p>

<p>RECE: </p>

<p>JB RI,MAIN1 收完RI机器置1,转数据处理。</p>

<p>AJMP $-3 

没收完继续 </p>

<p>MAIN1: </p>

<p>MOV A,SBUF</p>

<p>MOV P2,A</p>

<p>CLR RI</p>

<p>AJMP RECE 

继续接收 </p>

<p> </p>

<p>END</p>

<p> </p>

<p> </p>

<p></p>

<p> </p>

汇编编写的模拟串口通信程序

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_TXDSTART BIT

MOV R0,A

CLR TR2TR2置1,计数器2启动,时间计数启动。

MOV A,RCAP2L计数器2重新装载值

MOV TL2,A置计数器2初值 T2需要重新装载

MOV A,DPH

MOV A,RCAP2H

MOV TH2,A

MOV A,R0

SETB TR2TR2置1,计数器

JNB TF2,$

CLR TF2

JNB TF2,$

CLR TF2

CLR UART_TXDSTART BIT

JNB TF2,$

CLR TF2

JNB TF2,$

CLR TF2

MOV R0,#08H

UART_SEND_LOOP:

RRC A

MOV UART_TXD,C8 BIT

JNB TF2,$

CLR TF2

JNB TF2,$

CLR TF2

DJNZ R0,UART_SEND_LOOP

SETB UART_TXDEND 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 TR2TR2置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 TR2TR2置1,计数器2启动,时间计数启动。

JNB TF2,$

CLR TF20.5 BIT

JNB TF2,$

CLR TF21 BIT

JNB TF2,$

CLR TF21.5 BIT

MOV C,UART_RXD

MOV ACC.0,C

JNB TF2,$

CLR TF2

JNB TF2,$

CLR TF22.5

MOV C,UART_RXD

MOV ACC.1,C

JNB TF2,$

CLR TF2

JNB TF2,$

CLR TF23.5

MOV C,UART_RXD

MOV ACC.2,C

JNB TF2,$

CLR TF2

JNB TF2,$

CLR TF24.5

MOV C,UART_RXD

MOV ACC.3,C

JNB TF2,$

CLR TF2

JNB TF2,$

CLR TF25.5

MOV C,UART_RXD

MOV ACC.4,C

JNB TF2,$

CLR TF2

JNB TF2,$

CLR TF26.5

MOV C,UART_RXD

MOV ACC.5,C

JNB TF2,$

CLR TF2

JNB TF2,$

CLR TF27.5

MOV C,UART_RXD

MOV ACC.6,C

JNB TF2,$

CLR TF2

JNB TF2,$

CLR TF28.5

MOV C,UART_RXD

MOV ACC.7,C

JNB TF2,$

CLR TF29.5

JNB UART_RXD,$等待停止位,并重新复位计数器

SETB UART_RXD

POP DPL

POP DPH

POP IE

RET

补充回答:

串口调试

1. 发送:向总线上发命令

2. 接收:从总线接收命令,并分析是地址还是数据。

3. 定时发送:从内存中取数并向主机发送.

经过调试,以上功能基本实现,可以通过上位机对单片机进行实时控制。

程序如下:

//这是一个单片机C51串口接收(中断)和发送例程,可以用来测试51单片机的中断接收

//和查询发送,发送没有必要用中断,因为程序的开销是一样的

#include <reg51.h>

#include<stdio.h>

#include <string.h>

#define INBUF_LEN 4 //数据长度

unsigned char inbuf1[INBUF_LEN]

unsigned char checksum,count3 , flag,temp,ch

bit read_flag=0

sbit cp=P1^1

sbit DIR=P1^2

int i

unsigned int xdata *RAMDATA/*定义RAM地址指针*/

unsigned char a[6] ={0x11,0x22,0x33,0x44,0x55,0x66}

void init_serialcomm(void)

{

SCON=0x50 //在11.0592MHz下,设置串行口波特率为9600,方式1,并允许接收

PCON=0x00

ES=1

TMOD=0x21 //定时器工作于方式2,自动装载方式

TH0=(65536-1000)%256

TL0=(65536-1000)/256

TL1=0xfd

TH1=0xfd

ET0=1

TR0=1

TR1=1

// TI=0

EA=1

// TI=1

RAMDATA=0x1F45

}

void serial () interrupt 4 using 3

{

if(RI)

{ RI=0

ch=SBUF

TI=1 //置SBUF空

switch(ch)

{

case 0x01 :printf("A") TI=0break

case 0x02 :printf("B") TI=0break

case 0x03 :printf("C") TI=0break

case 0x04 :printf("D") TI=0break

default :printf("fg") TI=0break

}

}

}

//向串口发送一个字符

void timer0() interrupt 1 using 3{

// char i

flag++

TH0=0x00

TL0=0x00

if(flag==10)

{// cp=!cp

// for(i=0i<6i++)

P2=0x25

TI=1

temp=*RAMDATA

printf("%c",temp)

TI=0

// RAMDATA--

flag=0

}

}

//主程序

main()

{

init_serialcomm() //初始化串口

//向6264中送数据

{

*RAMDATA=0x33

}

while(1)

{

*RAMDATA=0x33

}

}

调试需要注意的问题:

1. 发送过程:在发送时必须保证TI=1:即发送缓冲器为空,否则将导致数据发不出去,如果想强制发送可以用:TI=1.具体发送数据:利用printf(“abcd”)函数直接发送即可。

2. 接收过程:在接收时多选用中断方式,这样可以节约CPU的时间,提高效率,


欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/yw/11300104.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-05-15
下一篇 2023-05-15

发表评论

登录后才能评论

评论列表(0条)

保存