注意,接收方的波特率必须和发送方的波特率相同!
接受放REN=1
中断服务程序请中断肯定是请RI
我手头没有陈老师的课程资料,程序要自己慢慢输入:
//$include (../comm/AI8051U.INC)
$INCLUDE (AI8051U.INC) ;包含AI8051U单片机的寄存器定义文件
ADDRT EQU 1000H
ORG0000H
LJMP MAINT ;跳至主程序入口
ORG0023H
LJMP UART1_ISR ;转至串行中断服务程序
MAINT: MOV SP, #80H ;设置堆栈指针
MOV SCON, #50H ;8位数据,可变波特率
ANL AUXR, #0FEH ;串口1选择定时器1为波特率发生器
ANL TMOD, #0FH ;设定定时器1为16位自动重装方式
MOV TL1, #0E8H ;设定定时初值
MOV TH1, #0FFH ;设定定时初值
CLR ET1 ;禁止定时器1中断
SETB TR1 ;启动定时器1
SETB ES ;串行口开中断
SETB EA ;开总中断
MOV DPTR,#ADDRT ;ADDRT是首址,可以使用EQU定义
MOV R0,#00H ;传送字节数初值
MOVX A,@DPTR ;取第一个发送字节
MOV SBUF,A ;启动串行口发送
SJMP $ ;等待中断
;中断服务程序
UART1_ISR:CLR TI ;将中断标志清零
CJNE R0,#7FH,LOOPT ;判断128B是否发送完,若没完,则转LOOPT
CLR ES ;全部发送完毕,禁止串行口中断
LJMP ENDT ;转中断返回
LOOPT: INC R0 ;修改字节数指针
INC DPTR ;修改地址指针,继续取下一发送数据
MOVX A,@DPTR ;取发送数据
MOV SBUF,A ;启动串行口
ENDT: RETI ;中断返回
END
下面是C语言对应的程序:
#include <AI8051U.H>
unsigned char xdata ADDRT; //在外部RAM区定义128个单元
unsigned char num=0; //声明计数变量
unsigned char xdata *psend; //指向发送数据区的指针
void main(void) //主程序,在C语言的主程序中可以不设置堆栈指针
{
SCON=0x40; //8位数据,可变波特率
AUXR &= 0xFE; //串口1选择定时器1为波特率发生器
TMOD &= 0x0F; //设定定时器1为16位自动重装方式
TL1 = 0xE8; //设定定时初值
TH1 = 0xFF; //设定定时初值
TR1 = 1; //启动定时器1
ES=1; //串行口开中断
psend = ADDRT; //设置发送数据缓冲区指针
EA=1; //开中断
psend=ADDRT; //设置发送数据缓冲区指针
SBUF = *psend; //发送第一个数据
while(1); //等待中断
}
void UART1_ISR(void) interruptUART1_VECTOR//串口1中断服务函数
{
TI = 0; //清发送中断标志
num++; //修改计数变量值
if(num==0x7F)
ES=0; //判断是否发送完,若已完,则关中断
else
{
psend++; //否则,修改指针,发送下一个数据
SBUF= *psend;
}
}
接收方的汇编源程序:
我们也只能慢慢输入:
//$include (../comm/AI8051U.INC)
$INCLUDE (AI8051U.INC) ;包含AI8051U单片机的寄存器定义文件
ADDRT EQU 1000H
ORG0000H
LJMP MAINT ;跳至主程序入口
ORG0023H
LJMP UART1_ISR ;转至串行中断服务程序
ORG0200H
MAINT: MOV SP, #80H ;设置堆栈指针
MOV SCON, #50H ;8位数据,可变波特率
ANL AUXR, #0FEH ;串口1选择定时器1为波特率发生器
ANL TMOD, #0FH ;设定定时器1为16位自动重装方式
MOV TL1, #0E8H ;设定定时初值
MOV TH1, #0FFH ;设定定时初值
CLR ET1 ;禁止定时器1中断
SETB TR1 ;启动定时器1
SETB ES ;串行口开中断
SETB EA ;开总中断
MOV DPTR,#ADDRT ;ADDRT是首址,可以使用EQU定义
MOV R0,#00H ;传送字节数初值
MOVX A,@DPTR ;取第一个发送字节
MOV SBUF,A ;启动串行口发送
SJMP $ ;等待中断
;中断服务程序
UART1_ISR:CLR RI ;接收中断标志清零
MOV A,SBUF ;取接收的数据
MOVX @DPTR,A ;接收的数据送缓冲区
CJNE R0,#7FH,LOOPR ;判断128B是否接收完,若没完,则转LOOPR
CLR ES ;全部接收完毕,禁止串行口中断
LJMP ENDR ;转中断返回
LOOPR: INC R0 ;修改字节数指针
INC DPTR ;修改地址指针,继续取下一发送数据
ENDR: RETI ;中断返回
END
对应的C语言接收源程序:
#include <AI8051U.H>
unsigned char xdata ADDRT; //在外部RAM区定义128个单元
unsigned char num=0; //声明计数变量
unsigned char xdata *prcc; //指向接收数据区的指针
void main(void) //主程序,在C语言的主程序中可以不设置堆栈指针
{
SCON=0x50; //8位数据,可变波特率
AUXR &= 0xFE; //串口1选择定时器1为波特率发生器
TMOD &= 0x0F; //设定定时器1为16位自动重装方式
TL1 = 0xE8; //设定定时初值
TH1 = 0xFF; //设定定时初值
ET1 = 0; //禁止定时器1中断
TR1 = 1; //启动定时器1
ES=1; //串行口开中断
EA=1; //开中断
prcc = ADDRT; //设置发送数据缓冲区指针
while(1); //等待中断
}
void UART1_ISR(void) interruptUART1_VECTOR//串口1中断服务函数
{
RI = 0; //清接收中断标志
num++; //修改计数变量值
if(num==0x7F)
ES=0; //判断是否接收完,若已完,则关中断
else
{
*prcc = SBUF ;
prcc++; //修改指针,接收下一个数据
}
}
接下来我们看看下一个内容:
串口2 的使用实际例子:
还有多机通信的问题:
多机通信的时候,主机发送地址后,要等待从机的回应
回应之后,再发送数据............
从机:接收主机发来的地址帧信息,并与本机的地址号相比较,若不符合,仍保持SM2=1不变;若相等,则使SM2清零,准备接收后续的数据信息,直至接收完10个数据信息。