C51单片机串行口收发通信(没有板子,虚拟串口)
2025-09-23 来源:bilibili

因为是虚拟串口,所以需要创建虚拟串口。





自此虚拟串口添加完成。下面需要串口调试助手应用程序,有很多种的这种应用程序,我用的是

运行->调至“串口助手”窗口,设置其相应的串口(如:串口1、2相对应,这里先将串口助手设置com2,然后在proteus里设置COMPIM(模拟RS232端口)为com1),设置相应的波特率(这个大家可以网上查,一般设置是AT89C51的板子内的晶振频率为11.0592Mhz,对应的波特率为9600)。


至此,虚拟串口的创建,调试软件的运行已经准备就绪。下面根据相应的题目要求进行实验。我的实验要求一是

原理图界面:

双击AC89C51开发板设置晶振频率

晶振频率11.0592对应波特率9600,设置COMPIM波特率(有关晶振频率和波特率的运算请自行百度)


至此,设置完毕,hex文件我此前已经导入到AT89C51开发板了,所以直接调试看运行结果。

此要求是接收实验,PC串口助手接收单片机发来的按键字符,由仿真结果显示成功。
源码:
#include<reg51.h>
#include<intrins.h>
#define uchar unsigned char
#define uint unsigned int
uchar code table[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71,0x00};
//共阴极0-灭段码
int flag=0,flag2=0;
uchar Display_Buffer[]={16,16,16,16,16,16,' ',16};//设置显示数组初值为'灭'
void delay(uint z) //延时子函数
{
uint x,y;
for(x=z;x>0;x--)
for(y=110;y>0;y--);
}
void UART_Send_Data(char byte)
{
SBUF=byte;
while(!TI);//等待串口数据发送完毕
TI=0;//将发送中断标志位清0,为下次发送数据做准备
}
uchar kscan() //扫描函数
{
uchar i,temp,num=16;
for(i=0;i<4;i++)
{
P1=_crol_(0xfe,i);//逐列扫描
temp=P3;
temp=temp&0xf0;
if(temp!=0xf0)
{
delay(20);
temp=P3;
temp=temp&0xf0;
if(temp!=0xf0)
{
temp=(P1&0x0f)|(P3&0xf0);
switch(temp)
{
case 0xe7:num=0;break;
case 0xeb:num=4;break;
case 0xed:num=8;break;
case 0xee:num=12;break;
case 0xd7:num=1;break;
case 0xdb:num=5;break;
case 0xdd:num=9;break;
case 0xde:num=13;break;
case 0xb7:num=2;break;
case 0xbb:num=6;break;
case 0xbd:num=10;break;
case 0xbe:num=14;break;
case 0x77:num=3;break;
case 0x7b:num=7;break;
case 0x7d:num=11;break;
case 0x7e:num=15;break;
default:break;
}
while((temp&0xf0)!=0xf0)//等待按键释放
{
temp=P3;
}
}
}
}
flag=1;
return num;
}
void init_com(void)
{
SCON = 0x50; // SCON: 方式 1, 8-bit, 允许接收数据
TMOD |= 0x20; // TMOD: 设置定时器1工作在方式2, 8-bit 自动重装
TH1 = 0xFD; // TH1: 初始值为0xFD 波特率:9600 晶振频率:11.0592MHz
TL1 = 0x0;
TR1 = 1; // TR1: 开启定时器1
EA = 1; //打开总中断
ES = 1; //打开串口中断
}
void main()
{
int k,m=0x7f;
uchar num;
P0=0x00;//关闭数码管的段选
P2=0xff;//关闭数码管的位选
init_com();
while(1)
{
num=kscan();
if(num!=16)
{
for(k=1;k<8;k++)
{
Display_Buffer[k-1]=Display_Buffer[k];//显示向前移动一位
}
Display_Buffer[7]=num; //显示数组最后赋扫描到按下的键的值
flag2++;
if(flag==1&&flag2!=1)
{
flag=0;
if(Display_Buffer[6]>=0&&Display_Buffer[6]<=9)
UART_Send_Data(Display_Buffer[6]+'0');
else
UART_Send_Data(Display_Buffer[6]+55);
}
delay(2);
num=16;
}
for(k=0;k<8;k++)
{
m=_crol_(m,1); //m左移1位
P2=m; //给P2口输入
P0=table[Display_Buffer[k]]; // 将扫描到的值转换为码段值输入给P0口
delay(2);
}
}
}
要求二:

频率和波特率还有串口同上。
原理图:

此前已导入hex文件,直接调试看仿真结果。

因为是串行口,发送和接收都是一个一个字符。由仿真结果知,实验成功。
源码:
#include<reg51.h>
#include<intrins.h>
#define uchar unsigned char
#define uint unsigned int
uchar code table[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71,0x00};//共阴极码段
uchar Display_Buffer[]={16,16,16,16,16,16,16,16};
uchar flag;
uchar c;
void delay(uint z)
{
uint x,y;
for(x=z;x>0;x--)
for(y=110;y>0;y--);
}
void init_uart(void)
{
SCON = 0x50; // SCON: 方式 1, 8-bit, 允许接收数据
TMOD |= 0x20; // TMOD: 设置定时器1工作在方式2, 8-bit 自动重装
TH1 = 0xFD; // TH1: 初始值为0xFD 波特率:9600 晶振频率:11.0592MHz
TL1 = 0x0;
TR1 = 1; // TR1: 开启定时器1
EA = 1; //打开总中断
ES = 1; //打开串口中断
}
void Serial_INT() interrupt 4 //串口中断处理函数 (串口接收到数据,发送数据完毕都可以引起串口中断)
{
if(RI==0)
return;
ES = 0;
RI = 0;
c=SBUF;
if(c>='0' && c<='9') //编码格式转换
{
c=c-'0';
}
else
c=c-55;
flag=1;
ES=1;
}
void main()
{
int k,m=0xfe,num=0;
P0=0x00;//关闭数码管的段选
P2=0xff;//关闭数码管的位选
init_uart();
while(1)
{
if(flag)
{
flag=0;
for(k=1;k<8;k++)
{
Display_Buffer[k-1]=Display_Buffer[k];//显示向前移动一位
}
Display_Buffer[7]=c;
}
for(k=0;k<8;k++) //控制P2口位显示和P0口段码显示
{
m=_cror_(m,1);
P2=m;
P0=table[Display_Buffer[k]];
delay(2);
}
}
}
- 六大全新产品系列推出,MCX A微控制器家族迎来创新
- 意法半导体全新STM32C5系列,重新定义入门级微控制器性能与价值,赋能万千智能设备
- 从控制到系统:TI利用边缘AI重塑嵌入式MCU的边界
- 模组复用与整机重测在SRRC、CCC、CTA/NAL认证中的实践操作指南
- 有源晶振与无源晶振的六大区别详解
- 英飞凌持续巩固全球微控制器市场领导地位
- 使用 Keil Studio for Visual Studio Code开发 STM32 设备
- 蓝牙信道探测技术原理与开发套件实践
- Microchip 推出生产就绪型全栈边缘 AI 解决方案,赋能MCU和MPU实现 智能实时决策
- LoRa、LoRaWAN、NB-IoT与4G DTU技术对比及工业无线方案选型分析




