800个电子设计项目分享解析含源码 帮助小白学嵌入式 从入门到年薪50万
笔者电子信息专业硕士毕业,获得过多次电子设计大赛、大学生智能车、数学建模国奖,现就职于南京某半导体芯片公司,从事与硬件设计,电路设计研究。对于学电子的小伙伴,深知入门的不易,特开次博客交流分享经验,共同互勉!全套资料领取扫描文末二维码!
温馨提示:学而不思则罔,思而不学则殆。实践是检验真理的唯一标准!
实验任务
单片机串口通信的应用,通过串口,我们的个人电脑和单片机系统进行通信。个人电脑作为上位机,向下位机单片机系统发送十六进制或者ASCLL码,单片机系统接收后,用LED显示接收到的数据和向上位机发回原样数据。
一、实验原理
RS-232是美国电子工业协会正式公布的串行总线标准,也是目前最常用的串行接口标准,用来实现计算机与计算机之间、计算机与外设之间的数据通讯。
RS-232串行接口总线适用于:设备之间的通讯距离不大于15m,传输速率最大为20kBps。
RS-232协议以-5V-15V表示逻辑1;以+5V-15V 表示逻辑0。 我们是用MAX232芯片将RS232电平转换为TTL电平的。 一个完整的RS-232接口有22根线,采用标准的25芯插头座。我们在 这里使用的是简化的9芯插头座。
注意我们在这里使用的晶振是11.0592M的,而不是12M。因为波特率的设置需要11.0592M的。
“串口调试助手V2.1.exe” 软件的使用很简单,只要将串口选择‘CMO1’波特率设置为‘9600’ 数据位为 8 位。打开串口(如果关闭)。然后在发送区里输入要发送的数据,单击手动发送就将数据发送出去了。注意,如果选中‘十六进制发送’那么发送的数据是十六进制的,必须输入两位数据。如果没有选中,则发送的是ASCLL码,那么单片机控制的数码管将显示ASCLL码值。单片机Px0~Px7引脚5V高电平上拉。
数字 | 二进制 | 引脚Px0~Px7 | 数码管Abcdefg p | 十六进制 |
0 | 00111111 | 00000011 | 11111100 | 0xco |
1 | 00000110 | 10011111 | 01100000 | 0xf9 |
2 | 01011011 | 00100101 | 11011010 | 0xa4 |
3 | 01001111 | 00001101 | 11110010 | 0xb0 |
4 | 00110110 | 10010011 | 01101100 | 0x99 |
5 | 01101101 | 01001001 | 10110110 | 0x92 |
6 | 01111101 | 01000001 | 10111110 | 0x82 |
7 | 00000111 | 00011111 | 11100000 | 0xf8 |
8 | 01111111 | 00000001 | 11111110 | 0x80 |
9 | 01101111 | 00001001 | 11110110 | 0x90 |
A | 01110111 | 00010001 | 11101110 | 0x88 |
B | 01111100 | 11000001 | 00111110 | 0x83 |
C | 00111001 | 01100011 | 10011100 | 0xc6 |
D | 01011110 | 10000101 | 01111010 | 0xa1 |
E | 01111001 | 01100001 | 10011110 | 0x86 |
F | 01110001 | 01110001 | 10001110 | 0x8e |
代码 | 字符 | 代码 | 字符 | 代码 | 字符 | 代码 | 字符 | 代码 | 字符 |
32 | 52 | 4 | 72 | H | 92 | \ | 112 | p | |
33 | ! | 53 | 5 | 73 | I | 93 | ] | 113 | q |
34 | ” | 54 | 6 | 74 | J | 94 | ^ | 114 | r |
35 | # | 55 | 7 | 75 | K | 95 | _ | 115 | s |
36 | $ | 56 | 8 | 76 | L | 96 | ` | 116 | t |
37 | % | 57 | 9 | 77 | M | 97 | a | 117 | u |
38 | & | 58 | : | 78 | N | 98 | b | 118 | v |
39 | ’ | 59 | ; | 79 | O | 99 | c | 119 | w |
40 | ( | 60 | < | 80 | P | 100 | d | 120 | x |
41 | ) | 61 | = | 81 | Q | 101 | e | 121 | y |
42 | * | 62 | > | 82 | R | 102 | f | 122 | z |
43 | + | 63 | ? | 83 | S | 103 | g | 123 | { |
44 | , | 64 | @ | 84 | T | 104 | h | 124 | | |
45 | - | 65 | A | 85 | U | 105 | i | 125 | } |
46 | . | 66 | B | 86 | V | 106 | j | 126 | ~ |
47 | / | 67 | C | 87 | W | 107 | k | ||
48 | 0 | 68 | D | 88 | X | 108 | l | ||
49 | 1 | 69 | E | 89 | Y | 109 | m | ||
50 | 2 | 70 | F | 90 | Z | 110 | n | ||
51 | 3 | 71 | G | 91 | [ | 111 | o |
二、单片机程序源码
1.主函数C
代码如下(示例):
#include "reg52.h" //包函8051 内部资源的定义
unsigned char dat; //用于存储单片机接收发送缓冲寄存器SBUF里面的内容
sbit gewei=P2^4; //个位选通定义
sbit shiwei=P2^5; //十位选通定义
sbit baiwei=P2^6; //百位选通定义
unsigned char code table[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,}; //1~10
void Delay(unsigned int tc) //延时程序
{
while( tc != 0 )
{unsigned int i;
for(i=0; i<100; i++);
tc--;}
}
void LED() //LED显示接收到的数据(十进制)
{
gewei=0; P0=table[dat%10]; Delay(10); gewei=1;
shiwei=0; P0=table[dat/10]; Delay(10); shiwei=1;
baiwei=0; P0=table[dat/100]; Delay(10); baiwei=1;
}
///功能:串口初始化,波特率9600,方式1/
void Init_Com(void)
{
TMOD = 0x20;
PCON = 0x00;
SCON = 0x50;
TH1 = 0xFd;
TL1 = 0xFd;
TR1 = 1;
}
/主程序功能:实现接收数据并把接收到的数据原样发送回去///
void main()
{
Init_Com();//串口初始化
while(1)
{
if ( RI ) //扫描判断是否接收到数据,
{
dat = SBUF; //接收数据SBUF赋与dat
RI=0; //RI 清零。
SBUF = dat; //在原样把数据发送回去(接收数据为发送数据的ASCII码,如发送q显示为113)
}
LED(); //显示接收到的数据
}
}
///这一个例子是以扫描的方式编写的,还可以以中断的方式编写,请大家思考//
2.PC控制单片机IO口输出
代码如下(示例):
#include "reg52.h" //包函8051 内部资源的定义
unsigned char dat; //用于存储单片机接收发送缓冲寄存器SBUF里面的内容
void Delay(unsigned int tc) //延时程序
{
while( tc != 0 )
{
unsigned int i;
for(i=0; i<100; i++);
tc--;
}
}
///功能:串口初始化,波特率9600,方式1/
void Init_Com(void)
{
TMOD = 0x20;
PCON = 0x00;
SCON = 0x50;
TH1 = 0xFd;
TL1 = 0xFd;
TR1 = 1;
}
/主程序功能:实现接收数据并把接收到的数据原样发送回去///
void main()
{
Init_Com();//串口初始化
while(1)
{
if ( RI ) //扫描判断是否接收到数据,
{
dat = SBUF; //接收数据SBUF赋与dat
if(dat==0x00) //如果PC发送十六进制00,单片机P1口全亮。
P1=0x00;
else if(dat==0x01)
P1=0x01;
else if(dat==0x02)
P1=0x02;
else if(dat==0x03)
P1=0x03;
else if(dat==0x04)
P1=0x04;
RI=0; //RI 清零。
SBUF = dat; //在原样把数据发送回去(接收数据为发送数据的ASCII码,如发送q显示为113)
}
}
}
3.PC机给单片机发送数据
代码如下(示例):
#include "reg52.h" //包函8051 内部资源的定义
unsigned char dat; //用于存储单片机接收发送缓冲寄存器SBUF里面的内容
unsigned char fan;
int i,j;
void Delay() //延时程序
{
for(i=0; i<100; i++)
for(j=0; j<100; j++);
}
void delays()
{
int k;
for (k=0;k<1200;k++);
}
///功能:串口初始化,波特率9600,方式1/
void Init_Com(void)
{
TMOD = 0x20;
PCON = 0x00;
SCON = 0x50;
TH1 = 0xFd;
TL1 = 0xFd;
TR1 = 1;
}
/主程序功能:实现接收数据并把接收到的数据原样发送回去///
void main()
{
Init_Com();//串口初始化
while(1)
{
if ( RI ) //扫描判断是否接收到数据,
{
dat = SBUF; //接收数据SBUF赋与dat
if(dat==0x30) //如果PC发送十六进制00,单片机P1口全亮。
{
P1=0x00;
Delay();
}
else if(dat==0x31)
{P1=0x01;
Delay();}
else if(dat==0x32)
{P1=0x03;
Delay();}
else if(dat==0x33)
{P1=0x07;
Delay(); }
else if(dat==0x34)
{P1=0x0f;
Delay(); }
else if(dat==0x35)
{P1=0x1f;
Delay();}
else if(dat==0x06)
{P1=0x3f;
Delay(); }
else if(dat==0x07)
{P1=0x7f;
Delay();}
else if(dat==0x08)
{P1=0xff;
Delay(); }
else if(!(P2&0x01))
{ delays();
while(!(P2&0x01));
fan = 0x36;}
else if(!(P2&0x02))
{ delays();
while(!(P2&0x02));
fan = 0x37;}
else if(!(P2&0x04))
{ delays();
while(!(P2&0x04));
fan = 0x38;}
else if(!(P2&0x08))
{ delays();
RI=0; //RI 清零。
SBUF =dat; //在原样把数据发送回去(接收数据为发送数据的ASCII码,如发送q显示为113)
}
}
}
回复【更多资料】海量嵌入式资料赠送
笔者电子信息专业硕士毕业,获得过多次电子设计大赛、大学生智能车、数学建模国奖,现就职于南京某半导体芯片公司,从事与硬件设计,电路设计研究。对于学电子的小伙伴,深知入门的不易,特开次博客交流分享经验,共同互勉!