CAN总线之saj1000与82c250应用源程序.docx

上传人:b****8 文档编号:10324990 上传时间:2023-02-10 格式:DOCX 页数:12 大小:20.05KB
下载 相关 举报
CAN总线之saj1000与82c250应用源程序.docx_第1页
第1页 / 共12页
CAN总线之saj1000与82c250应用源程序.docx_第2页
第2页 / 共12页
CAN总线之saj1000与82c250应用源程序.docx_第3页
第3页 / 共12页
CAN总线之saj1000与82c250应用源程序.docx_第4页
第4页 / 共12页
CAN总线之saj1000与82c250应用源程序.docx_第5页
第5页 / 共12页
点击查看更多>>
下载资源
资源描述

CAN总线之saj1000与82c250应用源程序.docx

《CAN总线之saj1000与82c250应用源程序.docx》由会员分享,可在线阅读,更多相关《CAN总线之saj1000与82c250应用源程序.docx(12页珍藏版)》请在冰豆网上搜索。

CAN总线之saj1000与82c250应用源程序.docx

CAN总线之saj1000与82c250应用源程序

CAN总线之saj1000与82c250应用源程序,基于c8051f340单片机平台。

2009年04月19日星期日10:

58

定义头文件:

s.h

voidCanInit();

voidCanSend(unsignedchar*bufDATA,unsignedchardatalen);

voidPort_IO_Init();

voidOscillator_Init();

voidInit_Device(void);

voidWR_SJA(unsignedcharsja_addr,unsignedcharsja_data);

unsignedcharRD_SJA(unsignedcharsja_addr);

//******SJA1000内部寄存器地址(初始化复位模式)PeliCAN模式的地址表.

//******标准帧格式(SFF)与扩展帧格式(EFF).

#defineSJA_MOD0   /*模式寄存器可以定义过滤模式MOD.3=AFM00H*/

#defineSJA_CMR1     //命令寄存器

#defineSJA_SR  2     //状态寄存器

#defineSJA_IR  3  //中断标志        03

#defineSJA_IER4    /*中断允许04H*/

#defineSJA_BTR06    /*总线定时器0  06H*/

#defineSJA_BTR17     /*总线定时器1  07H*/

#defineSJA_OCR  8     /*输出控制  08H*/

#defineSJA_ALC11  //仲裁丢失捕捉    11          

#defineSJA_ECC12      /*错误代码捕捉0CH*/

#defineSJA_EWLR13    //错误报警限制寄存器

#defineSJA_RXERR14     //错误计数寄存器

#defineSJA_TXERR15    /*发送错误记数0FH*/

//以下为复位模式定义

#defineSJA_ACR016     /*验收代码即ID?

16*/

#defineSJA_ACR117     /*验收代码即ID  17*/

#defineSJA_ACR218     /*验收代码即ID  18*/

#defineSJA_ACR319     /*验收代码即ID  19*/

#defineSJA_AMR020    /*验收屏蔽初地址20*/

#defineSJA_AMR121     /*验收屏蔽初地址21*/

#defineSJA_AMR222     /*验收屏蔽初地址22*/

#defineSJA_AMR323     /*验收屏蔽初地址23*/

//SJA1000内部寄存器地址(工作模式)

#defineSJA_EFF16     //RX和TX结构信息扩展帧/标准帧

#defineSJA_ID117     //识别码

#defineSJA_ID218     //识别码

#defineSJA_ID319     //识别码,标准帧无

#defineSJA_ID420     //识别码,标准帧无

#defineSJA_D121     //

#defineSJA_D222    

#defineSJA_D323     

#defineSJA_D424     

#defineSJA_D525   

#defineSJA_D626     

#defineSJA_D727   

#defineSJA_D828     //////////////

单片机程序如下:

#include

#include

#include"s.h"

//模块程序测试--CAN主动发送与中断接收。

//版本号:

V1.2

//                  c8051f340

//            -----------------

//(低有效)led1|P2.0      P3.0|-->P1继电器(低有效)上

//       led2|P2.1          P3.1|-->P2继电器    下

//          SDA|P2.2I2C     |

//          SCL|P2.3          |

//           |              |

//          AD0|P1.0            |

//           *|*          |

//(CAN通信)  *|*           |

//          AD7|P1.7              |

//           |              |

//   CS_CAN|P0.3              |

//          ALE|P0.0          |

//           RD|P0.1          |

//           WR|P2.7          |

//       INTCAN|P0.2          |

//           |              |

//

//

sbitled1   =P2^0;

sbitled2   =P2^1;

sbitSDA   =P2^2;

sbitSCL   =P2^3;

sbitJ1    =P3^0;

sbitJ2    =P3^1;

sbitst1   =P0^4;

sbitALE_CAN=P0^0;

sbitRD_CAN  =P0^1;

sbitINT_CAN=P0^2;

sbitCS_CAN  =P0^3;

sbitWR_CAN  =P2^7;

#defineWriteDeviceAddress0xa0//地址以及读写方向,本设备中只有一个IIC设备地址为0

#defineReadDviceAddress0xa1

#defineucharunsignedchar

#defineuintunsignedint

#definenop_nop_

ucharc1[16]={0X00,0X01,0X02,0X03,0X04,0X05,0X06,0X07,0X08,0X09,0X0a,0X0b,0X0c,

       0X0d,0X0e,0X0f};

ucharc2[16];

ucharc3[8]={0X00,0X01,0X02,0X03,0X04,0X05,0X06,0X07};

unsignedintidataMaxLenCanRxBuf=440;

unsignedcharxdataCanRxBuf[440];   //40个CAN帧缓冲区

unsignedcharidataCanTempBuf[11];  //单个can报文的缓冲区。

unsignedcharidataCanTxData[8];  //CAN发送数据缓冲区

unsignedchardata_flag=0;

unsignedintidataCanRxAddr=0;

unsignedcharCanRxcompleteFlag=0;

unsignedcharidatacfgbuf[32];

unsignedcharSendBufId[2]={0x07,0x20};//这个值要自己设定,现在只是测试程序代码假设的一个值11位标示符的格式,后3位可选值为20,,60,40,80,a0,e0

unsignedcharSendBufInfo;

unsignedintxdatamSendDelay=0;

unsignedchar*h_pointer;

unsignedchar*l_pointer;

unsignedchari=0;

unsignedcharj=0;

uintLedFlag1=0;

voidDelayMs(unsignedintnumber)

{

unsignedinttemp;

for(;number!

=0;number--)

  {

  for(temp=3066;temp!

=0;temp--);//forc8051

}

}

voiddelay(intnum)

{

intvalue;

unsignedcharjj;

value=num*5;

for(jj=0;jj

}

voiddelay2(intnum)

{

unsignedcharjj=0;

for(jj=0;jj

}

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

*函数名:

CanInit(void)

*功能描述:

CAN的初始化设置,在复位模式下设置CAN为单滤波,正常模式,PeliCAN模式,不屏蔽,8*     字节数据位

*函数说明:

通过ALE,RD,CS的配合控制完成

*调用函数:

NONE

*全局变量:

NONE

*输入:

*返回:

*设计者:

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

voidCanInit(void)

{

unsignedchartempMode;

unsignedchartemp7=0;

unsignedchartemp8=0;

tempMode=0x01;    //复位模式

tempMode|=0x08;    //设置CAN为单滤波,选择单个验收滤波器(32位长度)

tempMode|=0x00;    //正常模式,这句话貌似没有实际意义?

  WR_SJA(SJA_MOD,tempMode);  //模式寄存器进入复位模式

   temp7=RD_SJA(SJA_MOD);   //设置的变量用来查看前面的写入是否成功。

   WR_SJA(SJA_CDR,0x0C8);  //时钟分频选择PeliCAN模式终止can输入比较器关闭时钟输出CLKOUT

   temp8=RD_SJA(SJA_CDR);

WR_SJA(SJA_AMR0,0xff);  //验收屏蔽位设置,不影响

WR_SJA(SJA_AMR1,0xff);

WR_SJA(SJA_AMR2,0xff);

WR_SJA(SJA_AMR3,0xff);

WR_SJA(SJA_ACR0,0x80);    //验收代码位设置扩展祯数据8字节

WR_SJA(SJA_ACR1,0x00);

WR_SJA(SJA_ACR2,0x00);

WR_SJA(SJA_ACR3,0x00);

WR_SJA(SJA_BTR0,0x00);         //设置CAN波特率为500k通过波特率计算器可以算出该值

WR_SJA(SJA_BTR1,0x1c);

temp7=RD_SJA(SJA_BTR0);

temp8=RD_SJA(SJA_BTR1);

mSendDelay=1000;

WR_SJA(SJA_IER,0x01);   //中断允许打开接收中断使能

WR_SJA(SJA_OCR,0x0da);  //输出控制驱动上拉正常输出模式

WR_SJA(SJA_MOD,tempMode&0xFE);//模式寄存器退出复位模式

}

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

*函数名:

voidcan_rx_isr(void)interrupt0

*功能描述:

sja1000CAN接收中断函数

*函数说明:

在响应接收中断的时候,完成数据的接收。

问题是现在sja的数据根本读不出来RD_SJA()函数问题。

*调用函数:

NONE

*全局变量:

NONE

*输入:

*返回:

*设计者:

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

voidcan_rx_isr(void)interrupt0     //sja1000CAN接收中断

{

unsignedchark=0;

unsignedcharsja_addr;

EA=0;

/***!

RD_SJA(SJA_IR)读出来的值为0xff,所以也可以通过进入读环节。

****************************/                //关CPU中断

if((RD_SJA(SJA_IR)&0x01)==0x01)  //IR中断寄存器,当接收FIFO不空和接收中断使能时置位此位

{

  sja_addr=SJA_EFF;      //register17.datastartaddress

  if(CanRxAddr==MaxLenCanRxBuf)//unsignedintidataMaxLenCanRxBuf=440.

   CanRxAddr=0;

  for(k=0;k<11;k++)      //完成11位标准帧数据的接收过程。

{

  CanRxBuf[CanRxAddr+k]=RD_SJA(sja_addr);

   sja_addr++;

  }

  

  WR_SJA(SJA_CMR,0x04);    //释放接收缓冲区

  CanRxAddr+=11;

  CanRxcompleteFlag+=1;  //接收完一次完整的数据报文以后该标志位加1.

}

EA=1;//打开CPU中断

}

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

*函数名:

CanSend(unsignedchar*bufDATA,unsignedchardatalen)

*功能描述:

Can设备数据发送函数

*函数说明:

*调用函数:

NONE

*全局变量:

NONE

*输入:

*返回:

*设计者:

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

voidCanSend(unsignedchar*bufDATA,unsignedchardatalen)

{

unsignedintsja_addr;

unsignedcharj=0;

unsignedchartemp;      //局部变量

unsignedintn;

//CanLedFlag=1;

sja_addr=SJA_EFF;      //取SJA的ID号的首地址地址,ID0的地址。

SendBufInfo=datalen;     //填入数据长度信息

WR_SJA(sja_addr++,SendBufInfo);    //以标准帧发送消息

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

    WR_SJA(sja_addr+j,*(SendBufId+j));//发送两字节的id信息。

for(j=0;j

    WR_SJA(sja_addr+2+j,*(bufDATA+j));//发送data区数据。

WR_SJA(SJA_CMR,0x03);     //打开发送请求位与终止发送位,Send正常发送

for(n=0;n

{

  temp=RD_SJA(SJA_SR);    //读取状态寄存器SR.3--TCS发送完毕状态1(完毕)

  if((temp&0x08)==0x08)    //发送完毕

  {

   for(n=0;n<300;n++);    //延时

   break;

  }

}

}

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

*函数名:

WR_SJA(unsignedcharsja_addr,unsignedcharsja_data)

*功能描述:

完成先准备相应sja_addr地址,再在相应的sja_addr地址操作送sja_data数据的       过程

*函数说明:

通过ALE切换地址与数据位的操作

*调用函数:

NONE

*全局变量:

NONE

*输入:

*返回:

*设计者:

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

voidWR_SJA(unsignedcharsja_addr,unsignedcharsja_data)

{

ALE_CAN=1;//置高开启地址锁存允许,将io口的地址数据锁存。

P1=sja_addr;

delay2(3);

   

ALE_CAN=0;//置低关闭地址锁存允许,改为发送数据有效。

delay2

(1);

CS_CAN=0;

WR_CAN=0;

P1=sja_data;

delay2(4);

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

WR_CAN=1;

CS_CAN=1;//恢复到操作前的状态,避免影响单片机对sja1000误操作。

ALE_CAN=1;

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

}

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

*函数名:

RD_SJA(unsignedcharsja_addr)

*功能描述:

完成先准备相应sja_addr地址,再将该地址的数据读出到sja_data的过程

*函数说明:

通过ALE,RD,CS的配合控制完成

*调用函数:

NONE

*全局变量:

NONE

*输入:

*返回:

*设计者:

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

/*unsignedcharRD_SJA(unsignedcharsja_addr)

{

unsignedcharsja_data=0;

CS_CAN=0;//使能片选

ALE_CAN=1;//置高开启地址锁存允许,将io口的地址数据锁存。

delay2

(2);

P1=sja_addr;

ALE_CAN=0;//置低关闭地址锁存允许,改为发送数据有效。

delay2(4);

RD_CAN=0;//使能读有效

sja_data=P1;

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

ALE_CAN=1;

RD_CAN=1;//此处的3个使能一起操作,前面的写地址与写命令一样的原理

CS_CAN=1;

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

returnsja_data;

}*/

unsignedcharRD_SJA(unsignedcharsja_addr)

{

unsignedcharsja_data;

ALE_CAN=1;//置高开启地址锁存允许,将io口的地址数据锁存。

P1=sja_addr;

delay2(3);

ALE_CAN=0;//置低关闭地址锁存允许,改为发送数据有效。

delay2

(1);

CS_CAN=0;//使能片选

P1=0xFF;  //端口初始化

RD_CAN=0;//使能读有效

delay2(4);

sja_data=P1;

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

RD_CAN=1;//此处的3

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

当前位置:首页 > 求职职场 > 简历

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

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