实验目的:
甲机通过串口控制乙机 LED
甲单片机负责向外发送控制命令字符“A”、“B”、“C”,或者停止发送,乙机根据所接收到的字符完成 LED1 闪烁、LED2 闪烁、双闪烁、或停止闪烁
实验器材:
Protues、keil
实验原理(给出硬件电路图):
实验步骤:
- 原理分析
1.1串行通信使用配置
(1)设置T1的工作方式(编程TMOD寄存器)
(2)计算T1的初值,装载TH1、TL1
如果我们用9600波特率的
SMOD 通常不用到,如果给它赋予1或0,计数的波特率会翻倍,如果不使用,默认为0.
9600 = 11.0592 / 32* 12 * (256-T初)
得T初 = 253 = 0xfd
TH1 = 0xfd
TL1 = 0xfd
(3)启动T1(编程TCON中的TR1位)
TR1=1
(4)确定串行口控制(编程SCON寄存器)
程序代码及实验结果(含汇编语言代码和C语言代码):
甲机C语言:
/* 甲单片机负责向外发送控制命令字符“A”、“B”、“C”,或者停止发送,乙机根据所接收到的字符
完成 LED1 闪烁、LED2 闪烁、双闪烁、或停止闪烁。*/
#include<reg51.h>
//定义
sbit LED1=P0^0; //P0.0口控制LED1
sbit LED2=P0^3;//P0.3口控制LED3
sbit K1=P1^0; //P1.0口控制按键K1
//延时程序
void DelayMS(unsigned int ms)
{
unsigned char i;
while(ms--) for(i=0;i<120;i++);
}
//向串口发送字符
void Send( unsigned char C)
{
SBUF=C;//向SBUF(收发缓冲寄存器)写入字符“C”
//当数据发送完之后(TI==1),while语句不成立,跳出while,执行TI=0
while(TI==0);
TI=0; //软件清0
}
//主程序
void main()
{
unsigned char Data=0;
SCON=0x50; //SCON(定义串行口的工作方式),定义串行口工作在工作方式1(10位异步接收/发送),并且设置REN=1(允许数据的接收)
TMOD=0x20; //TMOD(定义定时器/计数器的工作方式),定义T1工作在工作方式2(8位定时器/计数器)
PCON=0x00; //PCON(串行口波特率倍增位)定义为0000 0000,波特率不倍增
//设置波特率,晶振频率是11.0592M,波特率9600
TH1=0xfd;//将宏计算的T1初值放到TH1中
TL1=0xfd;//将宏计算的T1初值放到TL1中
TI=0;//TI在发送数据前必须由软件清零
TR1=1;//启动T1开始计数
//一个死循环,实现功能
while(1)
{
//设置控制字符的变量
if(K1==0) //按下 K1 时选择操作代码 0,1,2,3
{
while(K1==0);
Data=(Data+1)%4; //对Data+1的值取4的余数,即取值范围在0-3之间的数,然后再把这个余数赋给Data变量
}
//switch语句判断Data的值
switch(Data) //根据操作代码发送 A/B/C 或停止发送
{
//停止闪烁
case 0: LED1=LED2=1;
break;
//LED1闪烁
case 1:Send('A');
LED1=~LED1;LED2=1;
break;
//LED2闪烁
case 2:Send('B');
LED2=~LED2;LED1=1;
break;
//双闪烁
case 3:Send('C');
LED1=~LED1;LED2=LED1;
break;
}
DelayMS(100);
}
}
甲机汇编语言:
; 甲单片机负责向外发送控制命令字符“A”、“B”、“C”,或者停止发送
KEY1 EQU P1.0 ;做等价替换使用
ORG 0000H
LJMP START
ORG 0030H
START: ;主程序开始
SETB EA ;打开总中断
SETB ET1;定时器1中断允许
MOV SCON ,#50H;设定串行口工作方式1,且准备接收信号
MOV TMOD,#20H;定时器1为工作方式2
MOV PCON ,#00H;保证 SMOD 为0,波特率不加倍
MOV TH1,#0FdH; 设定波特率
MOV TL1,#0FdH
SETB TR1;启动定时器1
MOV P0,#0FFH ;灯的起始状态为灭
MOV R5,#00H;用R5存放待发送的数,若为0则表示不发送
MOV R4,#00H;控制 LED 现象的标志变量
;判断按键是否按下
SCAN:
JB KEY1, LOOP ;K1=1,未按就跳转到灯灭的状态
LCALL DELAY;按键消抖
JB KEY1, LOOP ;K1=1,未按就跳转到灯灭的状态,按下则顺序执行
;R4实现加1的功能,执行不同的现象
D1:
MOV A,P1 ;此时开关已按下,P1=0FEH
CJNE A,#0FFH,D1 ;死循环,直到松开开关
INC R4 ;松开开关后R4加1
;全灭的状态
LOOP:
CJNE R4,#00H,LOOP1
MOV P0,#0FFH
LCALL DELAY
SJMP SCAN
;第一种状态:LED1亮
LOOP1:
CJNE R4,#01H,LOOP2
JNB KEY1,$;松手监测,key1=0,就向下执行
CLR P0.0;点亮LED1
LCALL DELAY;延时100
SETB P0.0;熄灭LED1
LCALL DELAY ;延时100ms
MOV R5,#'A';将 A ->R5
SJMP SEND ;发送
;第二种状态:LED2亮
LOOP2:
CJNE R4,#2,LOOP3
JNB KEY1,$;松手监测,k1=0,就向下执行
CLR P0.3;点亮LED2
LCALL DELAY;延时100ms
SETB P0.3;熄灭LED2
LCALL DELAY;延时100ms
MOV R5,#'B'
SJMP SEND ;发送
;LED1、LED2全亮
LOOP3:
CJNE R4,#3,LOOP4
JNB KEY1,$;松手监测,k1=0,就向下执行
CLR P0.0;点亮LED1
CLR P0.3;点亮LED2
LCALL DELAY;延时100ms
SETB P0.0 ;熄灭LED1
SETB P0.3 ;熄灭LED2
LCALL DELAY ;延时100ms
MOV R5,#'C'
SJMP SEND ;发送
LOOP4:
JNB KEY1,$;松手监测,k1=0,就向下执行
MOV R4,#0;控制 LED 变量归零
;判断是否发送完毕
SEND:
MOV SBUF ,R5 ;发送r5中的字符“A”“B”“C”
JNB TI ,$;等待发送完毕, TI 为1表示发送结束
CLR TI ;允许再发送,将 TI 位进行清零
;LCALL DELAY
SJMP SCAN;继续扫描按键
DELAY:
MOV R5,#0FFH
D2:
MOV R6,#0FFH
DJNZ R6,$ ;减1不为0则原地跳
DJNZ R5,D2
RET
RET
END
乙机C语言: 乙机汇编语言: | |
|