如何实现2个51单片机之间通过串口通信的源程序

如何实现2个51单片机之间通过串口通信的源程序,第1张

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

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 ;05 BIT

JNB TF2,$

CLR TF2 ;1 BIT

JNB TF2,$

CLR TF2 ;15 BIT

MOV C,UART_RXD

MOV ACC0,C

JNB TF2,$

CLR TF2

JNB TF2,$

CLR TF2 ;25

MOV C,UART_RXD

MOV ACC1,C

JNB TF2,$

CLR TF2

JNB TF2,$

CLR TF2 ;35

MOV C,UART_RXD

MOV ACC2,C

JNB TF2,$

CLR TF2

JNB TF2,$

CLR TF2 ;45

MOV C,UART_RXD

MOV ACC3,C

JNB TF2,$

CLR TF2

JNB TF2,$

CLR TF2 ;55

MOV C,UART_RXD

MOV ACC4,C

JNB TF2,$

CLR TF2

JNB TF2,$

CLR TF2 ;65

MOV C,UART_RXD

MOV ACC5,C

JNB TF2,$

CLR TF2

JNB TF2,$

CLR TF2 ;75

MOV C,UART_RXD

MOV ACC6,C

JNB TF2,$

CLR TF2

JNB TF2,$

CLR TF2 ;85

MOV C,UART_RXD

MOV ACC7,C

JNB TF2,$

CLR TF2 ;95

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

SETB UART_RXD

POP DPL

POP DPH

POP IE

RET

补充回答:

串口调试

1 发送:向总线上发命令

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

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

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

程序如下:

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

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

#include <reg51h>

#include<stdioh>

#include <stringh>

#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; //在110592MHz下,设置串行口波特率为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=0;break;

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

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

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

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

}

}

}

//向串口发送一个字符

void timer0() interrupt 1 using 3{

// char i;

flag++;

TH0=0x00;

TL0=0x00;

if(flag==10)

{// cp=!cp;

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

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的时间,提高效率,

ORG  0000H

AJMP MAIN    ;上电,转向主程序

ORG  0023H    ;串行口的中断入口地址

AJMP SERVE  ;转向中断服务程序

ORG  0040H    ;主程序

MAIN: MOV  SP,#60H  ;设置堆栈指针

MOV  SCON ,#50H

MOV  PCON ,#00H

MOV  TMOD,#20H

MOV  TH1,#0F3H

MOV  TL1,#0F3H

SETB  TR1

MOV  R0 ,#20H  ;置发送数据区首地址

MOV  R1 ,#40H  ;置接收数据区首地址

MOV  R7 ,#10H  ;置发送字节长度

MOV  R6 ,#10H  ;置接收字节长度

SETB ES            ;允许串行口中断

SETB EA            ;CPU允许中断

MOV  A ,@R0      ;取第一个数据发送

MOV  SBUF ,A        ;发送第一个数据

SJMP $      ;等待中断

SERVE: JNB  RI ,SEND  ;TI=1,为发送中断

CLR RI

MOV A ,SBUF  ;读出接收缓冲区内容

MOV @R1 ,A    ;读入接收缓冲区

DJNZ R6 ,L1  ;判断数据块发送完否

SJMP L2    ;数据块接收完,转L2

L1:INC  R1    ;修改数据区指针

L2:RETI                ;中断返回

SEND:

CLR  TI            ;清除发送中断标志

DJNZ R7 ,L3  ;判断数据块发送完否

SJMP L4    ;数据块接收完,转L4

L3:  MOV  A ,@R0    ;取数据发送

MOV  SBUF ,A    ;发送数据

INC  R0            ;修改数据地址

L4:

RETI                ;中断返回

END

51单片机当P10置零时每隔1秒钟向串口发送一个hello,这是典型的串口发送程序,在P10脚接一个按键。主程序先初始化串口,设置波特率,不要开中断,一定要有TI=1; 主程序用printf 函数发送字符串比较方便。当主程序检测到P10脚按键按下,用一个printf("hello");语句即可。

1。这是一条无条件 转移语句,这里转移地址为本条指令,就是原地无限循环。

去掉后 程序会继续 执行进入无程序区 后又回到开始,也相当于重复运行原程序。

2。串口通讯的 RI和TI 为 接收 和 发送 一个字节数据 结束 后 置1 ,需要软件清零。

3。F0 是一个 在状态寄存器中 的 用户标志位,用户编程时可以使用,也可以在可以

位 *** 作的RAM区 自己定义。

4。CLR ES 是关闭串口中断,这样就不会产生 串口中断,具体要看 程序需要,或者

在需要 关闭中断 的时候 关闭,需要 打开 时再 开启 中断,视编程方法而定。

5。你可以 通过 仿真 试试 你所提出的 情况 试试,可以增强认识。

以上就是关于如何实现2个51单片机之间通过串口通信的源程序全部的内容,包括:如何实现2个51单片机之间通过串口通信的源程序、使用AT89C51的串行口按工作方式1进行串行数据通信,假定波特率为2 400bit/s,以中断方式传送数据,请编写、求51单片机当P1.0置零时每隔1秒钟向串口发送一个hello的程序等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!

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

原文地址: http://outofmemory.cn/zz/9849926.html

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

发表评论

登录后才能评论

评论列表(0条)

保存