您的位置 首页 编程

根据AVR单片机硬件多机通讯功用的完成

基于AVR单片机硬件多机通讯功能的实现-通讯规则:

1:时钟7.3728MHz/波特率9600/9个数据位/奇校验/1个停止位/硬件多机通讯功能/

2:通讯连接采用硬件MAX485,双向单工

3:每个上行/下行的数据包的字节个数都是一样的(通讯数据量)

通讯规矩:

1:时钟7.3728MHz/波特率9600/9个数据位/奇校验/1个中止位/硬件多机通讯功用/

2:通讯衔接选用硬件MAX485,双向单工

3:每个上行/下行的数据包的字节个数都是相同的(通讯数据量)

根据AVR单片机硬件多机通讯功用的完成
 

4:每个上行/下行的数据包都选用CRC8校验

5:数据接纳选用中止+查询的方法

6:总是由主机向从机发送一个数据包,从机收到数据包后向主机回复一个数据包

7:不管是主机仍是从机,假如收到的数据包有任何过错,都将丢掉该数据包,等效于没有接纳

8:从机之间不能彼此通讯,有必要经过主机才干交流数据

9:无效地址是0,主机地址是1,从机地址是2.3.4.。。.。。播送地址是255

*/

#include

#include

#include

#include//CRC校验函数就在这个文件里边

#defineamount10//设定通讯数据量(包含1个地址帧,n个数据帧,1个校验帧)

unsignedcharsend[amount];//发件箱

unsignedcharinbox[amount];//收件箱

unsignedcharn=0;//回忆中止次数

//——————————————————————–

interrupt[12]Rxd_isr(void)//接纳中止

{

unsignedcharERROR=0;

if(UCSRA&4||UCSRA&16)ERROR=1;//奇偶效验过错或许帧过错就记载下来

inbox[n]=UDR;//保存到收件箱

n++;//回忆中止次数

if(ERROR)inbox[0]=0;//假如通讯有错,收件箱的地址帧就符号成无效地址0

}

//———————————————————————

voidmain(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

#defineamount10//设定通讯数据量(包含1个地址帧,n个数据帧,1个校验帧)

#defineaddress2//请在这儿设定本机地址

unsignedcharsend[amount];//发件箱

unsignedcharinbox[amount];//收件箱

unsignedcharn=0;//回忆中止次数

interrupt[12]Rxd_isr(void)//接纳中止

{

unsignedcharERROR=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)//假如是播送地址就。。.

{

//请在这儿增加你的代码

//收到播送数据请不要回复

}

}

}

}

voidmain(void)

{

usart_init();

#asm(“sei”)

while(1)

{

//send[1]=?

//。。.。。.

//send[n]=?

};

}

———————————————————————————

usart.h文件

———————————————————————————

//波特率9600/9个数据位/1个中止位/奇校验/收发敞开/接纳中止

voidusart_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个数据是地址帧,其他是数据帧

voidusart_out(unsignedchar*datas,unsignedcharn)

{

unsignedchari=0;

PORTD.4=1;//使MAX485处于发送状况

while(i{

if(i==0)UCSRB|=1;elseUCSRB&=254;

UDR=*(datas+i);//装载数据开端发送

while((UCSRA&64)==0);//等候发送完毕

UCSRA|=64;//铲除发送完毕标志

i++;//发送次数计算

}

PORTD.4=0;//使MAX485处于接纳状况

}

———————————————————————————

crc8校验程序

———————————————————————————

unsignedcharcrc8(unsignedchar*ptr,unsignedcharlen)

{

unsignedchari;

unsignedcharcrc=0;

while(len–!=0)

{

for(i=1;i!=0;i*=2)

{

if((crc&1)!=0){crc/=2;crc^=0x8C;}

elsecrc/=2;

if((*ptr&i)!=0)crc^=0x8C;

}

ptr++;

}

return(crc);

}

声明:本文内容来自网络转载或用户投稿,文章版权归原作者和原出处所有。文中观点,不代表本站立场。若有侵权请联系本站删除(kf@86ic.com)https://www.86ic.net/fangan/biancheng/346788.html

为您推荐

联系我们

联系我们

在线咨询: QQ交谈

邮箱: kf@86ic.com

关注微信
微信扫一扫关注我们

微信扫一扫关注我们

返回顶部