📄 basiccan.c
字号:
#include<reg52.h>
#include <string.h>
#define uchar unsigned char
#define uint unsigned int
#define SJA_BaseAdr 0x0000 //定义sja1000的片选基址
//计算SJA1000在电路中的实际地址:基址+内部寄存器地址
/************************************************************************
* 以下的定义为SJA1000的内部寄存器的地址,不可修改 *
* 各寄存器的具体功能清参阅sja1000的数据手册 *
************************************************************************/
#define REG_CONTROL SJA_BaseAdr+0x00 //内部控制寄存器
#define REG_COMMAND SJA_BaseAdr+0x01 //命令寄存器
#define REG_STATUS SJA_BaseAdr+0x02 //状态寄存器
#define REG_INTERRUPT SJA_BaseAdr+0x03 //中断寄存器
#define REG_ACR SJA_BaseAdr+0x04 //验收代码寄存器
#define REG_AMR SJA_BaseAdr+0x05 //验收屏蔽寄存器
#define REG_BTR0 SJA_BaseAdr+0x06 //总线定时寄存器0
#define REG_BTR1 SJA_BaseAdr+0x07 //总线定时寄存器1
#define REG_OCR SJA_BaseAdr+0x08 //输出控制寄存器
#define REG_TEST SJA_BaseAdr+0x09 //测试寄存器
//以下为发送缓冲区寄存器定义
#define REG_TxBuffer1 SJA_BaseAdr+0x0A //发送缓冲区1
#define REG_TxBuffer2 SJA_BaseAdr+0x0B //发送缓冲区2
#define REG_TxBuffer3 SJA_BaseAdr+0x0C //发送缓冲区3
#define REG_TxBuffer4 SJA_BaseAdr+0x0D //发送缓冲区4
#define REG_TxBuffer5 SJA_BaseAdr+0x0E //发送缓冲区5
#define REG_TxBuffer6 SJA_BaseAdr+0x0F //发送缓冲区6
#define REG_TxBuffer7 SJA_BaseAdr+0x10 //发送缓冲区7
#define REG_TxBuffer8 SJA_BaseAdr+0x11 //发送缓冲区8
#define REG_TxBuffer9 SJA_BaseAdr+0x12 //发送缓冲区9
#define REG_TxBuffer10 SJA_BaseAdr+0x13 //发送缓冲区10
//以下为接收缓冲区寄存器定义
#define REG_RxBuffer1 SJA_BaseAdr+0x14 //接收缓冲区1
#define REG_RxBuffer2 SJA_BaseAdr+0x15 //接收缓冲区2
#define REG_RxBuffer3 SJA_BaseAdr+0x16 //接收缓冲区3
#define REG_RxBuffer4 SJA_BaseAdr+0x17 //接收缓冲区4
#define REG_RxBuffer5 SJA_BaseAdr+0x18 //接收缓冲区5
#define REG_RxBuffer6 SJA_BaseAdr+0x19 //接收缓冲区6
#define REG_RxBuffer7 SJA_BaseAdr+0x1A //接收缓冲区7
#define REG_RxBuffer8 SJA_BaseAdr+0x1B //接收缓冲区8
#define REG_RxBuffer9 SJA_BaseAdr+0x1C //接收缓冲区9
#define REG_RxBuffer10 SJA_BaseAdr+0x1D //接收缓冲区10
/************************************************************************
*内部地址 01EH 备用 *
************************************************************************/
/************************************************************************
*时钟分频寄存器(内部地址01FH) *
************************************************************************/
#define REG_CDR SJA_BaseAdr+0x1F //时钟分频寄存器
uchar xdata *SJA_BCANAdr;//定义指向片外RAM的指针(SJA1000的基址)
static uchar data BandRateBuf;//用于保存当前要设置的波特率
static uchar idata send_data[10];//用于缓存将要发送的数据
static uchar idata code_led[20]={0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x67,0x77,0x7C,0x39,0x5E,0x79,0x71,0x40,0x76,0x73,0x38};
//依次表示0,1,2,3,4,5,6,7,8,9,A,b,C,d,E,F,-,H,P,L
static uchar data SetSystemBuf[4]={0,0,0,0};//用于显示的数据缓冲区
static uint idata band_rate[13]={20,40,50,80,100,125,200,250,400,500,666,800,1000};//用于显示选择的波特率
sbit P20=P2^0;
sbit sja=P2^0;
sbit P32=P3^2;
sbit P17=P1^7;//74LS373N的选通信号
sbit P14=P1^4;//LED灯的选择信号
sbit P15=P1^5;
sbit P16=P1^6;//蜂鸣器的选通信号
sbit ST=P3^0;//ADC0809的选通信号
sbit OE=P3^1;
/************************************************************************
*定义命令字 *
************************************************************************/
#define TR_CMD 0x01 //发送请求命令
#define AT_CMD 0x02 //夭折发送命令
#define RRB_CMD 0x04 //释放接收缓冲区
#define COS_CMD 0x08 //清除超载状态
#define GTS_CMD 0x10 //进入睡眠状态命令
/************************************************************************
*定义16M的晶体下,CAN总线波特率 *
************************************************************************/
#define ByteRate_20k 0x00 //波特率20kbps
#define ByteRate_40k 0x01 //波特率40kbps
#define ByteRate_50k 0x02 //波特率50kbps
#define ByteRate_80k 0x03 //波特率80kbps
#define ByteRate_100k 0x04 //波特率100kbps
#define ByteRate_125k 0x05 //波特率125kbps
#define ByteRate_200k 0x06 //波特率200kbps
#define ByteRate_250k 0x07 //波特率250kbps
#define ByteRate_400k 0x08 //波特率400kbps
#define ByteRate_500k 0x09 //波特率500kbps
#define ByteRate_666k 0x0a //波特率666kbps
#define ByteRate_800k 0x0b //波特率800kbps
#define ByteRate_1000k 0x0c //波特率1000kbps
/*-------------------------------------------------------------------------------------------
* 以下为BASICCAN SJA1000的错误字 *
-------------------------------------------------------------------------------------------*/
#define CAN_INTERFACE_0K 0 /*SJA1000接口正常 */
#define CAN_BUS_0K 0 /*CAN总线工作正常 */
#define CAN_INTERFACE_ERR 0XFF /*SJA1000接口错误? */
#define CAN_ENTRESET_ERR 0XFE /*SJA1000不能进入复位模式 */
#define CAN_QUITRESET_ERR 0XFD /*SJA1000不能退出复位模式 */
#define CAN_INITOBJECT_ERR 0XFC /*初始化报文验收滤波器错 */
#define CAN_INITBTR_ERR 0XFB /*初始化总线波特率错 */
#define CAN_INITOUTCTL_ERR 0XFA /*初始化输出控制错误 */
#define CAN_INTCLKDIV_ERR 0XF9 /*初始化时钟分频控制器错 */
#define CAN_BUS_ERR 0XF8 /*SJA1000发送数据错 */
//延时
void delay_ms(uint n)
{
uint k,j;
for(k=0;k<n;k++)
{
for(j=0;j<500;j++);
}
}
/************************************************************************
*以下为基本的函数说明(BasicCAN) *
************************************************************************/
/************************************************************************
*函数原型: bit BCAN_CREATE_COMMUNATION(void) *
*参数说明: 无 *
*返回值: *
* 0 ; 表示SJA1000接口正常 *
* 1 ; 表示SJA1000与处理器接口不正常 *
* *
*说明:该函数用于检测CAN控制器的接口是否正常 *
************************************************************************/
bit BCAN_CREATE_COMMUNATION(void)
{
SJA_BCANAdr=REG_TEST; //访问测试寄存器
*SJA_BCANAdr =0xaa; //写入测试值
if(*SJA_BCANAdr == 0xaa)
{
return 0; //读测试正确
}
else
{
return 1;
}
}
/************************************************************************
*函数原型: bit BCAN_ENTER_RETMODEL(void) *
*参数说明: 无 *
*返回值: *
* 0 ; 表示成功进入复位工作模式 *
* 1 ; 表示不能进入复位工作模式 *
* *
*说明: CAN控制器进入复位工作模式 *
************************************************************************/
bit BCAN_ENTER_RETMODEL(void)
{
uchar TempData;
SJA_BCANAdr = REG_CONTROL; //访问地址指向控制寄存器
TempData= *SJA_BCANAdr; //保存原始值
*SJA_BCANAdr=(TempData|0x01); //置位复位请求
if((*SJA_BCANAdr&0x01) == 1)
{
return 0;
}
else
{
return 1;
}
}
/************************************************************************
*函数原型: bit BCAN_QUIT_RETMODEL(void) *
*参数说明: 无 *
*返回值: *
* 0 ; 表示成功退出复位工作模式 *
* 1 ; 表示不能退出复位工作模式 *
* *
*说明: CAN控制器退出复位工作模式 *
************************************************************************/
bit BCAN_QUIT_RETMODEL(void)
{
uchar TempData;
SJA_BCANAdr = REG_CONTROL; //访问地址指向控制寄存器
TempData = *SJA_BCANAdr; //保存原始值
*SJA_BCANAdr=(TempData&0xfe); //清除复位请求
if((*SJA_BCANAdr&0x01) == 0)
{
return 0; //退出成功
}
else
{
return 1; //
}
}
/************************************************************************
;*函数原型: bit BCAN_SET_BANDRATE(uchar CAN_ByteRate) *
;*参数说明: R7 波特率(Kbit/s) BTR0 BTR1 *
;* 0 20 053H, 02FH *
;* 1 40 087H, 0FFH *
;* 2 50 047H, 02FH *
;* 3 80 083H, 0FFH *
;* 4 100 043H, 02fH *
;* 5 125 03H, 01cH *
;* 6 200 081H, 0faH *
;* 7 250 01H, 01cH *
;* 8 400 080H, 0faH *
;* 9 500 00H, 01cH *
;* 10 666 080H, 0b6H *
;* 11 800 00H, 016H *
;* 12 1000 00H, 014H *
;*返回值: *
;* 0 ;波特率设置成功 *
;* 1 ;波特率设置失败 *
;* *
;*说明:设置CAN控制器SJA1000通讯波特率.SJA1000的晶振为必须为16MHZ, *
;* 其它晶体的频率的值的波特率,需自己计算 。该子程序只能用于 *
;* 复位模式 *
;************************************************************************/
unsigned char code SJA_BTR_CODETAB[]={
0x53,0x2F, //;20KBPS的预设值
0x87,0xFF, //;40KBPS的预设值
0x47,0x2F, //;50KBPS的预设值
0x83,0xFF, //;80KBPS的预设值
0x43,0x2f, //;100KBPS的预设值
0x03,0x1c, //;125KBPS的预设值
0x81,0xfa, //;200KBPS的预设值
0x01,0x1c, //;250KBPS的预设值
0x80,0xfa, //;400KBPS的预设值
0x00,0x1c, //;500KBPS的预设值
0x80,0xb6, //;666KBPS的预设值
0x00,0x16, //;800KBPS的预设值
0x80,0x23 //;1000KBPS的预设值
};
bit BCAN_SET_BANDRATE(uchar CAN_ByteRate)
{
uchar BTR0_num,BTR1_num;
BTR0_num = SJA_BTR_CODETAB[CAN_ByteRate*2];
BTR1_num = SJA_BTR_CODETAB[CAN_ByteRate*2+1];
//将波特率的的预设值装入sja1000的总线定时器
SJA_BCANAdr=REG_BTR0; //访问地址指向总线定时寄存器0
*SJA_BCANAdr=BTR0_num; //写入参数
if(*SJA_BCANAdr != BTR0_num) //校验写入值
{
return 1;
}
SJA_BCANAdr=REG_BTR1; //访问地址指向总线定时寄存器0
*SJA_BCANAdr=BTR1_num; //写入参数
if(*SJA_BCANAdr != BTR1_num) //校验写入值
{
return 1;
}
return 0;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -