CAN总线的实现SJA1000实例.docx
- 文档编号:23920484
- 上传时间:2023-05-22
- 格式:DOCX
- 页数:15
- 大小:18.58KB
CAN总线的实现SJA1000实例.docx
《CAN总线的实现SJA1000实例.docx》由会员分享,可在线阅读,更多相关《CAN总线的实现SJA1000实例.docx(15页珍藏版)》请在冰豆网上搜索。
CAN总线的实现SJA1000实例
一、
以下是我做的CAN节点的测试程序,实现两个节点传送数据,程序主要分三部分SJA1000的初始化,接收数据,发送数据.
/****************************************************
**函数原型:
bitSja_1000_Init(void)
**功 能:
初始化SJA10000
**入口参数:
无
**返回值:
0:
初始化成功
1:
复位失败
2:
测试sja1000失败
3:
设置失败
4:
设置验收滤波器失败
5:
设置波特率失败
*****************************************************/
unsignedcharSja_1000_Init(void)
{
bits;
EA=0;
s=BCAN_ENTER_RETMODEL();
if(s==1)return1;
s=BCAN_CREATE_COMMUNATION();
if(s==1)return2;
s=BCAN_SET_OUTCLK(0xc0); *
********************************************************************/
bitBCAN_SET_OBJECT(unsignedchar BCAN_ACR0,BCAN_ACR1,BCAN_ACR2,BCAN_ACR3,BCAN_AMR0,BCAN_AMR1,BCAN_AMR2,BCAN_AMR3)
{
SJA_BCANAdr=REG_TxBuffer1;
*SJA_BCANAdr=BCAN_ACR0; JA1000的晶振必须为16MHz, *
;* 其它晶体的频率的值的波特率,需自己计算。
该子程序只能用于 *
;* 复位模式 *
;******************************************************************/
bitBCAN_SET_BANDRATE(unsignedintCAN_ByteRate)
{
//将波特率的的预设值装入sja1000的总线定时器
SJA_BCANAdr=REG_BTR0;
*SJA_BCANAdr=CAN_ByteRate>>8; //取CAN_ByteRate的高8位写入写入参数
//校验写入值
if(*SJA_BCANAdr!
=(CAN_ByteRate>>8))return1;
SJA_BCANAdr=REG_BTR1;
*SJA_BCANAdr=CAN_ByteRate;
//校验写入值
if(*SJA_BCANAdr!
=CAN_ByteRate)return1;
return0;
}
/********************************************************************
*函数原型:
bitBCAN_SET_CONTROL(unsigendcharCMD) *
*参数说明:
设置控制寄存器 *
*******************************************************************/
bitBCAN_SET_CONTROL(unsignedcharCMD)
{
unsignedcharTempData;
SJA_BCANAdr=REG_CONTROL; //SJA_BaseAdr+0x00 控制寄存器
TempData= *SJA_BCANAdr;
*SJA_BCANAdr=CMD;
if(*SJA_BCANAdr==CMD)
return0;
else
return1;
}
/********************************************************************
*函数原型:
bit BCAN_CREATE_COMMUNATION(void) *
*参数说明:
无 *
*返回值:
*
* 0;表示SJA1000接口正常 *
* 1;表示SJA1000与处理器接口不正常 *
*说明:
该函数用于检测CAN控制器的接口是否正常 *
*******************************************************************/
bitBCAN_CREATE_COMMUNATION(void)
{
SJA_BCANAdr=REG_TEST;
*SJA_BCANAdr=0xaa; //写入测试值
if(*SJA_BCANAdr==0xaa)
return0; //读测试正确
else
return1;
}
/******************************************************************
*函数原型:
bit BCAN_ENTER_RETMODEL(void) *
*参数说明:
无 *
*返回值:
*
* 0;表示成功进入复位工作模式 *
* 1;表示不能进入复位工作模式 *
* *
*说明:
CAN控制器进入复位工作模式 *
*******************************************************************/
bit BCAN_ENTER_RETMODEL(void) //置位复位请求
{
unsigned char TempData;
SJA_BCANAdr =REG_CONTROL;
TempData= *SJA_BCANAdr;
*SJA_BCANAdr=0x01; //置位复位请求
if((*SJA_BCANAdr&0x01)==1)
return 0;
else
return 1;
}
/****************************************************
**函数原型:
voidex0_int(void)interrupt0//using1
**功 能:
中断接收函数
**入口参数:
无
**出口参数:
RevceData[]数组
**说 明:
当sja1000收到正确的报文时,会产生int中断
*****************************************************/
voidex0_int(void)interrupt0//using1
{
unsignedchartt;
SJA_BCANAdr=REG_INTERRUPT;
if((*SJA_BCANAdr)&0x01) //产生了接收中断
{
SJA_BCANAdr=REG_RxBuffer1;
tt=*SJA_BCANAdr;
if((tt&0x40)!
=0x40)//数据帧 =为远程帧
{
memcpy(REG_RxBuffer6,RevceData,8);
send_char_com(RevceData[1]);//以下代码是发送到串口
send_char_com(RevceData[2]);
send_char_com(RevceData[3]);
send_char_com(RevceData[4]);
send_char_com(RevceData[5]);
send_char_com(RevceData[6]);
send_char_com(RevceData[7]);
send_char_com(RevceData[8]);
}
BCAN_CMD_PRG(4);//释放SJA1000接收缓冲区
}
}
unsignedcharBCAN_DATA_WRITE(unsignedchar*SendDataBuf)
{
unsignedchartemp;
SJA_BCANAdr=REG_STATUS;
temp=*SJA_BCANAdr;
if((temp&0x08)==0)return 1; //上次发送未完成
if((temp&0x04)==0)return 2; //发送缓冲区是否锁定
if((temp&0x10)==0x10)return3; //判断是否正在接收
SJA_BCANAdr=REG_TxBuffer1; //访问地址指向发送缓冲区1
memcpy(SJA_BCANAdr,SendDataBuf,13);
BCAN_CMD_PRG(0x03);
return0;
}
bit BCAN_CMD_PRG(unsignedcharcmd)
{
SJA_BCANAdr=REG_COMMAND; //访问地址指向命令寄存器
*SJA_BCANAdr=cmd; //启动命令字
switch(cmd)
{
case TR_CMD:
return 0;
break;
case SRR_CMD:
return 0;
break;
case AT_CMD:
SJA_BCANAdr=REG_STATUS; //访问地址指向状态寄存器
if((*SJA_BCANAdr&0x20)==0)//判断是否正在发送
return 0;
else
return 1;
break;
case RRB_CMD:
SJA_BCANAdr=REG_STATUS; //访问地址指向状态寄存器
if((*SJA_BCANAdr&0x01)==1)
return 1;
else
return 0;
break;
case COS_CMD:
SJA_BCANAdr=REG_STATUS;
if((*SJA_BCANAdr&0x02)==0)//判断清除超载是否成功
return 0;
else
return 1;
break;
default:
return 1;
break;
}
}
主程序部分:
voidmain(void)
{
unsignedchartemptt,ss;
CS=0;
Init_Cpu();
EA=0;
//initializeSja1000
ss=Sja_1000_Init();
if(ss!
=0)//初始化失败
send_string_com("initfail!
");
else
EA=1;//初始化成功,开中断
RECOK=0;
send_data[0]=Send_CAN_Info_ID[0];
send_data[1]=Send_CAN_Info_ID[1];
send_data[2]=Send_CAN_Info_ID[2];
send_data[3]=Send_CAN_Info_ID[3];
send_data[4]=Send_CAN_Info_ID[4];
while
(1)
{
SJA_BCANAdr=REG_STATUS;
temptt=*SJA_BCANAdr;
if((temptt&0x40)==0x40)
{
Sja_1000_Init();
send_char_com(0xee);
}
if(RECOK==1)
{
RECOK=0;
SJA_BCANAdr=REG_STATUS;
temptt=*SJA_BCANAdr;
if((temptt&0x04)==0x04)//可以向发送缓冲器写数据
{
send_data[5]=Com_RecBuff[0];
send_data[6]=Com_RecBuff[1];
send_data[7]=Com_RecBuff[2];
send_data[8]=Com_RecBuff[3];
send_data[9]=Com_RecBuff[4];
send_data[10]=Com_RecBuff[5];
send_data[11]=Com_RecBuff[6];
send_data[12]=Com_RecBuff[7];
ss=BCAN_DATA_WRITE(send_data);
if(ss==0) //发送正常
send_char_com(0x11);
else
{
send_char_com(0xFF);
send_char_com(ss);
SJA_BCANAdr=REG_ECC;
send_char_com(*SJA_BCANAdr);
}
}
}
}
}
二、can总线通讯程序(c) sja1000
nnyt原创经典,如需更多帮助,请联系我:
(短信联系,QQ详谈)
本人同时提供can实验开发板给初学者
1CAN控制器为SJA1000,驱动器为TJA1050,电源隔离;
2提供详尽的源程序,可根据用户需求编写程序
#include<>//单片机头文件
#include<>//SJA存储器定义头文件
#include<>//SJA子程序文件
/*************************函数声明*******************************/
voidInit_T0(void);//初始化单片机T0
voidSja_1000_Init(void);//初始化SJA
//*******************************************************************
bitflag_sec;//发送命令标志
unsignedchardatasend_data[10],rcv_data[10];//发送和接收数组
unsignedcharsec_data,second;//定时器记数变量,发送数据变量
unsignedchardataTmod_data;//定时器T0工作方式变量
unsignedcharbdataflag_init;//中断寄存器数据保存变量
sbitrcv_flag=flag_init^0;//接收中断标志
sbiterr_flag=flag_init^2;//错误中断标志
sbitP2_0=P2^0;
sbitP3_4=P3^4;
sbitLED=P3^5;//指示灯
//***********************************************************
voidex0_int(void)interrupt0using1//外部中断0
{
SJA_BCANAdr=REG_INTERRUPT;//指针指向中断寄存器
flag_init=*SJA_BCANAdr;//保持中断寄存器值
}
//***********************************************************
voidT0_int(void)interrupt1using2//定时器T0中断服务子程序
{
TR0=0;//关闭定时器T0
sec_data--;//秒计时变量减一
if(sec_data==0)//秒时间到了吗
{
sec_data=0x50;//重新赋值
TH0=0x80;
TL0=0x60;
flag_sec=1;//设置标志位
second++;//发送的数据加一
}
TR0=1;//启动定时器T0
}
//************************************************************
voidInit_T0(void)//初始化定时器0
{
Tmod_data=TMOD;
Tmod_data&=0xf0;
Tmod_data|=0x01;
TMOD=Tmod_data;//定时器T0工作方式设置
TH0=0x80;
TL0=0x60;//定时器T0初值设置
TR0=1;//开放定时器T0
sec_data=0x20;//记数值设置
second=0x00;//发送数据初始化清零
}
//***********************************************************
voidSja_1000_Init(void)
{
BCAN_ENTER_RETMODEL();//进入复位
BCAN_SET_BANDRATE(0x0b);//800K
BCAN_SET_OBJECT(0xaa,0xff);//设置地址ID:
557
BCAN_SET_OUTCLK(0xaa,0x48);//设置输出方式,禁止COLOCKOUT输出
BCAN_QUIT_RETMODEL();//退出复位模式
SJA_BCANAdr=REG_CONTROL;//地址指针指向控制寄存器
*SJA_BCANAdr|=0x1E;//开放错误\接收\发送中断
}
//*******************************************************************
voidmain(void)
{
P2_0=0;//SJA1000退出硬件复位模式
Sja_1000_Init();//initializeSja100
Init_T0();//initializeT0
PX0=1;//外部中断0高优先级
IT0=1;//开放T0中断
EX0=1;//外部中断0开放
ET0=1
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- CAN 总线 实现 SJA1000 实例