CAN总线控制器 SJA1000源程序(c语言)
基于51单片机的CAN通讯协议C语言程序

// 入口函数 无
// 出口函数 无
// 全局变量 SJA_workmode
// 操作寄存器 控制寄存器(地址00)
// 函数功能 设置SJA工作在复位模式
#define SJA_RIE 0 //接收中断
//-----------------------定义地址指针,指向基址--------------------------------------------------------
bit bdata SJA_workmode=1; //SJA_workmode=1SJA工作在工作模式
//SJA_workmode=0工作在复位模式
#define base_Adr 0x00
//-----------------------定义总线定时寄存器的值--------------------------------------------------------
#define SJA_BTR0 0x00 //该值需要用户根据实际需要的波特率进行计算
//------------------------------------------------------------------------------------------------------
// 函数类别 SJA1000基本操作
// 函数名称 CANREG_write
}BASICCAN_FRAME,receive_BUF,send_BUF;
//BASICCAN_BUFstruct send_BUF;
//------------------------------------------------------------------------------------------------------
CAN读写程序(C语言)

CAN读写程序(C语言)CAN读写程序(C语言)2008-08-12 14:26:59| 分类:默认分类|字号订阅;SJA1000初始化CANNI:MOV DPTR,#MODE ;方式寄存器MOV A,#01H ;复位模式,初始化MOVX @DPTR,AMOV DPTR,#CDR ;时钟分频寄存器MOV A,#88H ;选择PeliCAN模式,关闭CLKOUTMOVX @DPTR,AMOV DPTR,#IER ;中断允许寄存器MOV A,#0DH ;开放发送中断、溢出中断、错误警告中断 MOVX @DPTR,AMOV DPTR,#AMR ;接收屏蔽寄存器MOV R6,#4MOV A,#0 ;接收屏蔽寄存器都参与滤波AMRINI: MOVX @DPTR,A ;接收屏蔽寄存器赋初值INC DPTR DJNZ R6,AMRINIMOV DPTR,#ACR ;接收代码寄存器MOV A,#0A7HMOVX @DPTR,A ;ACR0=0,接收代码寄存器赋初值INC DPTRMOV A,#0F8HMOVX @DPTR,A ;ACR1=3INC DPTRMOV A,#0A7HMOVX @DPTR,A ;ACR2=0INC DPTRMOV A,#0F8HMOVX @DPTR,A ;ACR3=3MOV DPTR,#BTR0 ;总线定时寄存器0MOV A,#01HMOVX @DPTR,AMOV DPTR,#BTR1 ;总线定时寄存器1MOV A,#1CH ;设置波特率MOVX @DPTR,AMOV DPTR,#OCR ;输出控制寄存器MOV A,#0AAHMOVX @DPTR,AMOV DPTR,#RBSA ;接收缓存器起始地址寄存器MOV A,#0 ;设置接收缓存器FIFO起始地址为0MOVX @DPTR,AMOV DPTR,#TXERR ;发送错误计数寄存器MOV A,#0 ;清除发送错误计数寄存器MOVX @DPTR,AMOV DPTR,#ECC ;错误代码捕捉寄存器MOVX A,@DPTR ;清除错误代码捕捉寄存器MOV DPTR,#MODE ;方式寄存器MOV A,#00H ;双滤波接收,操作模式.#08H单滤波接收MOVX @DPTR,ARET;************************************************************** ****** ;************************************************************ **;发送低压数据帧TDATAL:MOV DPTR,#CANTXB ;SJA1000发送缓冲区首址MOV A,#88H ;发扩展帧格式数据帧,长度8字节MOVX @DPTR,AINC DPTRMOV A,#0A7HMOVX @DPTR,AINC DPTRMOV A,#0F8HMOVX @DPTR,A ;标识符INC DPTRMOV A,#28HMOVX @DPTR,AINC DPTRMOV A,#50HMOVX @DPTR,AMOV R0,#TRDA TA1 ;RAM发送数据区首址MTBFL: MOV A,@R0INC DPTRMOVX @DPTR,AINC R0CJNE R0,#TRDA TA1+8,MTBFL ;向发送缓冲区写8个字节MOV DPTR,#CMR ;命令寄存器地址MOV A,#01HMOVX @DPTR,A ;启动SJA1000发送RET。
CAN通信控制器SJA1000

1 错误;
0 正常; 1 发送;SJA1000正在发送一个报文 0 空闲;没有报文在发送中 1 接收;SJA1000正在接收一个报文 0 空闲;没有报文在接收中
中断寄存器(IR)
1、中断寄存器用作中断源的识别;
2、当寄存器的一位或多位被置位时 ,/INT引脚有效 (低),引起中断;
3、中断寄存器对微控制器来说是只读存储器;
位 地址过滤
7
6
5
4
3
2
1
0
10
标识符字节1 ID.10 ID.9 ID.8 ID.7 ID.6 ID.5 ID.4 ID.3
描述符
11
标识符字节2 ID.2 ID.1 ID.0 RTR DLC.3 DLC.2 DLC.1 DLC.0
12
TX数据1
13
TX数据2
14
TX数据3
15
TX数据4
数据
16
TX数据5
1 出现;一个报文将被发送 0 空缺;无动作
位
符号
名称
值
CMR.7
-
CMR.6
-
CMR.5
-
-
- 保留
-
- 保留
-
- 保留
功
能
状态寄存器(SR)
状态寄存器的内容反映SJA1000的状态。状态寄存器对微 控制器来说是只读存储器。提供给用户以查询的方式来处理数据 传输。 各个位的功能如下:
位 SR.3 SR.2
ir1ti发送中断11发送缓冲器状态从逻辑00至逻辑11跳变释放总线且跳变释放总线且发送中断使能位被置为逻辑11使能时此位被置位表示发送完成使能时此位被置位表示发送完成00微控制器的任何读访问可自动清除此位ir0ri接收中断11当接收fifo不空且接收中断使能位被置为逻辑11使能时此位被置位表示有数据待接收00微控制器的任何读访问可自动清除此位位符号名称值功能ir7保留ir6保留ir5保留ir4iwui唤醒中断11退出睡眠模式时此位被置位00微控制器的任何读访问可自动清除此位ir3doi数据溢出中断数据溢出中断11当数据溢出中断使能被置为逻辑11使能时一旦数据溢出状态位使能时一旦数据溢出状态位001跃变此位即被置位跃变此位即被置位00微控制器的任何读访问可自动清除此位发送缓冲区用来存储微控制器要发送的一个报文
独立CAN控制器SJA1000的C语言编程

SJA1000中断接收程序
unsigned char rx0; unsigned int rxide; unsigned char rxdata[8]; sbit rxsec=0; void receive interrupt 0 { unsigned char i; unsigned char *p; p=&rxide; rx0=RXEFF0; *p=RXEFF4; P++;
(ARM)设置 清零错误寄存器 中断使能寄存器(IER)设置 进入工作模式
SJA1000初始化程序
void sja1000_init( ) { MOD=0x09; CDR=0xc8;
OCR=0x1a; BTR0=0x??; BTR1=0x??; ACR0=0x??; ACR1=0x??; ACR2=0x??; ACR3=0x??;
ABSACC.H 提供的宏(Macro((unsigned char volatile code *) 0) #define DBYTE ((unsigned char volatile data *) 0) #define PBYTE ((unsigned char volatile pdata *) 0) #define XBYTE ((unsigned char volatile xdata *) 0) #define CWORD ((unsigned int volatile code *) 0) #define DWORD ((unsigned int volatile data *) 0) #define PWORD ((unsigned int volatile pdata *) 0) #define XWORD ((unsigned int volatile xdata *) 0)
sja1000c

#define SJA1000_H#include <reg52.h>#define unchar unsigned char#define unint unsigned intvoid peli_caninit(void);void SJA_TX(unchar txdata);sbit SJA_RST = P2^3;//SJA1000复位管脚sbit SJA_CS = P2^0;//SJA1000片选管脚#define XBYTE ((unsigned char volatile xdata *)0)#define SJA_BASE_ADR 0xfe00//SJA1000寄存器地址定义,作用在Peli模式,扩展帧方式/**********************模式控制寄存器及其位定义************************/#define SJA_MOD XBYTE[SJA_BASE_ADR + 0x00]#define RM_BIT 0x01 //复位模式请求位#define LOM_BIT 0x02 //只听模式位#define STM_BIT 0x04 //自检模式位#define AFM_BIT 0x08 //验收滤波器模式位#define SM_BIT 0x10 //睡眠模式位/**********************命令寄存器及其位定义************************/#define SJA_CMR XBYTE[SJA_BASE_ADR + 0x01]#define TR_BIT 0x01 //发送请求位#define AT_BIT 0x02 //中止发送位#define RRB_BIT 0x04 //释放接收缓冲器位#define CDO_BIT 0x08 //清除数据溢出位#define SRR_BIT 0x10 //自身接收请求位/**********************状态寄存器及其位定义************************/#define SJA_SR XBYTE[SJA_BASE_ADR + 0x02]#define RBS_BIT 0x01 //接收缓冲器状态位#define DOS_BIT 0x02 //数据溢出状态位#define TBS_BIT 0x04 //发送缓冲器状态位#define TCS_BIT 0x08 //发送完成状态位#define RS_BIT 0x10 //接收状态位#define TS_BIT 0x20 //发送状态位#define ES_BIT 0x40 //错误状态位#define BS_BIT 0x80 //总线状态位/**********************中断寄存器及其位定义************************/#define SJA_IR XBYTE[SJA_BASE_ADR + 0x03]#define RI_BIT 0x01 //接收中断位#define TI_BIT 0x02 //发送中断位#define EI_BIT 0x04 //错误警告中断位#define DOI_BIT 0x08 //数据溢出中断位#define WUI_BIT 0x10 //唤醒中断位#define EPI_BIT 0x20 //错误消极中断位#define ALI_BIT 0x40 //仲裁丢失中断位#define BEI_BIT 0x80 //总线错误中断位/**********************中断使能寄存器及其位定义************************/#define SJA_IER XBYTE[SJA_BASE_ADR + 0x04]#define RIE_BIT 0x01 //接收中断使能位#define TIE_BIT 0x02 //发送中断使能位#define EIE_BIT 0x04 //错误警告中断使能位#define DOIE_BIT 0x08 //数据溢出中断使能位#define WUIE_BIT 0x10 //唤醒中断使能位#define EPIE_BIT 0x20 //错误消极中断使能位#define ALIE_BIT 0x40 //仲裁丢失中断使能位#define BEIE_BIT 0x80 //总线错误中断使能位#define SJA_BTR0 XBYTE[SJA_BASE_ADR + 0x06] //总线定时器0寄存器#define SJA_BTR1 XBYTE[SJA_BASE_ADR + 0x07] //总线定时器1寄存器#define SAM_BIT 0x80 //采样模式位;0==总线被采样1次;1== 总线被采样3次/**********************输出控制寄存器及其位定义************************/#define SJA_OCR XBYTE[SJA_BASE_ADR + 0x08]/*OCMODE1 ,OCMODE0 */#define BiPhaseMode 0x00 //双相输出模式#define NormalMode 0x02 //正常输出模式#define ClkOutMode (0x01|0x02) //时钟输出模式/*TX1 的输出管脚配置*/#define OCPOL1_BIT 0x20 //输出极性控制位#define Tx1Float 0x00 //配置为悬空#define Tx1PullDn 0x40 //配置为下拉#define Tx1PullUp 0x80 //配置为上拉#define Tx1PshPull (0x40|0x80) //配置为推挽/*TX0 的输出管脚配置*/#define OCPOL0_BIT 0x04 //输出极性控制位#define Tx0Float 0x00 //配置为悬空#define Tx0PullDn 0x08 //配置为下拉#define Tx0PullUp 0x10 //配置为上拉#define Tx0PshPull (0x10|0x08) //配置为推挽#define SJA_TEST XBYTE[SJA_BASE_ADR + 0x09] //测试寄存器/********************************* #define SJA_10 XBYTE[SJA_BASE_ADR + 0x0a] 寄存器功能保留********************************//**********************其他寄存器及其位定义************************/#define SJA_ALC XBYTE[SJA_BASE_ADR + 0x0b] //仲裁丢失捕捉寄存器#define SJA_ECC XBYTE[SJA_BASE_ADR + 0x0c] //错误捕捉寄存器#define SJA_EWLR XBYTE[SJA_BASE_ADR + 0x0d] //错误报警限制寄存器#define SJA_RXERR XBYTE[SJA_BASE_ADR + 0x0e] //RX 错误计数器寄存器#define SJA_TXERR XBYTE[SJA_BASE_ADR + 0x0f] //TX 错误计数器寄存器/**********************验收滤波器寄存器及其位定义************************/#define SJA_ACR0 XBYTE[SJA_BASE_ADR + 0x10] //验收代码0寄存器#define SJA_ACR1 XBYTE[SJA_BASE_ADR + 0x11] //验收代码1寄存器#define SJA_ACR2 XBYTE[SJA_BASE_ADR + 0x12] //验收代码2寄存器#define SJA_ACR3 XBYTE[SJA_BASE_ADR + 0x13] //验收代码3寄存器#define SJA_AMR0 XBYTE[SJA_BASE_ADR + 0x14] //验收屏蔽0寄存器#define SJA_AMR1 XBYTE[SJA_BASE_ADR + 0x15] //验收屏蔽1寄存器#define SJA_AMR2 XBYTE[SJA_BASE_ADR + 0x16] //验收屏蔽2寄存器#define SJA_AMR3 XBYTE[SJA_BASE_ADR + 0x17] //验收屏蔽3寄存器/**********************TX缓冲器地址定义************************/#define SJA_TBSR0 XBYTE[SJA_BASE_ADR + 0x10]#define SJA_TBSR1 XBYTE[SJA_BASE_ADR + 0x11]#define SJA_TBSR2 XBYTE[SJA_BASE_ADR + 0x12]#define SJA_TBSR3 XBYTE[SJA_BASE_ADR + 0x13]#define SJA_TBSR4 XBYTE[SJA_BASE_ADR + 0x14]#define SJA_TBSR5 XBYTE[SJA_BASE_ADR + 0x15]#define SJA_TBSR6 XBYTE[SJA_BASE_ADR + 0x16]#define SJA_TBSR7 XBYTE[SJA_BASE_ADR + 0x17]#define SJA_TBSR8 XBYTE[SJA_BASE_ADR + 0x18]#define SJA_TBSR9 XBYTE[SJA_BASE_ADR + 0x19]#define SJA_TBSR10 XBYTE[SJA_BASE_ADR + 0x1a]#define SJA_TBSR11 XBYTE[SJA_BASE_ADR + 0x1b]#define SJA_TBSR12 XBYTE[SJA_BASE_ADR + 0x1c]/**********************RX缓冲器地址定义************************/#define SJA_RBSR0 XBYTE[SJA_BASE_ADR + 0x10]#define SJA_RBSR1 XBYTE[SJA_BASE_ADR + 0x11]#define SJA_RBSR2 XBYTE[SJA_BASE_ADR + 0x12]#define SJA_RBSR3 XBYTE[SJA_BASE_ADR + 0x13]#define SJA_RBSR4 XBYTE[SJA_BASE_ADR + 0x14]#define SJA_RBSR5 XBYTE[SJA_BASE_ADR + 0x15]#define SJA_RBSR6 XBYTE[SJA_BASE_ADR + 0x16]#define SJA_RBSR7 XBYTE[SJA_BASE_ADR + 0x17]#define SJA_RBSR8 XBYTE[SJA_BASE_ADR + 0x18]#define SJA_RBSR9 XBYTE[SJA_BASE_ADR + 0x19]#define SJA_RBSR10 XBYTE[SJA_BASE_ADR + 0x1a]#define SJA_RBSR11 XBYTE[SJA_BASE_ADR + 0x1b]#define SJA_RBSR12 XBYTE[SJA_BASE_ADR + 0x1c]#define SJA_RMC XBYTE[SJA_BASE_ADR + 0x1d] //RX 信息计数器寄存器#define SJA_RBSA XBYTE[SJA_BASE_ADR + 0x1e] //RX 缓冲区起始地址寄存器/**********************时钟分频寄存器地址定义************************/#define SJA_CDR XBYTE[SJA_BASE_ADR + 0x1f] //时钟分频寄存器#define CLKOff_BIT 0x08 //时钟关闭位,时钟输出管脚控制位#define RXINTEN_BIT 0x20 //用于接收中断的管脚TX1#define CBP_BIT 0x40 //CAN 比较器旁路控制位#define CANMode_BIT 0x80 //CAN 模式控制位#endif。
SJA1000 独立的CAN控制器应用指南-外文资料翻译

外文资料翻译译文SJA1000 独立的CAN控制器应用指南1 介绍SJA1000是一个独立的CAN控制器,它在汽车和普通的工业应用上有先进的特征。
由于它和PCA82C200 在硬件和软件都兼容,因此它将会替代PCA82C200。
SJA1000有一系列先进的功能适合于多种应用,特别在系统优化、诊断和维护方面非常重要。
本文是要指导用户设计基于SJA1000 的完整的CAN节点。
同时本文还提供典型的应用电路图和编程的流程图。
2 概述SJA1000 独立的CAN控制器有2个不同的操作模式:BasicCAN模式(和PCA82C200)兼容PeliCAN模式BasicCAN模式是上电后默认的操作模式。
因此,用PCA82C200开发的已有硬件和软件可以直接在SJA1000上使用,而不用作任何修改。
PeliCAN模式是新的操作模式,它能够处理所有CAN2.0B 规范的帧类型。
而且它还提供一些增强功能使SJA1000能应用于更宽的领域。
2.1 CAN 节点结构通常,每个CAN 模块能够被分成不同的功能块。
SJA1000使用[3] [4] [5]最优化的CAN收发器连接到CAN 。
收发器控制从CAN控制器到总线物理层或相反的逻辑电平信号。
上面一层是一个CAN 控制器,它执行在CAN规范[8]里规定的完整的CAN协议。
它通常用于报文缓冲和验收滤波,而所有这些CAN功能,都由一个模块控制器控制它负责执行应用的功能。
例如,控制执行器、读传感器和处理人机接口(MMI)。
如图1所示,SJA1000独立的CAN控制器通常位于微型控制器和收发器之间,大多数情况下这个控制器是一个集成电路。
图1 CAN模块装置2.2 结构图下图是SJA1000 的结构图图2 SJA1000的结构图根据CAN规范,CAN核心模块控制CAN帧的发送和接收。
接口管理逻辑负责连接外部主控制器,该控制器可以是微型控制器或任何其他器件。
经过SJA1000复用的地址/数据总线访问寄存器和控制读/写选通信号都在这里处理。
SJA1000程序

SJA1000程序给你提供一些思路1、sja1000初始化2、发送子程序3、中断方式接收下面是一些程序段你参考下(已用于产品)/**********SJA1000初始化***********//void Init_SJA1000(void){uchar state;uchar ACRR[4]={0XAA,0XFF,0X22,0X11};// 接收代码寄存器uchar AMRR[4]={0xff,0xff,0xff,0xff};// 接收屏蔽寄存器//uchar AMRR[4]={0x00,0x00,0xff,0xff};// 接收屏蔽寄存器do// 使用do--while语句确保进入复位模式{MODR = 0x09; // 设置MOD.0=1--进入复位模式,以便设置相应的寄存器state = MODR;}while( !(state & 0x01) );// 对SJA1000部分寄存器进行初始化设置CDR = 0x88; // CDR为时钟分频器,CDR.3=1--时钟关闭, CDR.7=0---basic CAN, CDR.7=1---Peli CANBTR0 = 0x04;//0x31; // 总线定时寄存器0 ;总线波特率设定BTR1 = 0x1c;//0x1c; // 总线定时寄存器1 ;总线波特率设定IER = 0x01; // IER.0=1--接收中断使能;IER.1=0--关闭发送中断使能OCR = 0xaa; // 配置输出控制寄存器CMR = 0x04; // 释放接收缓冲器ACR0 = ACRR[0];// 初始化接收代码寄存器ACR1 = ACRR[1];ACR2 = ACRR[2];ACR3 = ACRR[3];AMR0 = AMRR[0];// 初始化接收屏蔽寄存器AMR1 = AMRR[1];AMR2 = AMRR[2];AMR3 = AMRR[3];do// 使用do--while语句确保退出复位模式{MODR = 0x08; //MOD.3=0--双滤波器模式state = MODR;}while( state & 0x01 );}////////////////////////////////////////**********CAN发送数据到CAN-Bus***********//void CAN_TXD(void){uchar state;//初始化标示码头信息TX_buffer[0] = 0x88; //.7=0--扩展帧;.6=0--数据帧; .0-.3=100--数据长度为8字节// TX_buffer[1] = 0xFF; //本帧信息的ID//TX_buffer[2] = 0xFF;TX_buffer[3] = 0xFF;TX_buffer[4] = 0xFF;do //查询SJA1000是否处于接收状态,当SJA1000不处于接收状态时才可继续执行{state = SR; //SR为SJA1000的状态寄存器}while( state & 0x10 ); //SR.4=1 正在接收,等待do //查询SJA1000是否处于发送完毕状态{state = SR;}while(!(state & 0x08)); //SR.3=0,发送请求未处理完,等待直到SR.3=1do //查询发送缓冲器状态{state = SR;}while(!(state & 0x04)); //SR.2=0,发送缓冲器被锁。
CAN总线控制器-SJA1000源程序(c语言)

send_BUF.Frame_Data[1] = 0x22;
send_BUF.Frame_Data[2] = 0x33;
send_BUF.Frame_Data[3] = 0x44;
send_BUF.Frame_Data[4] = 0x55;
//函数类别延时
//函数名称delay
//入口函数无
//出口函数无
//函数功能延时
//------------------------------------------------------------------------------------------------------
void delay(unsigned char time)
//函数类别供调用子函数
//函数名称send_BUF_init
//入口函数无
//出口函数无
//函数功能对MCU内公共变量结构send_BUF赋初值
//-----------------------------------------------------------------------------------------------------
CAN总线控制器sja1000源程序
SJA1000是一种独立控制器用于移动目标和一般工业环境中的区域网络控制CAN它是PHILIPS
半导体PCA82C200 CAN控制器BasicCAN的替代产品而且它增加了一种新的工作模式PeliCAN ,
这种模式支持具有很多新特性的CAN 2.0B协议。
1特性
和PCA82C200独立CAN控制器引脚兼容
void SJAconnect_judge(void)
sja1000的初始化和收发程序框架

} } 接收CAN报文 CAN报文接收函数主要负责接收整车控制器发送的控制指令,来完成对充放电继电器、风 扇以及电池等器件的控制。CAN接收程序如下: if(TempData != 0) { if((TempData & 0x80) == 0x80) //总线关闭 { …… //总线关闭处理 } if((TempData & 0x02) == 0x02) //数据溢出 { …… //数据溢出处理 } if((TempData & 0x01) == 0x01) //RXFIFO存在完整有效的报文 { …… //读取缓冲区报文 } }
SJA1000初始化 通过向CAN控制器SJA1000模式寄存器写0x01,让其进入复位模式,然后分别对SJA1000的 时钟分频寄存器、错误报警限额寄存器、中断使能寄存器、接收代码和接收屏蔽寄存器、总 线时序寄存器和输出控制寄存器设置,最后向模式寄存器写0x08,进入正常工作模式。初始 化程序如下: #define SJA1000_Data_Port portA000 ioport unsigned int A000; //定义数据输入/输出端口 #define SJA1000_Address_Port port8000 ioport unsigned int port8000; //定义地址输入端口 …… SJA1000_WRITE(REG_MODE, 0x01); TempData= SJA1000_READ(REG_MODE); //向模式寄存器写0x01,进入复位模式 while((TempData & 0x01) != 0x01); //等待SJA1000复位 …… do { SJA1000_WRITE(REG_MODE, 0x08); TempData= SJA1000_READ(REG_MODE); }while ((TempData & 0x01)!=0x00); //等待SJA1000进入正常工作模式
SJA1000 BasicCAN模式的通讯测试程序

while(1)
void CanSendKey(void); //发送键
void EnterNext(void); //按确认键后进入下一小项处理
//led 送显
#define LED_SelBit() disp_pt++;if(disp_pt>4)disp_pt=0//位选
extern uchar Read_Xdata(uint Xadr); //从外部地址xadr中读取数据
extern void Key_Scan(void); //键盘扫描程序
extern uchar Key_Get(void); //取键盘值
void UartRcv_Prg(void); //串口接收到数据处理
void DrecDisplay(uchar *databuf); //直通显示处理函数
void TestDispPrg(void); //测试处理函数
}
/*-------------------------------------------------------------------------------------------
main程序
-------------------------------------------------------------------------------------------*/
void EnterKey(void); //确认键
void IncKey(void); //增加键
void QuitKey(void); //退出键
CAN-bus现场总线基础教程【第3章】CAN控制器驱动-SJA1000编程基础(9)

第3章 CAN 控制器驱动1.1 SJA1000编程基础1.1.1 MCU 访问SJA1000SJA1000使用并行总线接口与MCU 连接,对MCU 来说,SJA1000可以认为是1个外扩的RAM 芯片,51系列MCU 通过地址线、数据线和控制线与SJA1000连接,如图3.1所示。
AD[0:7]是低8位地址与数据总线复用的,MCU 在操作总线时,在该接口上先输出低8位地址线,然后再进行数据操作(读或写)。
SJA1000内部带有地址锁存器,由ALE 信号实现数据与地址的分离。
因为SJA1000的地址宽度为8位,所以寻址空间范围是0x00~0xFF 。
假如每个地址都对应一个寄存器,那么SJA1000最多支持256个寄存器。
而实际上SJA1000在BasicCAN (CAN2.0A )模式下只有32个寄存器,在FullCAN (CAN2.0B )模式下则有128个寄存器。
虽然SJA1000寄存器的访问地址会因为硬件设计不同而不同,但SJA1000内部寄存器的位置关系是固定的。
如果我们给SJA1000每个内部寄存器的地址都定义绝对地址(如程序清单3.1所示),那么在硬件设计发生变化时,特别是器件编址变化时,要修改的寄存器地址定义将会非常多。
为了提高驱动的可移植性,在实际访问SJA1000内部寄存器时,常采用基地址加偏移量的方式进行寄存器访问(如程序清单3.2所示)。
如果把SJA1000内部寄存器看做数组的话,那基地址就是这个数组的首地址,偏移量就是数组的下标,即成员在数组中的位置。
程序清单3.1 采用绝对编址的寄存器定义1 #define REG_CAN_MOD 0xA000 // 内部控制寄存器2 #define REG_CAN_CMR 0xA001 // 命令寄存器3 #define REG_CAN_SR 0xA002 // 状态寄存器4 #define REG_CAN_IR 0xA003 // 中断寄存器5 #define REG_CAN_IER0xA004// 中断使能寄存器6......程序清单3.2 采用基地址加偏移量方式的寄存器定义7 #define REG_BASE_ADD0xA000// SJA1000寄存器基地址 8 #defineREG_CAN_MOD 0x00 // 内部控制寄存器 9 #define REG_CAN_CMR 0x01 // 命令寄存器 10 #define REG_CAN_SR 0x02 // 状态寄存器 11 #define REG_CAN_IR 0x03 // 中断寄存器 12 #define REG_CAN_IER0x04// 中断使能寄存器13......通常MCU 的总线上会挂载很多器件,除了SJA1000外,可能还有RAM 和ROM 等器件。
CAN总线控制器SJA1000详解

5
TSEG 2.1
4
TSEG 2.0
3
TSEG 1.3
2
TSEG 1.2
1
TSEG 1.1
0
TSEG 1.0
总线定时寄存器1定义了每个位周期的长度、采样 点的位置和每个采样点的采样数目。
6.5 控制段寄存器
• 位周期=同步段(T_syncseg)+采样前段(T_tseg1)+ 采样后段(T_tseg2)
(3)TIE:发送中断允许位,若置位,当一个报文成功发送 或发送缓冲区再次可访问时(如在中止的发送命令后), 将会产生中断,复位时无发送中断产生。
(4)RIE:接收中断允许位,若置位,当一个报文被无误地 接收时将会产生接收中断,复位时无接收中断产生。
6.5 控制段寄存器
(5)RR :复位请求位,该位置位后,SJA1000将会终止 当前报文的接收或发送而进入复位工作状态。
(5) TCS: 发送完成标志,“1”表示上次的发送已成功完成。 (6) TBS: 发送缓冲区状态标志,“1”表示发送缓冲区可写。 若该位为“0”时,MCU写发送缓冲区,则写入数据无效且被 丢失。 (7) DOS: 数据超载标志,“1”表示由于RXFIFO没有足够的空 间,收到的报文丢失。 (8)RBS: 接收缓冲区状态标志,“1”表示RXFIFO中至少有 一个报文。当MCU读取报文后,应给出释放接收缓冲区的命 令,该标志才会清零。若RXFIFO中还有未读报文,该位又将 被置位。
T_sjw=T_scl×(1+SJW.0+2×SJW.1)
6.5 控制段寄存器
• 同步跳转宽度:定义了一个位周期可以 被一次重新同步缩短或延长的时钟周期 的最大数目。
6.5 控制段寄存器
一位时间的一般结构图
项目二 汽车CAN总线技术基本原理(任务四SJA1000CAN控制器及其应用)

0
接收中断使能 1
0
功能
使能 禁止 使能 禁止 使能 禁止 使能 禁止 使能 禁止 使能 禁止 使能 使能 使能 禁止
Peli_RXD: PUSH ACC PUSH PSW CLR EA ;//关CPU中断
RE6: MOV DPTR,#SJA_IR MOVX A,@DPTR ANL A,#01H CJNE A,#00H,RE7;接收中断 SJMP RE8
IR.3 DOS 溢出中 1 置位
断
复位
IR.2 EI 错误报 1 置位
警中断 0 复位
IR.1 TI 发送中 1 置位
断
0 复位
IR.0 RI 接收中 1 置位
断
0 复位
Peli_RXD: PUSH ACC PUSH PSW CLR EA ;//关CPU中断
RE6: MOV DPTR,#SJA_IR MOVX A,@DPTR ANL A,#01H CJNE A,#00H,RE7;接收中断 SJMP RE8
----
状态
----
3(IR) 中断
---
中断
---
4(IER) 中断使能
中断使能 中断使能 中断使能
5
保留(00H) ---
保留(00H) ---
6(BTR0) 总线定时0
---
总线定时0 总线定时0
7(BTR0) 总线定时1
---
总线定时1 总线定时1
8(OCR) 输出控制
---
输出控制 输出控制
接收缓存器 标识符RTR,DLC 字节1-8 时钟驱动器
10 11 12-19
20 21 22-29 31
7
6
测试方 同步 式
CAN总线的实现-SJA1000实例

一、以下是我做的CAN节点的测试程序, 实现两个节点传送数据,程序主要分三部分SJA1000 的初始化,接收数据,发送数据./******************************************************函数原型:bit Sja_1000_Init(void)**功能:初始化SJA10000**入口参数: 无**返回值:0:初始化成功1:复位失败2: 测试sja1000失败3:设置失败4:设置验收滤波器失败5:设置波特率失败*****************************************************/unsigned char Sja_1000_Init(void){bit s;EA=0;s=BCAN_ENTER_RETMODEL();if (s==1) return 1;s=BCAN_CREATE_COMMUNATION();if (s==1) return 2;s=BCAN_SET_OUTCLK(0xc0);//Pelicanif (s==1) return 3;s=BCAN_SET_OBJECT(0xFF,0x4E,0x16,0x00,0xff,0x00,0x00,0x00);if (s==1) return 4;s=BCAN_SET_BANDRATE(CAN_BPS_1M);if (s==1) return 5;SJA_BCANAdr=REG_OCR ;*SJA_BCANAdr=0x1a;SJA_BCANAdr=REG_IER;*SJA_BCANAdr=0x03;s=BCAN_SET_CONTROL(0x08);if (s==1) return 6;EA=1;return 0;}}/*********************************************************************函数原型: bit BCAN_SET_OUTCLK( unsigned char Clock_Out) **参数说明: ** Clock_Out:存放时钟分频寄存器(CDR)的参数设置**返回值: ** 0 ;设置成功** 1 ;设置失败**说明:设置SJA1000的时钟分频。
SJA1000程序

INC R0
MOV @R0, #08H
INC R0
MOV @R0, #05H
LCALL BCAN_CMD_PRG ;
RET
;;;;;;;;;;;;;;;;;;控制SJA1000向CAN总线发送数据处理部分;;;;;;;;;;;;;;;
SENDDATA_PRG:
MOV R0, #SEND_DATA_BUF1
RCV_DATA_BUF9 DATA 058H
RCV_DATA_BUF10 DATA 059H
ERROR_STATUS DATA 07CH ;错误状态表示
TEST_DATA DATA 07FH ;测试发送数据
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
MOV 3AH,#00H
RET
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;外部中断0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
BCAN_INT0:
push DPH
PUSH DPL
PUSH PSW ;PSW,ACC入栈
MOV A, TEST_DATA
INC R0
MOV @R0, A
MOV R0, #SEND_DATA_BUF1
LCALL BCAN_DATA_WRITE ;将要发送的数据送入发送缓冲区
LOOPER:
JNB RCV_GOOD,LOOPER2 ;sja1000成功接收一帧,通知CPU处理
CLR RCV_GOOD
LCALL RCVDATA_PRG
现场总线技术 SJA1000寄存器和c语言

中国矿业大学机电工程学院-张有忠 ©版权所有 2005-12
11
验收屏蔽寄存器AMR
现场总线技 术
验收屏蔽寄存器AMR,地址5
如果复位请求位置1(当前),这个寄存器可以被访问(读/写)
验收屏蔽寄存器定义验收代码寄存器的相应位对验收滤波器是相关的(AM.X = 0 ) 或无关的(AM.X = 1),(即可为任意值)
1111”
寄存器
位
符号
名称
CMR.7~5 -
CMR.4 GTS
命令寄 CMR.3
CDO
存器
CMR CMR.2
RRB
CMR.1 AT
CMR.0 TR
保留 睡眠 清除数据溢出 释放接收缓冲器 终止传送 发送请求
硬件复位
值
总线关闭或软件复 位CR.0=1
注
注
中国矿业大学机电工程学院-张有忠 ©版权所有 2005-12
读
写
20
标识符10~3 标识符10~3
21
标识符2~0 标识符2~0 RTR和DLC RTR和DLC
22
数据字节1 数据字节1
23
数据字节2 数据字节2
24 接收缓冲器 数据字节3 数据字节3
25
数据字节4 数据字节4
26
数据字节5 数据字节5
27
数据字节6 数据字节6
28
数据字节7 数据字节7
29
9
现场总线技 术
接收缓冲器
接收缓冲器的全部列表和发 送缓冲器类似
接收缓冲器是RXFIFO 中可 访问的部分,位于CAN 地址 的20-29 之间
识别码、远程发送请求位和 数据长度码同发送缓冲器的 相同,只不过是在地址2029
基于SJA1000的CAN总线测试程序

//置工作模式失败}return(SJA_mode);}
/*****************************************************************
********/bitSetting_SJA1000_rate(void){bit
setting_success;while(Setting_SJA1000_resetmode()==0){
Setting_SJA1000_resetmode();//设置SJA工作在复位模式}
Write_SJA1000(REG_BTR0,SJA_BTR0);Write_SJA1000(REG_BTR1,SJA_BTR1);
connect_OK=0; //连接故障} return(connect_OK);}
/*****************************************************************
函数功能:设置SJA1000为工作模式*入口参数:无*出口参数:
SJA_mode************************************************************
******/bit Judge_SJA1000_connect(void){bit connect_OK=0;
Write_SJA1000(REG_TEST,0xAA); //写AA到测试寄存器(地址09)
if(Read_SJA1000(0x09)==0xAA){connect_OK=1;//连接正常}else{
return(SJAREG_data);}
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
CAN总线控制器sja1000源程序SJA1000 是一种独立控制器用于移动目标和一般工业环境中的区域网络控制CAN 它是PHILIPS 半导体PCA82C200 CAN 控制器BasicCAN 的替代产品而且它增加了一种新的工作模式PeliCAN , 这种模式支持具有很多新特性的CAN 2.0B 协议。
1 特性和PCA82C200 独立CAN 控制器引脚兼容和PCA82C200 独立CAN 控制器电气兼容PCA82C200 模式即默认的BasicCAN 模式扩展的接收缓冲器64 字节先进先出FIFO和CAN2.0B 协议兼容PCA82C200 兼容模式中的无源扩展帧同时支持11 位和29 位识别码位速率可达1Mbits/sPeliCAN 模式扩展功能--可读/写访问的错误计数器--可编程的错误报警限制--最近一次错误代码寄存器--对每一个CAN 总线错误的中断--具体控制位控制的仲裁丢失中断--单次发送无重发--只听模式无确认无活动的出错标志--支持热插拔软件位速率检测--验收滤波器扩展4 字节代码4 字节屏蔽--自身信息接收自接收请求24MHz 时钟频率对不同微处理器的接口可编程的CAN 输出驱动器配置增强的温度适应-40-+125#include <reg52.h>#include <AT89X51.H>#include <intrins.h>//-----------------------沿袭引脚和变量----------------------------------------------#define uchar unsigned char //宏定义#define uint unsigned int //宏定义void MCU_init(void);/*P2口的管脚定义*/sbit LED1 = P2^6;sbit LED2 = P2^5;sbit SJA_CS = P2^7; //SJA1000片选管脚,低电平有效//sbit SJA_RST = P1^2;/*P3口的管脚定义*/sbit SJA_RD = P3^7;sbit SJA_WR = P3^6;//-----------------------定义寻址的基址--------------------------------------------------------#define base_Adr 0x7F00//-----------------------定义总线定时寄存器的值--------------------------------------------------------#define SJA_BTR0 0x07 //该值需要用户根据需要的波特率进行计算,推荐使用周立功发布的波特率计算器#define SJA_BTR1 0x2F//-----------------------设置接收报文类型(标示符)--------------------------------------------------------//该值需要用户根据实际需要重新配置#define SJA_ACR 0x11 //验收代码寄存器的值#define SJA_AMR 0xFF //验收屏蔽寄存器的值//-----------------------设置输出时钟类型--------------------------------------------------------//该值需要用户根据实际需要重新配置#define SJA_OCR 0xaa //输出控制寄存器的值#define SJA_CDR 0x40 //时钟分频寄存器的值//-----------------------设置SJA中断,1为开中断-------------------------------------------------------- #define SJA_OIE 1 //溢出中断#define SJA_EIE 1 //错误中断#define SJA_TIE 1 //发送中断#define SJA_RIE 1 //接收中断//-----------------------定义地址指针,指向基址-------------------------------------------------------- unsigned char xdata *SJA_base_Adr = base_Adr;//-----------------------定义硬件故障标志位--------------------------------------------------------bit bdata connect_OK=0; //connect_OK=1设备连接正常//connect_OK=0设备连接故障//-----------------------定义硬件故障标志位--------------------------------------------------------bit bdata SJA_workmode=1; //SJA_workmode=1SJA工作在工作模式//SJA_workmode=0工作在复位模式//-----------------------定义SJA1000读写缓冲区的数据结构--------------------------------------------------------struct BASICCAN_BUFStruct{unsigned char IDH8;unsigned char IDL_R_DLC;unsigned char Frame_Data[8];}receive_BUF,send_BUF;//------------------------------------------------------------------------------------------------------// 函数类别供调用子函数// 函数名称send_BUF_init// 入口函数无// 出口函数无// 函数功能对MCU内公共变量结构send_BUF赋初值//------------------------------------------------------------------------------------------------------bit send_BUF_init(void){//调用send_now()函数的时候,所发送的数据是在这里初始化的。
请用户根据具体情况自己调整bit setting_success=0;send_BUF.IDH8 = 0x99;send_BUF.IDL_R_DLC = 0xE8; //IDL_R_DLC。
4即为RTR位,数据=0,远程=1;send_BUF.Frame_Data[0] = 0x11;send_BUF.Frame_Data[1] = 0x22;send_BUF.Frame_Data[2] = 0x33;send_BUF.Frame_Data[3] = 0x44;send_BUF.Frame_Data[4] = 0x55;send_BUF.Frame_Data[5] = 0x66;send_BUF.Frame_Data[6] = 0x77;send_BUF.Frame_Data[7] = 0x88;setting_success = 1;return(setting_success);}//------------------------------------------------------------------------------------------------------// 函数类别延时// 函数名称delay// 入口函数无// 出口函数无// 函数功能延时//------------------------------------------------------------------------------------------------------void delay(unsigned char time){while(time--);}//------------------------------------------------------------------------------------------------------// 函数类别SJA1000基本操作// 函数名称CANREG_write// 入口函数SJAREG_ADR,setting// 出口函数无// 函数功能写SJA1000的寄存器//------------------------------------------------------------------------------------------------------ void CANREG_write(unsigned char SJAREG_ADR, unsigned char setting){*(SJA_base_Adr+SJAREG_ADR)=setting;}//------------------------------------------------------------------------------------------------------// 函数类别SJA1000基本操作// 函数名称CANREG_read// 入口函数SJAREG_ADR// 出口函数SJAREG_data// 函数功能读SJA1000的寄存器//------------------------------------------------------------------------------------------------------ unsigned char CANREG_read(unsigned char SJAREG_ADR){unsigned char SJAREG_data;SJAREG_data=*(SJA_base_Adr+SJAREG_ADR);return(SJAREG_data);}//------------------------------------------------------------------------------------------------------// 函数类别SJA1000基本操作// 函数名称SJAconnect_judge// 入口函数无// 出口函数无// 全局变量connect_OK// 操作寄存器测试寄存器(地址09)// 函数功能判断SJA1000与控制器连接是否正常//------------------------------------------------------------------------------------------------------ void SJAconnect_judge(void){CANREG_write(0x09,0xAA); //写AA到测试寄存器(地址09)if(CANREG_read(0x09)==0xAA){connect_OK=1; //连接正常}else{connect_OK=0; //连接故障}}//------------------------------------------------------------------------------------------------------// 函数类别SJA1000基本操作// 函数名称setting_SJA_resetmode// 入口函数无// 出口函数无// 全局变量SJA_workmode// 操作寄存器控制寄存器(地址00)// 函数功能设置SJA工作在复位模式//------------------------------------------------------------------------------------------------------ void setting_SJA_resetmode(void){unsigned char CONTROL_REGdata;CONTROL_REGdata=CANREG_read(0x00);CONTROL_REGdata=CONTROL_REGdata|0x01;CANREG_write(0x00,CONTROL_REGdata);if((CANREG_read(0x00)&0x01)==1){SJA_workmode=0; //置复位模式成功}else{SJA_workmode=1; //置复位模式失败}}//------------------------------------------------------------------------------------------------------ // 函数类别SJA1000基本操作// 函数名称setting_SJA_workingmode// 入口函数无// 出口函数无// 全局变量SJA_workmode// 操作寄存器控制寄存器(地址00)// 函数功能设置SJA工作在正常工作模式//------------------------------------------------------------------------------------------------------ void setting_SJA_workingmode(void){unsigned char CONTROL_REGdata;CONTROL_REGdata=CANREG_read(0x00);CONTROL_REGdata=CONTROL_REGdata&0xFE;CANREG_write(0x00,CONTROL_REGdata);if((CANREG_read(0x00)&0x01)==0){SJA_workmode=1; //置工作模式成功}else{SJA_workmode=0; //置工作模式失败}}//------------------------------------------------------------------------------------------------------// 函数类别SJA1000基本操作// 函数名称setting_SJA_rate// 入口函数SJA_BTR0,SJA_BTR1// 出口函数setting_success// 操作寄存器总线定时寄存器BTR1(地址07)和BTR0(地址06)// 函数功能设置SJA波特率// 特殊要求只能在复位工作模式下设置//------------------------------------------------------------------------------------------------------bit setting_SJA_rate(void){bit setting_success;while(SJA_workmode){setting_SJA_resetmode(); //设置SJA工作在复位模式}CANREG_write(0x06,SJA_BTR0);CANREG_write(0x07,SJA_BTR1);if((CANREG_read(0x06)==SJA_BTR0)&(CANREG_read(0x07)==SJA_BTR1)){setting_success=1; //波特率设置成功}else{setting_success=0; //波特率设置失败}return(setting_success);}//------------------------------------------------------------------------------------------------------// 函数类别SJA1000基本操作// 函数名称setting_SJA_dataselect// 入口函数SJA_ACR,SJA_AMR// 出口函数setting_success// 操作寄存器验收代码寄存器ACR(地址04)和验收屏蔽寄存器AMR(地址05)// 函数功能设置SJA接收数据类型// 特殊要求只能在复位工作模式下设置//------------------------------------------------------------------------------------------------------bit setting_SJA_dataselect(void){bit setting_success;while(SJA_workmode){setting_SJA_resetmode(); //设置SJA工作在复位模式}CANREG_write(0x04,SJA_ACR);CANREG_write(0x05,SJA_AMR);if((CANREG_read(0x04)==SJA_ACR)&(CANREG_read(0x05)==SJA_AMR)){setting_success=1; //滤波器设置成功}else{setting_success=0; //滤波器设置失败}return(setting_success);}//------------------------------------------------------------------------------------------------------// 函数类别SJA1000基本操作// 函数名称setting_SJA_CLK// 入口函数SJA_OCR,SJA_CDR// 出口函数setting_success// 操作寄存器输出控制寄存器OCR(地址08)和时钟分频寄存器CDR(地址31)// 函数功能设置SJA输出始终类型// 特殊要求只能在复位工作模式下设置//------------------------------------------------------------------------------------------------------bit setting_SJA_CLK(void){bit setting_success;while(SJA_workmode){setting_SJA_resetmode(); //设置SJA工作在复位模式}CANREG_write(0x08,SJA_OCR);CANREG_write(0x1f,SJA_CDR);if((CANREG_read(0x08)==SJA_OCR)&(CANREG_read(0x1f)==SJA_CDR)){setting_success=1; //滤波器设置成功}else{setting_success=0; //滤波器设置失败}return(setting_success);}//------------------------------------------------------------------------------------------------------// 函数类别SJA1000基本操作// 函数名称setting_SJA_interrupt// 入口函数SJA_OIE,SJA_EIE,SJA_TIE,SJA_RIE// 出口函数setting_success// 操作寄存器控制寄存器(00)// 函数功能设置SJA中断类型和中断状态// 特殊要求只能在复位工作模式下设置//------------------------------------------------------------------------------------------------------bit setting_SJA_interrupt(void){bit setting_success;unsigned char CONT_buf,temp=0;while(SJA_workmode){setting_SJA_resetmode(); //设置SJA工作在复位模式}CONT_buf=CANREG_read(0x00);temp=SJA_OIE*16+SJA_EIE*8+SJA_TIE*4+SJA_RIE*2;CONT_buf=(temp&0x1E)|(CONT_buf&0x01);CANREG_write(0x00,CONT_buf);if(CANREG_read(0x00)==CONT_buf|0x20) //CR.5是保留位,无论如何设置,读此位的值总是逻辑1{setting_success=1; //滤波器设置成功}else{setting_success=0; //滤波器设置失败}return(setting_success);}//------------------------------------------------------------------------------------------------------// 函数类别SJA1000基本操作// 函数名称write_SJAsendBUF// 入口函数无// 出口函数setting_success// 操作寄存器发送缓存器(10-19)状态寄存器02// 函数功能写发送缓存器// 特殊要求只能在工作模式下写//------------------------------------------------------------------------------------------------------bit write_SJAsendBUF(void){bit setting_success=0;unsigned char i;while(SJA_workmode==0){setting_SJA_workingmode(); //设置SJA在工作模式}if((CANREG_read(0x02)&0x10)==0){if((CANREG_read(0x02)&0x04)!=0){CANREG_write(0x0a,send_BUF.IDH8);CANREG_write(0x0b,send_BUF.IDL_R_DLC);}for(i=0;i<8;i++){CANREG_write(0x0c+i,send_BUF.Frame_Data[i]);}setting_success=1; //发送寄存器写成功}return(setting_success);}//------------------------------------------------------------------------------------------------------ // 函数类别SJA1000基本操作// 函数名称read_SJAsendBUF// 入口函数无// 出口函数setting_success// 操作寄存器接收缓存器(20-29)状态寄存器02// 函数功能写发送缓存器// 特殊要求只能在工作模式下写//------------------------------------------------------------------------------------------------------ bit read_SJAreceiveBUF(void){bit setting_success=0;unsigned char i;while(SJA_workmode==0){setting_SJA_workingmode(); //设置SJA在工作模式}if((CANREG_read(0x02)&0x01)!=0){if((CANREG_read(0x02)&0x10)==0){receive_BUF.IDH8=CANREG_read(0x14);receive_BUF.IDL_R_DLC=(CANREG_read(0x15));for(i=0;i<8;i++){receive_BUF.Frame_Data[i]=CANREG_read(0x16+i);}}setting_success=1; //接收寄存器读成功}return(setting_success);}//------------------------------------------------------------------------------------------------------ // 函数类别供调用子程序// 函数名称SJA1000_init// 入口函数无// 出口函数无// 操作寄存器1)控制寄存器(地址00)// 2)收代码寄存器ACR(地址04)// 3)验收屏蔽寄存器AMR(地址05)// 4)总线定时寄存器BTR0(地址06)// 5)总线定时寄存器BTR1(地址07)// 6)输出控制寄存器OCR(地址08)// 7)测试寄存器(地址09)// 8)时钟分频寄存器CDR(地址31)// 9)中断使能寄存器// 函数功能SJA1000初始化设置// 特殊要求在复位模式进行,初始化结束进入工作状态//------------------------------------------------------------------------------------------------------ void SJA1000_init(void){while(connect_OK==0){SJAconnect_judge(); //检测设备连接}while(SJA_workmode){setting_SJA_resetmode(); //置SJA1000为复位模式}while(setting_SJA_rate()==0); //设置总线波特率while(setting_SJA_dataselect()==0); //设置SJA接收数据的格式(标示位)while(setting_SJA_CLK()==0); //设置SJA输出时钟的形式while(setting_SJA_interrupt()==0); //设置SJA的中断使能while(!SJA_workmode){setting_SJA_workingmode(); //进入工作模式}}//------------------------------------------------------------------------------------------------------// 函数类别中断处理函数// 函数名称send_interrupt// 入口函数无// 出口函数无// 操作寄存器// 函数功能接收中断处理函数//------------------------------------------------------------------------------------------------------void send_now(void){unsigned char state;// unsigned char CMR_REGdata;do{state = CANREG_read(0x02); //SR为SJA1000的状态寄存器}while(( state & 0x10 )|(!(state & 0x08))|(!(state & 0x04)));//查询SJA1000是否处于接收状态,发送完毕状态,或者发送缓存器被锁;while(write_SJAsendBUF()==0); //写入缓存器// CMR_REGdata = CANREG_read(0x01); //CMR是只写寄存器,不可读,读出值总是1111 1111// CMR_REGdata = CMR_REGdata | 0x01;CANREG_write(0x01,0x01); //简单置位发送位即可}//------------------------------------------------------------------------------------------------------// 函数类别发送中断处理函数// 函数名称receive_interrupt// 入口函数// 出口函数// 操作寄存器// 函数功能发送中断处理函数//------------------------------------------------------------------------------------------------------void receive_now(void){while(read_SJAreceiveBUF()==0);CANREG_write(0x01,0x04); //向CMR写入0x04,释放接收缓冲区}//------------------------------------------------------------------------------------------------------// 函数类别中断函数// 函数名称SJA_INTR// 入口函数无// 出口函数无// 操作寄存器中断寄存器(地址03)// 函数功能中断分析,判断是什么中断,调用相应的中断处理函数//------------------------------------------------------------------------------------------------------void SJA_INTR(void) interrupt 0 //CanBus接口芯片产生中断(INTR0){//这里仅简单区分了接收中断和发送中断,对于其余中断,均简单重启SJA1000,另外,IR的高三位保留位读出值总是1.unsigned char sta;EA = 0; //关闭总中断EX0 = 0; //关闭外部中断sta = CANREG_read(0x03); //读中断寄存器IRif(sta == 0xe2) //发送中断处理{LED1=0; //如果有信息发出,则指示灯亮}else if(sta == 0xe1) //接收中断,接收数据{LED2=0; //如果接收到中断,则LED2指示灯亮receive_now();}elseMCU_init();EX0 = 1;EA = 1;}void MCU_init(void){SJA_CS = 0;EX0 = 1;IT0 = 0;EA = 1;}void main() //主程序{MCU_init();SJA1000_init();while(send_BUF_init()==0);send_now(); //待发送信息之后,进入死循环,接下来就是等待中断了while(1);}代码如下:/*************定义地址指针,指向基址***********/unsigned char xdata *SJA_base_Adr = SJA_BaseAdr;/*************定义SJA1000读写缓冲区的数据结构***********/struct BASICCAN_BUFStruct{unsigned char IDH8;unsigned char IDL_R_DLC;unsigned char Frame_Data[2];}receive_BUF,send_BUF;/*****************************************************************函数功能:写SJA1000的寄存器*入口参数:地址SJAREG_ADR,数据setting*出口参数:无****************************************************************/void Write_SJA1000(unsigned char SJAREG_ADR, unsigned char setting){*(SJA_base_Adr+SJAREG_ADR)=setting;}/*****************************************************************函数功能:读SJA1000的寄存器*入口参数:地址SJAREG_ADR,数据setting*出口参数:无****************************************************************/unsigned char Read_SJA1000(unsigned char SJAREG_ADR){unsigned char SJAREG_data;SJAREG_data=*(SJA_base_Adr+SJAREG_ADR);return(SJAREG_data);}/*****************************************************************函数功能:测试SJA1000是否正常连接*入口参数:无*出口参数:connect_OK****************************************************************/bit Judge_SJA1000_connect(void){bit connect_OK=0;Write_SJA1000(REG_TEST,0xAA); //写AA到测试寄存器(地址09)if(Read_SJA1000(0x09)==0xAA){connect_OK=1; //连接正常}else{connect_OK=0; //连接故障}return(connect_OK);}/*****************************************************************函数功能:设置SJA1000为工作模式*入口参数:无*出口参数:SJA_mode****************************************************************/bit Setting_SJA1000_workingmode(void){bit SJA_mode;unsigned char CONTROL_REGdata;CONTROL_REGdata=Read_SJA1000(REG_CONTROL);CONTROL_REGdata&=0xFE;Write_SJA1000(REG_CONTROL,CONTROL_REGdata);if((Read_SJA1000(REG_CONTROL)&0x01)!=0x01){SJA_mode=1; //置工作模式成功}else{SJA_mode=0; //置工作模式失败}return(SJA_mode);}/*****************************************************************函数功能:设置SJA1000为复位模式*入口参数:无*出口参数:SJA_mode****************************************************************/bit Setting_SJA1000_resetmode(void){bit SJA_mode;unsigned char CONTROL_REGdata;CONTROL_REGdata=Read_SJA1000(REG_CONTROL);CONTROL_REGdata|=0x01;Write_SJA1000(REG_CONTROL,CONTROL_REGdata);if((Read_SJA1000(REG_CONTROL)&0x01)==0x01){SJA_mode=1; //置复位模式成功}else{SJA_mode=0; //置复位模式失败}return(SJA_mode);}/*****************************************************************函数功能:设置SJA1000波特率*入口参数:无*出口参数:setting_success****************************************************************/bit Setting_SJA1000_rate(void){bit setting_success;while(Setting_SJA1000_resetmode()==0){Setting_SJA1000_resetmode(); //设置SJA工作在复位模式}Write_SJA1000(REG_BTR0,SJA_BTR0);Write_SJA1000(REG_BTR1,SJA_BTR1);if((Read_SJA1000(REG_BTR0)==SJA_BTR0)&(Read_SJA1000(REG_BTR1)==SJA_BTR1)) {setting_success=1; //波特率设置成功}else{setting_success=0; //波特率设置失败}return(setting_success);}/*****************************************************************函数功能:设置SJA1000的滤波寄存器和屏蔽寄存器*入口参数:无*出口参数:setting_success****************************************************************/bit Setting_SJA1000_dataselect(void){bit setting_success;while(Setting_SJA1000_resetmode()==0){Setting_SJA1000_resetmode(); //设置SJA工作在复位模式}Write_SJA1000(REG_ACR,SJA_ACR);Write_SJA1000(REG_AMR,SJA_AMR);if((Read_SJA1000(REG_ACR)==SJA_ACR)&(Read_SJA1000(REG_AMR)==SJA_AMR)) {setting_success=1; //滤波器设置成功}else{setting_success=0; //滤波器设置失败}return(setting_success);}/*****************************************************************函数功能:设置SJA1000的时钟分频器*入口参数:无*出口参数:setting_success****************************************************************/bit Setting_SJA1000_CDR(void){bit setting_success;while(Setting_SJA1000_resetmode()==0){Setting_SJA1000_resetmode(); //设置SJA工作在复位模式}Write_SJA1000(REG_CDR,SJA_CDR);if(Read_SJA1000(REG_CDR)==SJA_CDR){setting_success=1; //滤波器设置成功}else{setting_success=0; //滤波器设置失败}return(setting_success);}/*****************************************************************函数功能:设置SJA1000的输出控制寄存器*入口参数:无*出口参数:setting_success****************************************************************/bit Setting_SJA1000_OCR(void){bit setting_success;while(Setting_SJA1000_resetmode()==0){Setting_SJA1000_resetmode(); //设置SJA工作在复位模式}Write_SJA1000(REG_OCR,SJA_OCR);if(Read_SJA1000(REG_OCR)==SJA_OCR){setting_success=1; //滤波器设置成功}else{setting_success=0; //滤波器设置失败}return(setting_success);}/*****************************************************************函数功能:初始化SJA1000*入口参数:无*出口参数:setting_success****************************************************************/void Initial_SJA1000(void){while(Judge_SJA1000_connect==0);do{Setting_SJA1000_resetmode();}while(Setting_SJA1000_resetmode()==0);while(Setting_SJA1000_CDR()==0);while(Setting_SJA1000_rate()==0);while(Setting_SJA1000_OCR()==0);while(Setting_SJA1000_dataselect()==0)do{Setting_SJA1000_workingmode();}while(Setting_SJA1000_workingmode()==0);}/*****************************************************************函数功能:初始化发送数据*入口参数:无*出口参数:setting_success,指示初始化是否成功****************************************************************/bit Initial_transmitter_BUF(void){bit setting_success=0;send_BUF.IDH8 = 0x30;send_BUF.IDL_R_DLC = 0x22; //IDL_R_DLC。