📄 sja1000.h
字号:
#ifndef __SJA1000_H__
#define __SJA1000_H__
#define uint unsigned int
#define uchar unsigned char
#define ulong unsigned long
/***********************************************************
CAN总线寄存器地址定义
************************************************************/
#define MODE 0xbf00 //模式寄存器
#define CMR 0xbf01 //命令寄存器
#define SR 0Xbf02 //状态寄存器
#define IR 0Xbf03 //中断寄存器
#define IER 0Xbf04 //中断允许寄存器
#define BTR0 0xbf06 //总线定时寄存器0
#define BTR1 0xbf07 //总线定时寄存器1
#define OCR 0xbf08 //输出控制寄存器
#define ECC 0Xbf0C //错误代码寄存器
#define RXERR 0Xbf0e //接收错误计数器
#define TXERR 0Xbf0f ///发送错误计数器
#define ACR0 0Xbf10 //验收代码寄存器0
#define CANTX 0Xbf10 //报文发送缓冲区首址
#define CANRX 0Xbf10 //报文接受缓冲区首址
#define ACR1 0Xbf11 //验收代码寄存器1
#define ACR2 0Xbf12 //验收代码寄存器2
#define ACR3 0Xbf13 //验收代码寄存器3
#define AMR0 0Xbf14 //验收屏蔽寄存器0
#define AMR1 0Xbf15 //验收屏蔽寄存器1
#define AMR2 0Xbf16 //验收屏蔽寄存器2
#define AMR3 0Xbf17 //验收屏蔽寄存器3
#define CANDATA 0Xbf15 //数据部分的首地址
#define RMC 0Xbf1D //报文计数器
#define RBSA 0Xbf1E //RX缓冲区首地址
#define CDR 0xbf1f //时钟分频寄存器
/***********************************************************
CAN总线函数声明
************************************************************/
void init_sja(void); //SJA1000进入复位模式并初始化寄存器
void send_dframe(uchar *id,uchar *pointer); //发送一帧数据帧子程序
///void send_Fframe(void); //发送一帧远程帧子程序
/**************************************************************
SJA1000初始化程序
**************************************************************/
void init_sja(void) //SJA1000进入复位模式并初始化寄存器
{
uchar stata=0;
uchar xdata *nm_poin;
//进入复位状态
nm_poin=MODE; //选中SJA1000,使其进入复位模式
*nm_poin=0x01; //模式寄存器设置
//0000 1101-MOD.0->复位模式,MOD.1->正常模式
//MOD.2->自检测模式,MOD.3->单验收滤波器模式
while((stata&0x01)!=0x01) //必须确认SJA进入了复位模式
{
stata=*nm_poin;
}
//1 设置总线定时寄存器
nm_poin=BTR0; //BTR0 0x0006 总线定时寄存器0
*nm_poin=0xc9; //11001001总线定时寄存器0-系统时钟,同步跳转宽度
nm_poin=BTR1; //BTR1 0x0007 总线定时寄存器1
*nm_poin=0xA3; //总线定时寄存器1-波特率100K,采样次数3
//2 设置时钟分频寄存器
nm_poin=CDR; //CDR 0x001f 时钟分频寄存器
*nm_poin=0xc0; //时钟分频寄存器,1100 0000 PeliCAN,RX1不允许,CLKOUT不允许
//3 设置输出控制寄存器
nm_poin=OCR; //OCR 0x0008 输出控制寄存器
*nm_poin=0xaa; //输出控制寄存器,1010 1010 正常输出模式
//4 设置中断使能寄存器
nm_poin=IER; //IER 0X0004 中断使能寄存器
*nm_poin=0x0f; //0000 1111输入,总线出错,数据溢出中断允许
//IER.7->0->禁止总线错误中断使能
//IER.6->0->禁止总线仲裁丢失使能
//IER.5->0->禁止总线错误认可使能
//IER.4->0->禁止总线唤醒中断使能
//IER.3->1->允许数据溢出中断使能
//IER.2->1->允许出错报警中断使能
//IER.1->1->允许总线发送中断使能
//IER.0->1->允许总线接收中断使能
//总线中,共存在4种中断
//5 设置验收代码寄存器 4个字节
nm_poin=ACR0; //ACR0 0X0010 验收代码寄存器0
*nm_poin=00; //ACR0=0x00
nm_poin=ACR1; //ACR1 0X0011 验收代码寄存器1
*nm_poin=00; //ACR1=0x81
nm_poin=ACR2; //ACR2 0X0012 验收代码寄存器2
*nm_poin=0xff; //ACR2=0x00
nm_poin=ACR3; //ACR3 0X0013 验收代码寄存器3
*nm_poin=0xff; //ACR3=0x00/////////////////为0的ID标识符优先级最高
//验收代码 ff 7f 00 08
//6 设置验收屏蔽寄存器 4个字节
nm_poin=AMR0; //验收屏蔽 06 00 00 00
*nm_poin=0X00; //AMR0=0x00//均相关
nm_poin=AMR1;
*nm_poin=0x00; //AMR1=0x00//均相关
nm_poin=AMR2;
*nm_poin=0x00; //AMR2=0x00
nm_poin=AMR3;
*nm_poin=0x00; //AMR3=0x00
//7 设置接收缓冲区首址
nm_poin=RBSA; //接收缓冲区首址
*nm_poin=0; //首地址为00h
//8 设置发送错误计数器
nm_poin=TXERR; //错误计数
*nm_poin=0; //初始值为0
//9 设置错误代码寄存器
nm_poin=ECC; //错误代码值
*nm_poin=0; //初始值为0
//10 进入正常状态
nm_poin=MODE;////////////////////////////////////////////
*nm_poin=0x00; //单滤波设置,返回到工作状态
stata=0x01;
while((stata&0x01)==0x01) //必须确认SJA进入了工作模式
{
stata=*nm_poin;
}
}
/**************************************************************
发送一帧数据帧子程序
**************************************************************/
void send_dframe(uchar *id,uchar *pointer)
{
uchar s_state;//////////,frame_number=0x31,gw_number=0;
uchar xdata *nm_poin; //SJA1000地址变量指针
nm_poin=SR; //SR 0X0002 状态寄存器
s_state=0;
while(s_state!=0x0c) //检查各状态位 0000 1100 SR.2,SR.3=1表示发送缓冲器空,发送已完成,其它状态均不可发送数据
{
s_state=*nm_poin;
s_state=s_state&0x1c; //0001 1100检查三位状态,不能发则等待完成
}
//可以发送
nm_poin=CANTX; //CANTX 0X0010 报文发送缓冲区首址
*nm_poin=0x88; //1000 1000 扩展帧格式,数据帧,8个字节
nm_poin++; //验收代码 1
*nm_poin=id[0]; //id[0]
nm_poin++; //验收代码 2
*nm_poin=id[1]; //id[1]
nm_poin++; //验收代码 3
*nm_poin=id[2]; //id[2]
nm_poin++; //验收代码 4
*nm_poin=id[3]; //id[3]的高5位有效
//该帧的ID号为四个字节: 0x 31 00 00 31
//写入8个字节的数据
for(s_state=0;s_state<8;s_state++) //将数据送至发送缓冲区
{
nm_poin++;
(*nm_poin)=(*pointer);
pointer++;
}
nm_poin=CMR;
*nm_poin=0X01; //启动发送
}
#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -