实现功能:51单片机与电脑串口通信,电脑给单片机发送一个字符,单片机收到以后在数码管上进行显示,并且将此字符返回给电脑程序对应的电路图:
方法1,开启串口中断。
补充说明:电脑和单片机串口通信时,数据是以ASCII码形式存在的,所以在操作的 时候应该注意格式的问题,
(1)如果在串口助手中,以文本形式发送数据的话,单片机接收到的是相应的ASCII码,例如你写的是数字3,那么单片机接收到的却是3的ASCII码(对应:51),如果没有相应的转换的话,就会出错。此时就必须进行相应的转换才能正确显示,具体可应用switch case语句,进行查表(下面代码里有说明);
(2)如果在串口助手中,如果以16进制形式发送,,你发送的是什么,单片机接收到的就是什么,无需转换。
代码如下:
/*==========================================================
* 开发人员:laowang
* 当前版本:V1.0
* 创建时间:11/30/2013
* 修改时间:
* 功能说明:电脑通过串口助手给单片机发送字符,单片机接收到以后,在数码管上进行相应的显示
同时返给电脑一个字符串:“X"(X为电脑发给单片机的字符)
*==========================================================*/
#include //头文件
#include"Define.h" //包含宏定义的头文件
uchar a;
uchar flag;
***it wela=P3^5;
***it dula=P3^4;
uchar code table1[]="I receive ";
uchar code table2[]= //数码管编码0-F,共阴;
{
0x3f,0x06,0x5b,0x4f,
0x66,0x6d,0x7d,0x07,
0x7f,0x6f,0x77,0x7c,
0x39,0x5e,0x79,0x71
};
/*==========================================================
*函数名称:Init()
*功 能:串口初始化函数
*入口参数:
*出口参数:void
*说 明:第一步:设置定时器;第二部设置串口;第三部,设置中断
*==========================================================*/
void Init()
{
TMOD=0x20; //0010 0000 定时器1,工作方式2
TH1=0xfd; //初值,根据波特率的计算公式,备注晶振频率11.0592Mhz
TL1=0xfd;
TR1=1; //开始定时器计数,此处没必要开始定时器中断,开了中断没事做
REN=1; //允许串口接收
SM0=0; //串口工作方式1
SM1=1;
EA=1; //开总中断
ES=1; //开启串口中断
}
//主函数
void main()
{
P1=0; //对数码管进行初始设置,刚开始均不亮
wela=1;
wela=0;
dula=1;
dula=0;
Init(); //初始化
while(1)
{
if(flag==1) //说明接收到了数据
{
flag=0;
ES=0; //关闭中断
SBUF=a; //将接收到的数据发送
while(!ti);
TI=0; //重新开启中断
ES=1;
}
/***************************************************
switch(a) //备注:如果在串口助手中,以文本形式发送的话,单片机接收到的是相应的ASCII码
{ //此时就必须进行相应的转换才能正确显示;如果以16进制形式发送,则不需要这一部分
case '0':P1=table2[0];break;
case '1':P1=table2[1];break;
case '2':P1=table2[2];break;
case '3':P1=table2[3];break;
case '4':P1=table2[4];break;
case '5':P1=table2[5];break;
case '6':P1=table2[6];break;
case '7':P1=table2[7];break;
case '8':P1=table2[8];break;
case '9':P1=table2[9];break;
case 'a':P1=table2[10];break;
case 'b':P1=table2[11];break;
case 'c':P1=table2[12];break;
case 'd':P1=table2[13];break;
case 'e':P1=table2[14];break;
case 'f':P1=table2[15];break;
}
*************************************************************************/
P1=table2[a]; //将电脑发送来的数据传给P1
dula=1; //这一部分为数码管的显示的部分
dula=0;
P1=0x00; //八个全亮
wela=1;
wela=0;
}
}
//中断服务函数
void Serial() interrupt 4
{
flag=1;
RI=0;
a=SBUF;
}
方法2.不开启中断
代码如下:
/*==========================================================
* 开发人员:laowang
* 当前版本:V1.0
* 创建时间:12/1/2013
* 修改时间:
* 功能说明:电脑通过串口助手给单片机发送字符,单片机接收到以后,在数码管上进行相应的显示
同时返给电脑一个字符串:“X"(X为电脑发给单片机的字符)
*==========================================================*/
#include //头文件
#include"Define.h" //包含宏定义的头文件
uchar a;
***it wela=P3^5;
***it dula=P3^4;
uchar code table[]= //数码管编码0-F,共阴;
{
0x3f,0x06,0x5b,0x4f,
0x66,0x6d,0x7d,0x07,
0x7f,0x6f,0x77,0x7c,
0x39,0x5e,0x79,0x71
};
/*==========================================================
*函数名称:Init()
*功 能:串口初始化函数
*入口参数:
*出口参数:void
*说 明:第一步:设置定时器;第二部设置串口
此处没开中断
*==========================================================*/
void Init()
{
TMOD=0x20; //0010 0000 定时器1,工作方式2
TH1=0xfd; //初值,根据波特率的计算公式,备注晶振频率11.0592Mhz
TL1=0xfd;
TR1=1; //开始定时器计数,此处没必要开始定时器中断,开了中断没事做
REN=1; //允许串口接收
SM0=0; //串口工作方式1
SM1=1;
}
//主函数
void main()
{
P1=0; //对数码管进行初始设置,刚开始均不亮
wela=1;
wela=0;
dula=1;
dula=0;
Init(); //初始化
while(1)
{
while(RI==0); //程序一开始等待等待接受数据,当接收到数据后,RI=1,跳出循环,然后将RI置0
RI=0;
a=SBUF; //将接收到的数据送给a
SBUF=a; //将接收到的数据发送
while(!TI); //等待数据发送,一旦发送完毕,TI=1.
TI=0;
P1=table[a]; //将电脑发送来的数据传给P1
dula=1; //这一部分为数码管的显示的部分
dula=0;
P1=0x00; //八个全亮
wela=1;
wela=0;
}
}
方法1,源代码:
方法2,源代码:
|