注册 登录  
 加关注
   显示下一条  |  关闭
温馨提示!由于新浪微博认证机制调整,您的新浪微博帐号绑定已过期,请重新绑定!立即重新绑定新浪微博》  |  关闭

易拉罐的博客

心静自然凉

 
 
 

日志

 
 

转 基于RS-485的多机通信程序  

2010-03-28 11:33:16|  分类: 串行通信 |  标签: |举报 |字号 订阅

  下载LOFTER 我的照片书  |

//-----------------------函数声明,变量定义---------------------
#include <reg51.h>
sbit RE_DE=P1^0;
#define COUNT 10                   // 定义接收缓冲区大小
#define Slaver_NUM 10

unsigned char bdata flag;          //在可位寻址去定义一个标志变量
sbit time_over_flag =flag^0;       //接收超时标志

unsigned char buffer[COUNT];       //定义缓冲区
unsigned char point;               //定义缓冲区位置指示

unsigned char Slave_AD[Slaver_NUM]; //定义有效地址存放区
unsigned char ADD_num;               //有效地址个数

unsigned char idata count_10ms;    //用于表示有多少次10ms中断

unsigned char idata send_data[7]={
0x31,0x32,0x33,0x34,0x35,0x36,0x37}; //与定义发送数据,共7位

void UART_init();                  //串口初始化函数
void COM_send(void);               //串口接收函数
unsigned char CLU_checkdata(void); //计算校验位函数

//---------------------------------------------------------------
// 函数名称: UART_init()串口初始化函数
// 函数功能: 在系统时钟为11.059MHZ时,设定串口波特率为9600bit/s
//            串口接收中断允许,发送中断禁止,设定定时器中断允许
//---------------------------------------------------------------
void UART_init()
{
//初始化串行设置
SCON =0x58;          //选择串口工作方式为1,打开接收允许,TB8=1
TMOD =0x21;          //定时器1工作在方式2,定时器0工作在方式1
TR1 =1;              //启动定时器T1
ES=1;                //允许串行口中断
PS=1;                //设计串行口中断优先级
//初始化定时器1
TH1 =0xfd;           //实现波特率9600(系统时钟11.0592MHZ)
ET1 =0;     //定时器1中断禁止
}
//---------------------------------------------------------------
// 函数名称: timer0_init()初始化定时器0
// 函数功能: 设置timer0工作模式
//---------------------------------------------------------------
void timer0_init()
{
time_over_flag=0;
count_10ms=0;
ADD_num=0;
TL0=0x0F0;            //T0用于产生10ms的中断
TH0=0x0D8;     //50次T0中断产生1次超时溢出
ET0=1;            //允许定时器0中断
}
//---------------------------------------------------------------
// 函数名称: system_init()系统初始化
// 函数功能: 调用串口、定时器初始化函数,完成系统初始化
//---------------------------------------------------------------
void system_init(void)
{
//系统总设置
UART_init();
timer0_init();
EA =1;                //单片机中断允许
}
//---------------------------------------------------------------
// 函数名称: com_interrup()串口接收中断处理函数
// 函数功能: 接收包括起始位"S"在内的十位数据到数据缓冲区
//---------------------------------------------------------------
com_interrupt(void) interrupt 4 using 3
{
  unsigned char RECEIVR_buffer;
  if(RI)                              //处理接收中断
  {RI=0;                               //清除中断标志位
  RECEIVR_buffer=SBUF;            //接收串口数据
if(point==0)        //如果还没有接收到起始位
        {
        if(RECEIVR_buffer==0xFE)        //判断是否起始标志位
             {
    buffer[point++]=RECEIVR_buffer;//把接收到的数据放入接收缓存区
    }
  else
       point=0;      //不是,继续等待起始位
   }
else if(point>0&&point<10)     //判断是否接收够十位数据
  buffer[point++]=RECEIVR_buffer;  //不够,把接收到的数据放入接收缓存区
else if(point==10)
      {
        if(RECEIVR_buffer==0xEF)        //判断结束标志位是否正确
          {
    buffer[point]=RECEIVR_buffer; //把接收到的数据放入接收缓存区
    Slave_AD[ADD_num++]=buffer[2]; //把接收到的地址放到地址存储器
                                  //表示该地址有有效设备
     }
  else
       point=0;      //不是,继续等待起始位
   }
 else point=0;                   //缓冲区已满,清除缓存区内数据重新接收
}
if(TI)                                   //串口发送中断
{
 TI=0;                                   //清除发送中断
 }
}
//---------------------------------------------------------------
// 函数名称: timer0_interrup()
// 函数功能:定时器T0中断服务程序
// 函数说明:T0枚10ms中断一次,连续中断50次置time_over_flag=1;
//---------------------------------------------------------------
timer0_interrupt(void) interrupt 1 using 2

  count_10ms++;
  if(count_10ms==50)
  {
  ET0=0;           //关闭定时器T0中断
  TR0=0;           //停止定时器T0
  time_over_flag=1;//设置接收超时标志
  count_10ms=0x00; //10ms计数器复位
  }
  else
  {
  TL0=0x0F0;            //重装定时器初始值
  TH0=0x0D8;  
  }
}

//---------------------------------------------------------------
// 函数名称: COM_send()串口发送函数
// 函数功能: 把数据缓冲区的十位数据发送出去
//---------------------------------------------------------------
void COM_send(void)
{
 RE_DE=1;                                //设置MAX483进入发送状态
 for(point=0;point<=10,TI=1;point++)  //连续发送十位数据
                                         //把缓存区的数据都发送到串口
  {
   SBUF=buffer[point];
   TI=0;
   }
    RE_DE=0;                                //设置MAX483进入接收状态

}
//---------------------------------------------------------------
// 函数名称: write_buffer()
// 函数功能: 写发送缓冲区十位数据
//---------------------------------------------------------------
void write_buffer(unsigned char slaver_add)
{
  unsigned char i;
  TB8=1;                                  //打开多机通信方式
  buffer[0]=0xFE;
  buffer[1]=slaver_add;
  for(i=2;i<9;i++)          //连续发送十位数据
                                         //把缓存区的数据都发送到串口
  {
   buffer[i]=send_data[i-2];
   }
   buffer[9]=0xEF;
 }

//---------------------------------------------------------------
// 函数名称: 主函数
// 函数功能: 调度个子函数,完成通信过程
//---------------------------------------------------------------
 void main(void)
 {
 unsigned char i=0;
 system_init();     //系统初始化
 do{       //查旬0到10好地址有没有对应设备
 write_buffer(i++);    //写查询第i号设备的发送信息
 COM_send();     //调用发送函数,完成发送
 timer0_init();     //完成一次查询,重新初始定时器0,准备下一次查询
 }
 while(time_over_flag&

;&i<10);
 }

//-----------------------函数声明,变量定义--------------------------------------------------------
#include <reg51.h>
sbit RE_DE=P1^0;

#define COUNT 10                // 定义接收缓冲区大小
#define ADD    5    //定义设备地址
unsigned char buffer[COUNT]; //定义接收缓冲区
unsigned char point;            //定义接收数据个数指示变量

void UART_init();               //串口初始化函数
void COM_send(void);            //串口接收函数
unsigned char CLU_checkdata(void);//计算校验位函数
//--------------------------------------------------------------------------------------------------
// 函数名称: UART_init()串口初始化函数
// 函数功能: 在系统时钟为11.059MHZ时,设定串口波特率为9600bit/s
//            串口接收中断允许,发送中断禁止
//--------------------------------------------------------------------------------------------------
void UART_init()
{
                     //初始化串行口和波特率发生器
SCON =0x0F0;          //选择串口工作方式为3,打开接收允许
TMOD =0x21;          //定时器1工作在方式2,定时器0工作在方式1
TH1 =0xfd;           //实现波特率9600(系统时钟11.0592MHZ)
TL1 =0xfd;           //实现波特率9600(系统时钟11.0592MHZ)
TR1 =1;              //启动定时器T1
ET1 =0;
ES=1;                //允许串行口中断
PS=1;                //设计串行口中断优先级
EA =1;               //单片机中断允许
SM2=1;                //设备处于地址****状态
}
//--------------------------------------------------------------------------------------------------
// 函数名称: com_interrup()串口接收中断处理函数
// 函数功能: 接收包括起始位0xFE,地址位和终止位0xEF在内的十位数据到数据缓冲区,
//            地址不匹配,则接收到的是无效数字,不写到接收缓冲区
//--------------------------------------------------------------------------------------------------
com_interrupt(void) interrupt 4 using 3
{
  unsigned char RECEIVR_buffer;
  if(RI)
  {                               //处理接收中断
   RI=0;                                 //清除中断标志位
   RECEIVR_buffer=SBUF;              //接收串口数据
   if(point==0)          //如果还没有接收到起始位
        {
        if(RECEIVR_buffer==0xFE)         //判断是否起始标志位
             buffer[point++]=RECEIVR_buffer;//起始正确,接收起始位
  else
       point=0;        //不是,继续等待起始位
   }
     else if(point==1)      //是否地址位
        {
        if(RECEIVR_buffer==ADD)          //判断地址是否匹配
          buffer[point++]=RECEIVR_buffer;//地址匹配,接收开始接收
  else
       point=0;        //不匹配,继续下一个起始位
   }
else if(point>0&&point<10)     //判断是否接收够十位数据
  buffer[point++]=RECEIVR_buffer;  //不够,把接收到的数据放入接收缓存区
else point=0;                   //缓冲区已满,清除缓存区内数据重新接收
}
if(TI)                                   //串口发送中断
{
 TI=0;                                   //清除发送中断
 }
}
//--------------------------------------------------------------------------------------------------
// 函数名称: COM_send()串口发送函数
// 函数功能: 把数据缓冲区的十位数据发送出去
//--------------------------------------------------------------------------------------------------
void COM_send(void)
{
 RE_DE=1;                                //设置MAX483进入发送状态
 for(point=0;point<=10,TI=1;point++)  //连续发送十位数据
                                         //把缓存区的数据都发送到串口
  {
   SBUF=buffer[point];
   TI=0;
   }
    RE_DE=0;                                //设置MAX483进入接收状态
}

//--------------------------------------------------------------------------------------------------
// 函数名称: 主函数
// 函数功能: 调度个子函数,完成通信过程
//--------------------------------------------------------------------------------------------------
 void main(void)
 {
   UART_init();       //初始化串口

  do
  {
   }
   while(point!=10);  //判断数据是否接收完成
   COM_send();    //地址匹配,数据完整接收,调用发送程序通知主机
  SM2=0;                  //设置为点对点通信状态  
 }

 

高校自动化网

http://www.zdh1909.com/html/MCS51/5556_4.html

  评论这张
 
阅读(521)| 评论(1)
推荐 转载

历史上的今天

在LOFTER的更多文章

评论

<#--最新日志,群博日志--> <#--推荐日志--> <#--引用记录--> <#--博主推荐--> <#--随机阅读--> <#--首页推荐--> <#--历史上的今天--> <#--被推荐日志--> <#--上一篇,下一篇--> <#-- 热度 --> <#-- 网易新闻广告 --> <#--右边模块结构--> <#--评论模块结构--> <#--引用模块结构--> <#--博主发起的投票-->
 
 
 
 
 
 
 
 
 
 
 
 
 
 

页脚

网易公司版权所有 ©1997-2017