51单片机串口通信相关例程.docx

上传人:b****8 文档编号:11004660 上传时间:2023-02-24 格式:DOCX 页数:35 大小:152.16KB
下载 相关 举报
51单片机串口通信相关例程.docx_第1页
第1页 / 共35页
51单片机串口通信相关例程.docx_第2页
第2页 / 共35页
51单片机串口通信相关例程.docx_第3页
第3页 / 共35页
51单片机串口通信相关例程.docx_第4页
第4页 / 共35页
51单片机串口通信相关例程.docx_第5页
第5页 / 共35页
点击查看更多>>
下载资源
资源描述

51单片机串口通信相关例程.docx

《51单片机串口通信相关例程.docx》由会员分享,可在线阅读,更多相关《51单片机串口通信相关例程.docx(35页珍藏版)》请在冰豆网上搜索。

51单片机串口通信相关例程.docx

51单片机串口通信相关例程

51单片机串口通信

1./*打开串口调试程序,将波特率设置为9600,无奇偶校验

晶振11.0592MHz,发送和接收使用的格式相同,如都使用

字符型格式,在发送框输入hello,ILoveMCU,在接

收框中同样可以看到相同字符,说明设置和通信正确*/

#include

/*主程序*/

voidmain(void)

{

SCON=0x50;/*SCON:

模式1,8-bitUART,使能接收*/

TMOD|=0x20;/*TMOD:

timer1,mode2,

8-bitreload*/

TH1=0xFD;/*TH1:

reloadvaluefor9600baud@11.0592MHz*/

TR1=1;/*TR1:

timer1run*/

EA=1;/*打开总中断*/

ES=1;/*打开串口中断*/

while

(1)/*主循环不做任何动作*/

{

}

}

voidUART_SER(void)interrupt4//串行中断服务程序

{

unsignedcharTemp;//定义临时变量

if(RI)//判断是接收中断产生

{

RI=0;//标志位清零

Temp=SBUF;//读入缓冲区的值

P1=Temp;//把值输出到P1口,用于观察

SBUF=Temp;//把接收到的值再发回电脑端

}

if(TI)//如果是发送标志位,清零

TI=0;

}

2.51单片机与电脑串口通信的C程序,最好是中断方式的

#include

#include

unsignedcharch;

bitread_flag=0;

voidinit_serialcom(void)//串口通信初始设定

{

SCON=0x50;//UART为模式1,8位数据,

允许接收

TMOD|=0x20;//定时器1为模式2,8位自动重装

PCON|=0x80;//SMOD=1;

TH1=0xFD;//Baud:

19200fosc="11".0592MHz

IE|=0x90;//EnableSerialInterrupt

TR1=1;//timer1run

TI=1;

}

//向串口发送一个字符

voidsend_char_com(unsignedcharch)

{

SBUF=ch;

while(TI==0);

TI=0;

}

voidserial()interrupt4using3//串口接收中断函数

{

if(RI)

{

RI=0;

ch=SBUF;

read_flag=1;//就置位取数标志

}

}

main()

{

init_serialcom();//初始化串口

while

(1)

{

if(read_flag)//如果取数标志已置位,就将读到的数从串口发出

{

read_flag=0;//取数标志清0send_char_com(ch);

}

}

}

3.//单片机串行口发送/接收程序,每接收到字节即发送出去

//和微机相接后键入的字符回显示在屏幕上

//可用此程序测试

#include

#defineXTAL11059200//CUP晶振频率

#definebaudrate9600//通信波特率

voidmain(void)

{

unsignedcharc;

TMOD=0x20;//定时器1工作于8位自动重载模式,用于产生波特率

TH1=(unsignedchar)(256-(XTAL/(32L*12L*baudrate)));

TL1=(unsignedchar)(256-(XTAL/(32L*12L*baudrate)));//定时器0赋初值

SCON=0x50;

PCON=0x00;

TR1=1;

IE=0x00;//禁止任何中断

while

(1)

{

while(RI==0);

RI=0;

c=SBUF;//从缓冲区中把接收的字符放入c中

SBUF=c;//要发送的字符放入缓冲区

while(TI==0);

TI=0;

}

}

4./////////////////////////////////////////////////////////////////////////

//E51Pro.c

//Easy51Pro编程器主程序,负责通讯,管理编程操作

/////////////////////////////////////////////////////////////////////////

#include

BYTEComBuf[18];//串口通讯数据缓存,发送和接收都使用

UINTnAddress;//ROM中地址计数

UINTnTimeOut;//超时计数

ProWorkpw;//编程器一般操作

voidDelay_us(BYTEnUs)//微秒级延时<255us

{

TH0=0;

TL0=0;

TR0=1;

while(TL0

{

}

TR0=0;

}

voidDelay_ms(UINTnMs)//豪秒级的延时<65535ms

{

UINTn=0;

TR0=1;

while(n

{

TH0=0;

TL0=20;

while(TH0<4)

{

}

n++;

}

TR0=0;

}

BOOLWaitComm()//等待上位机的命令,18字节

{

BYTEn=0;

RI=0;

while(!

RI){}//等待第一个字节

ComBuf[n]=SBUF;

RI=0;

n++;

for(n;n<=17;n++)

{

nTimeOut=0;

while(!

RI)

{

nTimeOut++;

if(nTimeOut>10000)//后17个字节都有超时限制

return0;

}

ComBuf[n]=SBUF;

RI=0;

}

return1;

}

BOOLWaitResp()//等待上位机回应,1字节,有超时限制

{

nTimeOut=0;

RI=0;

while(!

RI)

{

nTimeOut++;

if(nTimeOut>50000)

{

return0;

}

}

RI=0;

ComBuf[0]=SBUF;

return1;

}

BOOLWaitData()//写器件时等待上位机数据,18字节,有超时限制

{

BYTEn;

RI=0;

for(n=0;n<=17;n++)

{

nTimeOut=0;

while(!

RI)

{

nTimeOut++;

if(nTimeOut>10000)

{

return0;

}

}

RI=0;

ComBuf[n]=SBUF;

}

return1;

}

voidSendData()//发送数据或回应操作完成,18字节

{

BYTEn=0;

for(n;n<=17;n++)

{

TI=0;

SBUF=ComBuf[n];

while(!

TI){}

TI=0;

}

}

voidSendResp()//回应上位机1个字节,在写器件函数中使用

{

TI=0;

SBUF=ComBuf[0];

while(!

TI){}

TI=0;

}

voidSetVpp5V()//设置Vpp为5v

{

P3_4=0;

P3_3=0;

}

voidSetVpp0V()//设置Vpp为0v

{

P3_3=0;

P3_4=1;

}

voidSetVpp12V()//设置Vpp为12v

{

P3_4=0;

P3_3=1;

}

voidRstPro()//编程器复位

{

pw.fpProOver();//直接编程结束

SendData();//通知上位机,表示编程器就绪,可以直接用此函数因为协议号(ComBuf[0])还没被修改,下同

}

voidReadSign()//读特征字

{

pw.fpReadSign();

SendData();//通知上位机,送出读出器件特征字

}

voidErase()//擦除器件

{

pw.fpErase();

SendData();//通知上位机,擦除了器件

}

voidWrite()//写器件

{

BYTEn;

pw.fpInitPro();//编程前的准备工作

SendData();//回应上位机表示进入写器件状态,

可以发来数据

while

(1)

{

if(WaitData())//如果等待数据成功

{

if(ComBuf[0]==0x07)//判断是否继续写

{

for(n=2;n<=17;n++)//ComBuf[2~17]为待写入数据块

{

if(!

pw.fpWrite(ComBuf[n]))//<<<<<<<<<调用写该器件一个单元的函数

{

pw.fpProOver();//出错了就结束编程

ComBuf[0]=0xff;

SendResp();//回应上位机一个字节,

表示写数据出错了

WaitData();//等待上位机的回应后就结束

return;

}

nAddress++;//下一个单元

}

ComBuf[0]=1;//回应上位机一个字节,表示数据块顺利完成,请求继续

SendResp();

}

elseif(ComBuf[0]==0x00)//写器件结束

break;

else//可能是通讯出错了

{

pw.fpProOver();

return;

}

}

else//等待数据失败

{

pw.fpProOver();

return;

}

}

pw.fpProOver();//编程结束后的工作

Delay_ms(50);//延时等待上位机写线程结束

ComBuf[0]=0;//通知上位机编程器进入就绪状态

SendData();

}

voidRead()//读器件

{

BYTEn;

pw.fpInitPro();//先设置成编程状态

SendData();//回应上位机表示进入读状态

while

(1)

{

if(WaitResp())//等待上位机回应1个字节

{

if(ComBuf[0]==0)//ComBuf[0]==0表示读结束

{

break;

}

elseif(ComBuf[0]==0xff)//0xff表示重发

{

nAddress=nAddress-0x0010;

}

for(n=2;n<=17;n++)//ComBuf[2~17]保存读出的数据块

{

ComBuf[n]=pw.fpRead();//<<<<<<<<<<调用写该器件一个单元的函数

nAddress++;//下一个单元

}

ComBuf[0]=6;//向上位机发送读出的数据块

SendData();

}

else

break;//等待回应失败

}

pw.fpProOver();//操作结束设置为运行状态

ComBuf[0]=0;//通知上位机编程器进入就绪状态

SendData();

}

voidLock()//写锁定位

{

pw.fpLock();

SendData();

}

/////////////////////////////////////////////////////////////////////////////////

//所支持的FID,请在这里继续添加

/////////////////////////////////////////////////////////////////////////////

externvoidPreparePro00();//FID=00:

AT89C51编程器

externvoidPreparePro01();//FID=01:

AT89C2051编程器

externvoidPreparePro02();//FID=02:

AT89S51编程器

voidmain()

{

SP=0x60;

SetVpp5V();//先初始化Vpp为5v

SCON=0x00;

TCON=0x00;

//PCON=0x00;//波特率*2

IE=0x00;

//TMOD:

GATE|C/!

T|M1|M0|GATE|C/!

T|M1|M0

//00100001

TMOD=0x21;//T0用于延时程序

TH1=0xff;

TL1=0xff;//波特率28800*2,注意PCON

//SCON:

SM0|SM1|SM2|REN|TB8|RB8|TI|RI

//01010000

SCON=0x50;

TR1=1;

Delay_ms(1000);//延时1秒后编程器自举

ComBuf[0]=0;

SendData();

while

(1)//串口通讯采用查询方式

{

if(!

WaitComm())//如果超时,通讯出错

{

Delay_ms(500);

ComBuf[0]=0;//让编程器复位,使编程器就绪

}

switch(ComBuf[1])//根据FID设置(ProWork)pw中的函数指针

{

case0:

//at89c51编程器

PreparePro00();break;

case1:

//at89c2051编程器

PreparePro01();break;

case2:

//at89s51编程器

PreparePro02();break;

//case3:

支持新器件时,请继续向下添加

//break;

//case4:

//break;

default:

ComBuf[0]=0xff;

ComBuf[1]=0xff;//表示无效的操作

break;

}

switch(ComBuf[0])//根据操作ID跳到不同的操作函数

{

case0x00:

RstPro();break;//编程器复位

case0x01:

ReadSign();break;//读特征字

case0x02:

Erase();break;//擦除器件

case0x03:

Write();break;//写器件

case0x04:

Read();break;//读器件

case0x05:

Lock();break;//写锁定位

default:

SendData();break;

}

}

}

5.voidInitSerial(void)

{

TMOD=0x20;//T1方式2

PCON=0x00;//PCON=00H,SMOD=0PD=PCON.2=1进入掉电模式

TH1=TL1=BAUD_9600;//BAUD:

9600

SCON=0x50;//串行通信方式1REN=1允许接收

ET1=0;//不允许中断

TR1=1;//开启定时器1

IE=0;//关闭所有中断允许位

memset(&SerialBuf,0x00,SERIAL_BUF_LEN);//初始化SerialBuf[SERIAL_BUF_LEN]

}

/********************************************************

**名称:

SendByte()

**功能:

串口发送一个字节

**输入:

ucData

**返回:

**说明:

********************************************************/

voidSendByte(unsignedcharucData)

{

SBUF=ucData;

while(!

TI)

{

_CLRWDT_;

}

TI=0;

}

 

RS232串口通信程序

#include

unsignedcharcodedispcode1[]={"   welcome!

   "};

unsignedcharcodedispcode2[]={""};

unsignedchari,j,k,l,DData;

sbitRS=P3^5;

sbitRW=P3^6;

sbitE=P3^7;

unsignedcharm=0;

voiddelay()

{for(l=0;l<=100;l++){}}

voidenable()//writeorder

{

RS=0;RW=0;E=0;delay();E=1;

}

voidenable2()//writedata

{

RS=1;RW=0;E=0;delay();E=1;

}

voidinitializtion()//lcdinitializtion

{

for(i=0;i<=100;i++)

P0=0x01;enable();

P0=0x38;enable();

P0=0x0f;enable();

P0=0x06;enable();

}

voidDisplay(m,DData)//displaydata

{

  P0=0xC0+m;  //writeaddress

  enable();

  P0=DData;  //writedata

  enable2();

}

voidEsisr()interrupt4//串口接收中断服务程序

{   

unsignedchartemp;

ES=0;

if(RI==1)

{

  RI=0;

  temp=SBUF;//接收数据

  SBUF=temp; //将接收到的数据发送至PC机

  Display(m,temp);//将接收到的数据送LCD显示

    while(!

TI);//等待数据发送完成

  TI=0;

  m++;

  if(m>16)

  m=0;

}

ES=1;

}

voidsystem_initial(void)  //systeminitializtion

{

  TMOD=0x21;//定时器1工作方式2,定时器0工作方式1

  PCON=0x00;//数据传输率选择。

  SCON=0x50;//串口工作方式选择,并打开接收允许。

  TH1=0xfd;//定时器赋初值。

  TL1=0xfd;//波特率9600bit/s

  TR1=1;//启动定时器。

  EA=1;  //开总中断。

  ES=1;

}

voidmain()

{

  initializtion();

  P0=0x80;enable();

  for(j=0;j<=15;j++)

  {

  P0=dispcode1[j];

  enable2();

  }

  P0=0xC0;enable();

  for(k=0;k<=15;k++)

  {

  P0=dispcode2[k];

  enable2();

  }

  system_initial();

  while

(1);

}

RS232串口通信单片机接收发送数据的C51程序

这是一个单片机C51串口接收(中断)和发送例程,可以用来测试51单片机的中断接收和查询发送。

关于RS232串口通信原理详解见:

关于单片机串口控制寄存器设置见:

#include

#include

#definelength4              //数据长度

unsignedcharinbuf[length];

unsignedcharchecksum,counter;

bitflag=0;              //取数标记

main()

{

init_serial();      //串行口初始化

while

(1)

{

if(flag!

=0)  //如果取数标志已置位,

就将读到的数从串口发出

{

flag=0;             //取数标志清0

send_string(inbuf,length);    //向串口发送字符串

}

}

}

/*串行口初始化*/

voidinit_serial(void)  

{

SCON=0x50;  //串行工作方式1,8位异步通信方式

TMOD|=0x20;    //定时器1,方式2,8位自动重装

PCON|=0x80;   //SMOD=1,表示数据传输率加倍

TH1=0xF4;         //数据传输率:

4800fosc=11.0592MHz

IE|=0x90;                          //允许串行中断

TR1=1;                             //启动定时器1

}

/*向串口发送一个字符*/

voidsend_char(unsignedcharx)

{

SBUF=x;

while(TI==0);

TI=0;

}

/*向串口发送

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 自然科学 > 数学

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1