can多机通信.docx

上传人:b****5 文档编号:29517189 上传时间:2023-07-24 格式:DOCX 页数:32 大小:23.63KB
下载 相关 举报
can多机通信.docx_第1页
第1页 / 共32页
can多机通信.docx_第2页
第2页 / 共32页
can多机通信.docx_第3页
第3页 / 共32页
can多机通信.docx_第4页
第4页 / 共32页
can多机通信.docx_第5页
第5页 / 共32页
点击查看更多>>
下载资源
资源描述

can多机通信.docx

《can多机通信.docx》由会员分享,可在线阅读,更多相关《can多机通信.docx(32页珍藏版)》请在冰豆网上搜索。

can多机通信.docx

can多机通信

Node1

//&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&

//描述:

//本程序为第7章节点1的配套程序&

//功能描述:

//INT0按键程序+显示程序+CAN两点通信程序&

//数码管1-2(从右至左)显示(十进制)本节点计数结果,数码管3-4显示(十进制)接收到的数据&&

//CAN主要参数:

//PeliCAN模式,扩展帧EFF模式&

//29位标示码结构:

&

//发送数据结构:

计数结果&

//接收数据结构:

待显示数据&

//本节点的地址:

0x01(ACR0~3:

0xff,0x01,0xff,0xff)&

//验收屏蔽寄存器:

0xff,0x00,0xff,0xff;(AMR0~3)只接收发往本节点的报文&

//报文标识符:

0x01,0x02,0x10,0x00;&

//提示:

如果CAN通讯不正常,会进入一个死循环,显示也不正常

//&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&

//【声明】此程序仅用于学习与参考,引用请注明版权和作者信息!

&

//【声明】作者:

PIAE小组&

#include

#include

#include

ucharjidian=0;

voidINT0_Counter(void)interrupt0using1

{//INT0按键为计数按键

EA=0;

Txd_data++;//存储计数结果,并为待发送的数据

TXD_flag=1;//要发送数据标志位

jidian++;

EA=1;

}

voidCAN_RXD(void)interrupt2

{//接收数据函数,在中断服务程序中调用

uchardataJudge;

uchardataCanDataLength;//报文数据长度变量

unsignedcharvolatilexdata*p;//外部寄存器指针

uchari;

EA=0;//关CPU中断

IE0=0;

Judge=IR;

if(Judge&0x01)

{//IR.0=1接收中断

CanDataLength=RBSR&0x0f;//CAN数据报文的数据长度

p=&RBSR;

for(i=0;i<=(CanDataLength+5);i++)

{

RX_buffer[i]=*p++;

}

jidian=RX_buffer[6];

jidian=~jidian;

if(jidian)LED_GRE=1;

if(!

jidian)LED_GRE=0;

RXD_flag=1;//置有接收标志

CMR=0X04;

Judge=ALC;//释放仲裁随时捕捉寄存器

Judge=ECC;//释放错误代码捕捉寄存器

}

IER=0x01;//.0=1--接收中断使能;

EA=1;//打开CPU中断

}

voidmain(void)

{

CPU_init();//CPU初始化

CAN_init();//SJA1000初始化,对SJA1000寄存器的读写是采用外部寄存器寻址方式,所以不需要程序单独控制片选有效无效

_nop_();

_nop_();

while

(1)

{

_nop_();

_nop_();

Rxd_deal();//接收处理程序

Txd_deal();//发送处理程序

led_seg7(1,Txd_data);

led_seg7(3,Rxd_data);

}

}

//*********************处理函数********************************

//*********************CPU初始化函数********************************

voidCPU_init(void)

{//初始化CPU

SJA_RST=0;//CAN总线复位管脚有效

Delay(20);

SJA_RST=1;//CAN总线复位管脚无效

SJA_CS=0;//CAN总线片选有效

EX1=1;

IT1=0;//CAN总线接收中断

IT0=1;//外部中断0负边沿触发

EX0=1;//打开外部中断0

EA=1;//打开总中断

SJA_CS=1;//CAN总线片选无效,使对数据总线的操作不会影响SJA1000。

}

voidRxd_deal(void)

{////////接收处理程序//////////////

if(RXD_flag)

{

EA=0;//关闭CPU中断

RXD_flag=0;

if(RX_buffer[3]==0x10)//如果该报文传输的为按键计数

{

Rxd_data=RX_buffer[5];

}

EA=1;

}

}////////接收处理程序//////////////

voidTxd_deal(void)

{//发送处理函数,主要是准备数据,并且调用发送函数

if(TXD_flag==1)

{

_nop_();

TXD_flag=0;

if(Txd_data&0x01)

{//将奇数计数值发往节点2.

//初始化标示码头信息

TX_buffer[0]=0x82;//.7=0扩展帧;.6=0数据帧;.3~0=1数据长度

TX_buffer[1]=0x01;//本节点地址

TX_buffer[2]=0x02;//

TX_buffer[3]=0x10;//

TX_buffer[4]=0x00;//

TX_buffer[5]=Txd_data;//

jidian++;

TX_buffer[6]=jidian;

}

elseif(!

(Txd_data&0x01))

{//将偶数计数值发往节点3.

//初始化标示码头信息

TX_buffer[0]=0x82;//.7=0扩展帧;.6=0数据帧;.3~0=1数据长度

TX_buffer[1]=0x01;//本节点地址

TX_buffer[2]=0x03;//

TX_buffer[3]=0x10;//

TX_buffer[4]=0x00;//

TX_buffer[5]=Txd_data;//

jidian++;

TX_buffer[6]=jidian;

}

CAN_TXD();

_nop_();

_nop_();

}

}

//*********************处理函数********************************

//*********************CAN子函数***********************

voidCAN_init(void)

{//SJA1000的初始化

ucharbdataJudge;

ucharACRR[4];

ucharAMRR[4];

ACRR[0]=0xff;

ACRR[1]=0x01;

ACRR[2]=0xff;

ACRR[3]=0xff;//接收代码寄存器

AMRR[0]=0xff;

AMRR[1]=0xff;

AMRR[2]=0xff;

AMRR[3]=0xff;//接收屏蔽寄存器,只接收发往本节点的报文

do

{//.0=1---resetMODR,进入复位模式,以便设置相应的寄存器

//防止未进入复位模式,重复写入

MODR=0x09;

Judge=MODR;

}

while(!

(Judge&0x01));

CDR=0x88;//CDR.3=1--时钟关闭,.7=0---basicCAN,.7=1---PeliCAN

BTR0=0x31;

BTR1=0x1c;//总线波特率设定

IER=0x01;//.0=1--接收中断使能;.1=0--关闭发送中断使能

OCR=0xaa;//配置输出控制寄存器

CMR=0x04;//释放接收缓冲器

ACR=ACRR[0];

ACR1=ACRR[1];

ACR2=ACRR[2];

ACR3=ACRR[3];//初始化标示码

AMR=AMRR[0];

AMR1=AMRR[1];

AMR2=AMRR[2];

AMR3=AMRR[3];//初始化掩码

do

{//确保退出复位模式

MODR=0x08;

Judge=MODR;

}

while(Judge&0x01);

}//SJA1000的初始化

voidCAN_TXD(void)

{

uchardataJudge;

//初始化数据信息

EA=0;//关中断

do

{

Judge=SR;

LED_RED=0;//

}

while(Judge&0x10);//SR.4=1正在接收,等待

do

{

Judge=SR;

LED_RED=0;//

}

while(!

(Judge&0x08));//SR.3=0,发送请求未处理完,等待

do

{

Judge=SR;

LED_RED=0;//

}

while(!

(Judge&0x04));//SR.2=0,发送缓冲器被锁。

等待

LED_RED=!

LED_RED;

//LED_GRE=!

LED_GRE;//灯闪烁

TBSR=TX_buffer[0];

TBSR1=TX_buffer[1];

TBSR2=TX_buffer[2];

TBSR3=TX_buffer[3];

TBSR4=TX_buffer[4];

TBSR5=TX_buffer[5];

TBSR6=TX_buffer[6];

CMR=0x01;//置位发送请求

EA=1;

}

voidDelay(uchardelay_time)

{//延时程序

while(delay_time--)

{}

}

//*********************CAN子函数*************************

//*********************显示子函数*************************

voidled_seg7(ucharfrom,ucharnumber)//from(1_4):

数码管显示起始位置(从右到左),number:

显示的数(数码管上采用10进制显示)

{

uchardigit,temp_l;

uchartemp_h=0x7f;

temp_h=_cror_(temp_h,from-1);//确定从哪一位开始显示,即确定高四位

temp_h=temp_h&0xf0;//取高四位

temp_l=P2&0x0f;//取P2的低四位

P2=temp_h|temp_l;//设定P2口

if(number==0)

{

P0=led[0];

Delay(10);

P0=0xff;

}

else

{

while(number)

{

digit=number%10;

number/=10;

P0=led[digit];

Delay(10);

temp_h=P2&0xf0;//取P2的高四位

temp_h=temp_h|0x0f;//拼装temp_h,进行位选

temp_h=_cror_(temp_h,1);

temp_h=temp_h&0xf0;//取高四位

temp_l=P2&0x0f;//取P2的低四位

P0=0xff;

P2=temp_h|temp_l;//设定P2口

}

}

}

Node2

//&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&

//描述:

//本程序为第7章节点2的配套程序&

//功能描述:

//INT0按键程序+显示程序+CAN两点通信程序&

//数码管1-2(从右至左)显示(十进制)本节点计数结果,数码管3-4显示(十进制)接收到的数据&&

//CAN主要参数:

//PeliCAN模式,扩展帧EFF模式&

//29位标示码结构:

&

//发送数据结构:

计数结果&

//接收数据结构:

待显示数据&

//本节点的地址:

0x02(ACR0~3:

0xff,0x02,0xff,0xff)&

//验收屏蔽寄存器:

0xff,0x00,0xff,0xff;(AMR0~3)只接收发往本节点的报文&

//报文标识符:

0x02,0x01,0x10,0x00;&

//提示:

如果CAN通讯不正常,会进入一个死循环,显示也不正常

//&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&

//【声明】此程序仅用于学习与参考,引用请注明版权和作者信息!

&

//【声明】作者:

PIAE小组&

#include

#include

#include

ucharjidian=0;

voidINT0_Counter(void)interrupt0using1

{//INT0按键为计数按键

EA=0;

Txd_data++;//存储计数结果,并为待发送的数据

TXD_flag=1;//要发送数据标志位

jidian++;

EA=1;

}

voidCAN_RXD(void)interrupt2

{//接收数据函数,在中断服务程序中调用

uchardataJudge;

uchardataCanDataLength;//报文数据长度变量

unsignedcharvolatilexdata*p;//外部寄存器指针

uchari;

EA=0;//关CPU中断

IE0=0;

Judge=IR;

if(Judge&0x01)

{//IR.0=1接收中断

CanDataLength=RBSR&0x0f;//CAN数据报文的数据长度

p=&RBSR;

for(i=0;i<=(CanDataLength+5);i++)

{

RX_buffer[i]=*p++;

}

jidian=RX_buffer[6];

jidian=~jidian;

if(jidian)LED_GRE=1;

if(!

jidian)LED_GRE=0;

RXD_flag=1;//置有接收标志

CMR=0X04;

Judge=ALC;//释放仲裁随时捕捉寄存器

Judge=ECC;//释放错误代码捕捉寄存器

}

IER=0x01;//.0=1--接收中断使能;

EA=1;//打开CPU中断

}

voidmain(void)

{

CPU_init();//CPU初始化

CAN_init();//SJA1000初始化,对SJA1000寄存器的读写是采用外部寄存器寻址方式,所以不需要程序单独控制片选有效无效

_nop_();

_nop_();

while

(1)

{

_nop_();

_nop_();

Rxd_deal();//接收处理程序

Txd_deal();//发送处理程序

led_seg7(1,Txd_data);

led_seg7(3,Rxd_data);

}

}

//*********************处理函数********************************

//*********************CPU初始化函数********************************

voidCPU_init(void)

{//初始化CPU

SJA_RST=0;//CAN总线复位管脚有效

Delay(20);

SJA_RST=1;//CAN总线复位管脚无效

SJA_CS=0;//CAN总线片选有效

EX1=1;

IT1=0;//CAN总线接收中断

IT0=1;//外部中断0负边沿触发

EX0=1;//打开外部中断0

EA=1;//打开总中断

SJA_CS=1;//CAN总线片选无效,使对数据总线的操作不会影响SJA1000。

}

voidRxd_deal(void)

{////////接收处理程序//////////////

if(RXD_flag)

{

EA=0;//关闭CPU中断

RXD_flag=0;

if(RX_buffer[3]==0x10)//如果该报文传输的为按键计数

{

Rxd_data=RX_buffer[5];

}

EA=1;

}

}////////接收处理程序//////////////

voidTxd_deal(void)

{//发送处理函数,主要是准备数据,并且调用发送函数

if(TXD_flag==1)

{

_nop_();

TXD_flag=0;

TX_buffer[5]=Txd_data;//

TX_buffer[6]=jidian;

CAN_TXD();

_nop_();

_nop_();

}

}

//*********************处理函数********************************

//*********************CAN子函数***********************

voidCAN_init(void)

{//SJA1000的初始化

ucharbdataJudge;

ucharACRR[4];

ucharAMRR[4];

ACRR[0]=0xff;

ACRR[1]=0x02;

ACRR[2]=0xff;

ACRR[3]=0xff;//接收代码寄存器

AMRR[0]=0xff;

AMRR[1]=0X00;

AMRR[2]=0xff;

AMRR[3]=0xff;//接收屏蔽寄存器,只接收发往本节点的报文

do

{//.0=1---resetMODRe,进入复位模式,以便设置相应的寄存器

//防止未进入复位模式,重复写入

MODR=0x09;

Judge=MODR;

}

while(!

(Judge&0x01));

CDR=0x88;//CDR.3=1--时钟关闭,.7=0---basicCAN,.7=1---PeliCAN

BTR0=0x31;

BTR1=0x1c;//总线波特率设定

IER=0x01;//.0=1--接收中断使能;.1=0--关闭发送中断使能

OCR=0xaa;//配置输出控制寄存器

CMR=0x04;//释放接收缓冲器

ACR=ACRR[0];

ACR1=ACRR[1];

ACR2=ACRR[2];

ACR3=ACRR[3];//初始化标示码

AMR=AMRR[0];

AMR1=AMRR[1];

AMR2=AMRR[2];

AMR3=AMRR[3];//初始化掩码

do

{//确保退出复位模式

MODR=0x08;

Judge=MODR;

}

while(Judge&0x01);

}//SJA1000的初始化

voidCAN_TXD(void)

{

uchardataJudge;

//初始化标示码头信息

TX_buffer[0]=0x82;//.7=0扩展帧;.6=0数据帧;.3~0=1数据长度

TX_buffer[1]=0x02;//本节点地址

TX_buffer[2]=0x01;//

TX_buffer[3]=0x10;//

TX_buffer[4]=0x00;//

//初始化标示码头信息

//初始化发送数据单元

TX_buffer[5]=Txd_data;

TX_buffer[6]=jidian;

//初始化数据信息

EA=0;//关中断

do

{

Judge=SR;

LED_RED=0;//

}

while(Judge&0x10);//SR.4=1正在接收,等待

do

{

Judge=SR;

LED_RED=0;//

}

while(!

(Judge&0x08));//SR.3=0,发送请求未处理完,等待

do

{

Judge=SR;

LED_RED=0;//

}

while(!

(Judge&0

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

当前位置:首页 > IT计算机 > 互联网

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

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