AVR多机通讯

发布者:Radiant777最新更新时间:2017-12-15 来源: eefocus关键字:AVR  多机通讯 手机看文章 扫描二维码
随时随地手机看文章

通讯规则:  
   1:时钟7.3728 MHz/波特率9600/9个数据位/奇校验/1个停止位/硬件多机通讯功能/  
   2:通讯连接采用硬件MAX485,双向单工  
   3:每个上行/下行的数据包的字节个数都是一样的(通讯数据量)  

   4:每个上行/下行的数据包都采用CRC8校验  
   5:数据接收采用中断+查询的方式  
   6:总是由主机向从机发送一个数据包,从机收到数据包后向主机回复一个数据包  
   7:不管是主机还是从机,如果收到的数据包有任何错误,都将丢弃该数据包,等效于没有接收  
   8:从机之间不能相互通讯,必须通过主机才能交换数据  
   9:无效地址是0,主机地址是1,从机地址是2.3.4......广播地址是255  
*/  
#include   
#include   
#include   
#include      //CRC校验函数就在这个文件里面    

#define    amount 10    //设定通讯数据量(包括1个地址帧,n个数据帧,1个校验帧)  

unsigned char   send[amount];            //发件箱  
unsigned char inbox[amount];            //收件箱  
unsigned char n=0;                      //记忆中断次数  

//--------------------------------------------------------------------  
interrupt[12] Rxd_isr(void)             //接收中断  
{    
   unsigned char ERROR=0;  
   if( UCSRA&4 || UCSRA&16 ) ERROR=1; //奇偶效验错误或者帧错误就记录下来     
   inbox[n]=UDR;                        //保存到收件箱  
   n++;                                  //记忆中断次数  
   if(ERROR) inbox[0]=0;                 //如果通讯有错,收件箱的地址帧就标记成无效地址0  
}  

//---------------------------------------------------------------------  
void main(void)  
{  
   usart_init();                          //串口初始化  
   UCSRA=0;                             //主机关闭地址筛选功能(多机通讯功能)  
   #asm("sei")                           //打开全局中断  
   while(1)  
   {  
     //-------------与从机2对话,与其他从机对话与下面的程序类似-------------------  
     n=0;                                //中断次数清0  
     inbox[0]=0;                         //收件箱地址清0  
     //请更新准备发送的数据  
     //send[1]=?    
     //......  
     //send[n]=?  
     send[0]=2;                          //改变这个地址就可以实现与某个从机对话  
     send[amount-1]=crc8(send,amount-1);       //计算发件箱的crc8校验码  
     usart_out(send,amount);                          //将发件箱的数据send[]发送出去;  
      
     //等待,从机接收到数据后会回复数据的,如果是10个字节数据量,不能少于13ms!!!  
     //这个时间由人工计算,要考虑从机由于各种中断延长回复时间的可能  
      
     delay_ms(15);  
      
     //if(n<3) 如果接收到的数据还不到3个,那么就是通讯线路故障  
      
     //如果收件箱已经收到amount个数据,并且crc8校验成功就...  
     if(n==amount && inbox[amount-1]==crc8(inbox,amount-1))  
       {  
         if(inbox[0]==1)                 //如果收件箱地址帧属于本机就运行下面的测试代码  
           {  
             DDRD.3=1;  
             PORTD.3=1; delay_ms(10);  
             PORTD.3=0; delay_ms(990);  
           }  
            
         if(inbox[0]==255)  
           {  
             //请在这里添加收到广播数据的处理程序  
           }  
       }                
   }  
}    //end  

---------------------------------------------------------------------------------  
从机  
---------------------------------------------------------------------------------  
#include   
#include   
#include   

#define    amount 10     //设定通讯数据量(包括1个地址帧,n个数据帧,1个校验帧)    
#define    address 2     //请在这里设定本机地址  

unsigned char   send[amount];                      //发件箱  
unsigned char inbox[amount];                      //收件箱  
unsigned char n=0;                                //记忆中断次数  

interrupt[12] Rxd_isr(void)                       //接收中断  
{    
   unsigned char ERROR=0;  
   if( UCSRA&4 || UCSRA&16 ) ERROR=1;              //记录奇偶效验错误或者帧错误  
   inbox[n]=UDR;                                   //把接收到的数据保存到收件箱  
   n++;                                            //记忆接收的次数  
   if(ERROR)                                       //如果通讯有错....  
     {  
       n=0;                                        //接收计数清0  
       inbox[0]=0;                                 //把地址改为无效地址0  
       UCSRA|=0x01;                                //重新打开接收器的地址帧筛选功能  
     }  
    
   //如果地址匹配本机或者是广播地址就关闭地址筛选(多机通讯)功能    
   if(inbox[0]==address ||inbox[0]==255) UCSRA&=254;  
    
   if(n==amount)                                   //接收到amount个数据以后...  
     {    
       n=0;                                        //接收计数清0  
       UCSRA|=0x01;                                //重新打开接收器的地址帧筛选功能  
       if(inbox[amount-1]==crc8(inbox,amount-1))   //如果crc8校验正确就...  
         {     
           if(inbox[0]==address)                   //如果地址匹配本机就回复数据  
             {    
               send[0]=1;                          //发件箱地址指向主机  
               send[amount-1]=crc8(send,amount-1);//产生发件箱的crc8校验码  
               usart_out(send,amount);             //发送发件箱的数据包send[]  
               //请在这里备份你的收件箱信息  
             }  
           if(inbox[0]==255)                       //如果是广播地址就...  
             {  
               //请在这里添加你的代码  
               //收到广播数据请不要回复  
             }  
         }  
     }  
}  

void main(void)  
{  
   usart_init();  
   #asm("sei")  

   while (1)  
         {  
           //send[1]=?  
           //......  
           //send[n]=?  
         };  
}  


---------------------------------------------------------------------------------  
usart.h文件  
---------------------------------------------------------------------------------  
//波特率9600/9个数据位/1个停止位/奇校验/收发开启/接收中断  
void usart_init(void)  
      {    
        UCSRA=0x01;  
        UCSRB=0x9C;  
        UCSRC=http://www.pICavr.com/0xB6;  
        UBRRH=0x00;  
        UBRRL=47;  

        PORTD.4=0;                       //MAX485平时工作在接收状态  
        DDRD.4=1;  
      }  

//-----------------------------------------------------------  
//从数组datas[]的首地址开始发送amount个数据,其中第0个数据是地址帧,其他是数据帧  
void usart_out(unsigned char *datas,unsigned char n)  
      {  
        unsigned char i=0;    
        PORTD.4=1;                       //使MAX485处于发送状态  
        while(i             {    
               if(i==0) UCSRB|=1; else UCSRB&=254;     
               UDR=*(datas+i);          //装载数据开始发送  
               while((UCSRA&64)==0);    //等待发送结束  
               UCSRA|=64;               //清除发送结束标志  
               i++;                      //发送次数统计  
             }  
        PORTD.4=0;                       //使MAX485处于接收状态  
      }     

---------------------------------------------------------------------------------  
crc8校验程序  
---------------------------------------------------------------------------------  
unsigned char crc8(unsigned char *ptr, unsigned char len)    
{  
   unsigned char i;  
   unsigned char crc=0;  
   while(len--!=0)    
    {  
      for(i=1; i!=0; i*=2)  
       {  
         if((crc&1)!=0) {crc/=2; crc^=0x8C;}  
         else crc/=2;  
         if((*ptr&i)!=0) crc^=0x8C;       
        }    
      ptr++;  
     }  
return(crc);  


关键字:AVR  多机通讯 引用地址:AVR多机通讯

上一篇:icc avr LCD1602显示屏程序
下一篇:avr单片机控制AD5161实验程序

推荐阅读最新更新时间:2024-03-16 15:49

AVR单片I/O口读74HC165接口程序
AVR单片机I/O口读74HC165接口程序 /******************************** AVR单片机I/O口读74HC165接口程序 文件名:serin.c 编译:WinAVR-20070525 硬件:ATMEGA16 时钟:7372800 Hz 此程序在硬件上调试通过! 芯艺设计室 2004-2007 版权所有 转载请保留本注释在内的全部内容 WEB: http://www.chipart.cn Email: changfutong@sina.com ***************************
[单片机]
<font color='red'>AVR</font>单片<font color='red'>机</font>I/O口读74HC165接口程序
AVR相比51系列单片的优势特征
单片机又称单片微控制器,它是把一个计算机系统集成到一个芯片上,概括的讲:一块芯片就成了一台计算机。单片机技术是计算机技术的一个分支,是简易机器人的核心元件。 1997年,由ATMEL公司挪威设计中心的A先生与V先生利用ATMEL公司的Flash新技术, 共同研发出RISC精简指令集的高速8位单片机,简称AVR。 AVR单片机的优势特征 单片机已广泛地应用于军事、工业、家用电器、智能玩具、便携式智能仪表和机器人制作等领域,使产品功能、精度和质量大幅度提升,且电路简单,故障率低,可靠性高,成本低廉。单片机种类很多,在简易机器人制作和创新中,为什么选用AVR单片机呢? 一、简便易学
[单片机]
基于AVR单片的数字电子秤的设计
0 引言 随着电子技术和自动化测量技术的不断发展,传统的称重系统在功能、精度、性价比等方面已难以满足人们的需要,尤其在智能化、便携式、对微小质量的测量方面更显得力不从心。近年来,新型单片机的出现和集成电路技术的发展为更新产品设计,研制高性价比的称重控制器提供了条件。本设计采用AVR单片机为控制核心,结合电阻应变式压力传感器和相应的信号采集电路,设计出一种高精度、多功能、低成本的新型电子秤。 1 系统总体设计 首先由称重传感器采集因压力变化而产生的电压信号,通过A/D转换器将模拟信号转换为数字信号,把数字信号送入AVR单片机,单片机做相应的处理后,得到当前物体重量的数据,并通过LCD显示出来。系统硬件结构如图1所
[单片机]
基于<font color='red'>AVR</font>单片<font color='red'>机</font>的数字电子秤的设计
AVR单片解密后的熔丝配置
AVR单片机内部有多组与器件配置和运行环境相关的的熔丝位,这些熔丝位非常重要,用户可以通过设定和配置熔丝位使AVR单片机局部不同的特性,以更加适合实际应用。但是由于需要对熔丝位进行配置,给初学者带来一些不太好理解的地方,对于单片机解密以后,在烧录程序的时候,也要对熔丝位配置,如果配置不对了,可能不工作或功能发生变化。所有在烧录解密后的文件的时候一定要对熔丝位进行配置,由于支持AVR的工具非常多,而不同的工具的软件的界面不同,所以在做AVR单片机解密前最好告诉解密公司自己使用的是什么工具,让芯片解密公司按照自己的工具的界面做配置图,这样就方便了解密以后去烧写程序,不过自己也可以用解密公司提供的样片去读熔丝位配置,有的工具直接读芯片就
[单片机]
LCD2004AVR单片驱动源程序
/*======================================================= 20x4字符液晶主程序,编译软件(I CC AVR_6.31) CPU内部 晶振 8M 数据线B0~B7接PORTB, E=D7 RW=D6 RS=D5 ========================================================= 接线图如下: _______________ ______________ | --1|GND | | --2|+5V | | --3|V0 |
[单片机]
AVR开发 Arduino方法(四) 串行通信子系统
  Arduino UNO R3主处理器ATMega328P的串行通信子系统可以用于与计算机、外设或其他微控制器进行通信,它支持3种串行通信方式:通用同步/异步收发器,串行外设接口和两线串行接口。 1. 通用同步/异步收发器   在串行通信中,波特率用来衡量传输速率的快慢,同步和异步的对象是波特率的时钟信号;同步通信的设备之间需要一条额外的时钟线,也因此同步方式可以提供更高的波特率;这里将以异步为例。   下面的示例可以使通过串口发送给Arduino的数据回显到串口监视器上: 1 // SerialEcho.ino 2 char data; 3 4 void setup() { 5 Serial.begin(9600
[单片机]
<font color='red'>AVR</font>开发 Arduino方法(四) 串行通信子系统
AVR单片简介
ATmel 挪威设计中心的A先生与V先生,于97年设计出一款使用RISC指令集的8位单片机,起名为AVR AVR 性能简介: AVR单片机是ATMEL公司研制开发的一种新型单片机,它与51单片机、PIC单片机相比具有一系列的优点: 1:在相同的系统时钟下AVR运行速度最快; 2: 芯片内部的Flsah、EEPROM、SRAM容量较大; 3:所有型号的Flash、EEPROM都可以反复烧写、全部支持在线编程烧写(ISP); 4:多种频率的内部RC振荡器、上电自动复位、看门狗、启动延时等功能,零外围电路也可以工作; 5:每个IO口都可以以推换驱动的方式输出高、低电平,驱动能力强; 6:内部资源丰富,一般都集成AD、DA模
[单片机]
AVR单片在柴油机转速测量中的应用
   摘要:利用ATMEL新一代AVR单片机(AT90S2313)实现对柴油机转速的测量,在C语言程序设计中引入了消息的概念,最后给出了AT90S2313与AT89C2051在转速测量中使用效果的比较。 关键词:单片机 转速测量 柴油机 消息    柴油机的转速是一个较为重要的运行参数,也有很多种用于测量转速的仪表,如:机械软轴式转速表、频率-电压转换式转速表、数字式转速表等,它们中间有的成本很高而且精度较差、有的工艺复杂而且可靠性不高。本文介绍了一种利用单片机技术制成的智能转速表,不仅精度高、工艺简单、线路简洁,而且可靠性高、功能强。其不仅可以测量转速,而且可以统计机器运行的累计时间,当柴油
[测试测量]
小广播
添点儿料...
无论热点新闻、行业分析、技术干货……
设计资源 培训 开发板 精华推荐

最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

换一换 更多 相关热搜器件
电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved