实验六 单片机串行口通讯实验
一、实验要求
利用单片机串行口,实现两个实验台之间的串行通讯。其中一个实验台作为发送方,另一侧为接收方。发送方读入按键值,并发送给接收方,接收方收到数据后在LED上显示。
二、实验目的
1、掌握单片机串行口工作方式的程序设计,及简易三线式通讯的方法。
2、了解实现串行通讯的硬环境、数据格式的协议、数据交换的协议。
3、学习串口通讯的中断方式的程序编写方法。
三、实验电路
显示电路和键盘电路见硬件实验十六和硬件实验十七。
四、实验说明
1、8051、80C196的RXD、TXD接线柱在POD51/96仿真板上,8088/86的TXD、RXD在POD8086仿真板上的8251芯片旁边。
2、通讯双方的RXD、TXD信号本应经过电平转换后再行交叉连接,本实验中为减少连线可将电平转换电路略去,而将双方的RXD、TXD直接交叉连接。也可以将本机的TXD接到RXD上,这样按下的键,就会在本机LED上显示出来。
3、若想与标准的RS232设备通信,就要做电平转换,输出时要将TTL电平换成RS232电平,输入时要将RS232电平换成TTL电平。可以将仿真板上的RXD、TXD信号接到实验板上的“用户串口接线”的相应RXD和TXD端,经过电平转换,通过“用户串口”接到外部的RS232设备。可以用实验仪上的逻辑分析仪采样串口通信的波形
五、实验框图
OUTBIT equ 08002h ; 位控制口
OUTSEG equ 08004h ; 段控制口
IN equ 08001h ; 键盘读入口
HasRcv equ 20h.0 ; 接收标志位
LEDBuf equ 40h ; 显示缓冲
RCVBuf equ 50H ; 接收缓冲
ORG 0000H
LJMP START
; 串行口中断程序
ORG 0023H
JNB TI,S0_R
CLR TI
NOP
SJMP S0_RET
S0_R: ; 接收数据
CLR RI
MOV RCVBUF,SBUF ; 保存数据
SETB HasRcv ; 提示收到数据
NOP
S0_RET:
RETI
LEDMAP: ; 八段管显示码
db 3fh, 06h, 5bh, 4fh, 66h, 6dh, 7dh, 07h
db 7fh, 6fh, 77h, 7ch, 39h, 5eh, 79h, 71h
Delay: ; 延时子程序
mov r7, #0
DelayLoop:
djnz r7, DelayLoop
djnz r6, DelayLoop
ret
DisplayLED:
mov r0, #LEDBuf
mov r1, #6 ; 共6个八段管
mov r2, #00100000b ; 从左边开始显示
Loop:
mov dptr, #OUTBIT
mov a, #0
movx @dptr, a ; 关所有八段管
mov a, @r0
mov dptr, #OUTSEG
movx @dptr,a
mov dptr, #OUTBIT
mov a, r2
movx @dptr, a ; 显示一位八段管
mov r6, #1
call Delay
mov a, r2 ; 显示下一位
rr a
mov r2, a
inc r0
djnz r1, Loop
ret
TestKey:
mov dptr, #OUTBIT
mov a, #0
movx @dptr, a ; 输出线置为0
mov dptr, #IN
movx a, @dptr ; 读入键状态
cpl a
anl a, #0fh ; 高四位不用
ret
KeyTable: ; 键码定义
db 16h, 15h, 14h, 0ffh
db 13h, 12h, 11h, 10h
db 0dh, 0ch, 0bh, 0ah
db 0eh, 03h, 06h, 09h
db 0fh, 02h, 05h, 08h
db 00h, 01h, 04h, 07h
GetKey:
mov dptr, #OUTBIT
mov P2, dph
mov r0, #Low(IN)
mov r1, #00100000b
mov r2, #6
KLoop:
mov a, r1 ; 找出键所在列
cpl a
movx @dptr, a
cpl a
rr a
mov r1, a ; 下一列
movx a, @r0
cpl a
anl a, #0fh
jnz Goon1 ; 该列有键入
djnz r2, KLoop
mov r2, #0ffh ; 没有键按下, 返回 0ffh
sjmp Exit
Goon1:
mov r1, a ; 键值 = 列 X 4 + 行
mov a, r2
dec a
rl a
rl a
mov r2, a ; r2 = (r2-1)*4
mov a, r1 ; r1中为读入的行值
mov r1, #4
LoopC:
rrc a ; 移位找出所在行
jc Exit
inc r2 ; r2 = r2+ 行值
djnz r1, LoopC
Exit:
mov a, r2 ; 取出键码
mov dptr, #KeyTable
movc a, @a+dptr
mov r2, a
WaitRelease:
mov dptr, #OUTBIT ; 等键释放
clr a
movx @dptr, a
mov r6, #10
call Delay
call TestKey
jnz WaitRelease
mov a, r2
ret
START:
MOV SP, #60H
MOV IE, #0 ; DISABLE ALL INTERRUPT
MOV TMOD,#020H ; 定时器1工作于方式2 (8位重装)
MOV TH1, #0F3H ; 波特率?2400BPS @ 12MHz
MOV TL1, #0F3H
ANL PCON,#07FH ; SMOD 位清零
orl PCON,#80h
MOV SCON,#050H ; 串行口工作方式设置
MOV LEDBuf, #0ffh ; 显示 8.8.8.8.
mov LEDBuf+1, #0ffh
mov LEDBuf+2, #0ffh
mov LEDBuf+3, #0ffh
mov LEDBuf+4, #0
mov LEDBuf+5, #0
SETB TR1
SETB ES
SETB EA
;mov sbuf,a
;jnb ti,$
MLoop:
jb HasRcv, RcvData ; 收到数据?
call DisplayLED ; 显示
call TestKey ; 有键入?
jz MLoop ; 无键入, 继续显示
call GetKey ; 读入键码
anl a, #0fh ; 通讯口输出键码
MOV SBUF,A
LJMP MLoop
RcvData:
clr HasRcv ; 是
mov a, RcvBuf ; 显示数据
mov b,a
anl a,#0fh ; 显示低位
mov dptr, #LEDMap
movc a, @a+dptr
mov LEDBuf+5, a
mov a,b
swap a ; 显示高位
anl a,#0fh
mov dptr, #LEDMap
movc a, @a+dptr
mov LEDBuf+4, a
ljmp MLoop
END
第二篇:实验6___串行口通讯实验
实验6 串行口通讯实验
学号 201017819 姓名 蔡鹏
实验目的
1、掌握单片机串行口工作方式的程序设计,及简易三线式通讯的方法。
2、了解实现串行通讯的硬环境、数据格式的协议、数据交换的协议。
3、学习串口通讯的中断方式的程序编写方法
实验内容
利用单片机串行口, 实现两个实验台之间的串行通讯。 其中一个实验台作为发送方,另一侧为接收方。发送方读入按键值,并发送给接收方,接收方收到数据后在LED上显示。
实验说明
1、8051的 RXD、TXD 接线柱在 POD51/96 仿真板上。
2、通讯双方的RXD、TXD信号本应经过电平转换后再行交叉连接,本实验中为减少连线可将电平转换电路略去,而将双方的 RXD、TXD 直接交叉连接。也可以将本机的 TXD接到 RXD上,这样按下的键,就会在本机LED上显示出来。
实验仪器和设备
计算机和LAB2000P实验箱。
所写程序和调试心得(请画出程序流程图和硬件连线图):
1. 程序流程图:
2. 硬件连线图:
3. 程序:
#include <reg51.h>
#define LEDLen 6
xdata unsigned char OUTBIT _at_ 0x8002; // 位控制口
xdata unsigned char OUTSEG _at_ 0x8004; // 段控制口
xdata unsigned char IN _at_ 0x8001; // 键盘读入口
unsigned char LEDBuf[LEDLen]; // 显示缓冲
unsigned char RcvBuf; // 接收缓冲
bit HasRcv = 0; // 接收标志
code unsigned char LEDMAP[] = { // 八段管显示码
0x3f, 0x06, 0x5b, 0x4f, 0x66, 0x6d, 0x7d, 0x07,
0x7f, 0x6f, 0x77, 0x7c, 0x39, 0x5e, 0x79, 0x71
};
void SerialIO0() interrupt 4
{
if(RI)
{
RI = 0;
RcvBuf = SBUF;
HasRcv = 1;
}else
{
TI = 0;
}
}
void Delay(unsigned char CNT)
{
unsigned char i;
while (CNT-- !=0)
for (i=100; i !=0; i--);
}
void DisplayLED()
{
unsigned char i, j;
unsigned char Pos;
unsigned char LED;
Pos = 0x20; // 从左边开始显示
for (i = 0; i < LEDLen; i++) {
OUTBIT = 0; // 关所有八段管
LED = LEDBuf[i];
OUTSEG = LED;
OUTBIT = Pos; // 显示一位八段管
Delay(1);
Pos >>= 1; // 显示下一位
}
}
code unsigned char KeyTable[] = { // 键码定义
0x16, 0x15, 0x14, 0xff,
0x13, 0x12, 0x11, 0x10,
0x0d, 0x0c, 0x0b, 0x0a,
0x0e, 0x03, 0x06, 0x09,
0x0f, 0x02, 0x05, 0x08,
0x00, 0x01, 0x04, 0x07
};
unsigned char TestKey()
{
OUTBIT = 0; // 输出线置为 0
return (~IN & 0x0f); // 读入键状态 (高四位不用)
}
unsigned char GetKey()
{
unsigned char Pos;
unsigned char i;
//unsigned char j;
unsigned char k;
i = 6;
Pos = 0x20; // 找出键所在列
do {
OUTBIT = ~ Pos;
Pos >>= 1;
k = ~IN & 0x0f;
} while ((--i != 0) && (k == 0));
// 键值 = 列 X 4 + 行
if (k != 0) {
i *= 4;
if (k & 2)
i += 1;
else if (k & 4)
i += 2;
else if (k & 8)
i += 3;
OUTBIT = 0;
do Delay(10); while (TestKey()); // 等键释放
return(KeyTable[i]); // 取出键码
} else return(0xff);
}
void main()
{
IE = 0x00; // DISABLE ALL INTERRUPT
TMOD = 0x20; // 定时器 1 工作于方式 2 (8 位重装)
TH1 = 0xF3; // 2400BPS @ 12MHz
TL1 = 0xF3;
PCON&= 0x7F; // SMOD 位清零
SCON = 0x50; // 串行口工作方式设置
LEDBuf[0] = 0xff;
LEDBuf[1] = 0xff;
LEDBuf[2] = 0xff;
LEDBuf[3] = 0xff;
LEDBuf[4] = 0x00;
LEDBuf[5] = 0x00;
TR1 = 1;
ES = 1;
EA = 1;
HasRcv = 0;
while (1) {
if(HasRcv){
LEDBuf[5] = LEDMAP[RcvBuf & 0x0f];
}
DisplayLED();
if (TestKey()) SBUF = GetKey();
}
}
实验心得
通过本次试验,了解了串行口工作的特点,掌握单片机串行口工作方式的程序设计,及简易三线式通讯的方法。 并了解实现串行通讯的硬环境、数据格式的协议、数据交换的协议。 而且基本掌握串口通讯的中断方式的程序编写方法