📄 canbus.c
字号:
#include<reg51.h>
#include<SJA1000REG.h>
#define uchar unsigned char
unsigned char Send_CAN_Filter[8]={0x00,0x00,0x00,0x00,0xff,0xff,0xff,0xff};
unsigned char Send_CAN_Info_ID[5]={0x88,0x00,0x00,0x00,0x00};
unsigned char BTR0,BTR1;
unsigned char Send_CAN_Data[8]={0x31,0x32,0x13,0x14,0x05,0x06,0x07,0x08};
unsigned char Rec_CAN_Filter[8]={0x00,0x0D,0x0C,0x0A,0x45,0x01,0x23,0x12};
unsigned char Rec_CAN_Data[8];
bit Send_Enable;
bit SJAQuitResetMode();
sbit SJA_RST=P2^5;//硬件复位信号
sbit SJA_CS=P2^7;//片选择
sbit SJA_MODE=P2^6;//模式选择
sbit INIT_ERR_LED=P1^1;//初始化错误指示。
sbit RST=P1^3;//硬件复位
uchar bdata EINT_flag=0x00;
sbit Rec_flag=EINT_flag^0;
sbit Send_flag=EINT_flag^1;
/*****************************************************************************************************
/*************延时N ms********************************************
******************************************************************************************************/
void delay_NMS(int j)
{
int k,l;
for(l=0;l<=j;l++)
for(k=0;k<=250;k++);
}
/*--------------------------------------------------------------------------------------------------------
** 函数原型: unsigned char ReadSJAReg(unsigned char RegAdr)
** 功能描述: 该函数用于读出sja1000的指定的寄存器
** 参数说明: RegAdr 要读的sja1000的内部寄存器地址
** 返回值: 内部寄存器Reg的值
** 全局变量:
** 调用模块:
** 作 者:
** 日 期:
/*------------------------------------------------------------------------------------------------------*/
unsigned char ReadSJAReg(unsigned char RegAdr)
{
uchar tes,TES1,T;
tes=RegAdr;
T=*(SJA_CS_Point+RegAdr);
delay_NMS(100);
TES1=RegAdr;
return T;
}
/*--------------------------------------------------------------------------------------------------------
** 函数原型: unsigned char WriteSJAReg(unsigned char RegAdr,unsigned char Value)
** 功能描述: 该函数用于将指定的数值写入sja1000的指定的寄存器
** 参数说明: RegAdr 要读的sja1000的内部寄存器地址
** Value 写入寄存器的值
** 返回值: 0 写入正确
** 1 写入不正确
** 全局变量:
** 调用模块:
** 作 者:
** 日 期:
/*------------------------------------------------------------------------------------------------------*/
bit WriteSJAReg(unsigned char RegAdr,unsigned char Value)
{
*(SJA_CS_Point+RegAdr)=Value;
if(*(SJA_CS_Point+RegAdr)==Value)
return 0;
else
return 1;
}
/*--------------------------------------------------------------------------------------------------------
** 函数原型: unsigned char WriteSJARegBlock(unsigned char RegAdr,unsigned char *ValueBuf,unsigned char len)
** 功能描述: 该函数用于将指定的数值写入sja1000的指定的寄存器
** 参数说明: RegAdr 要写入的sja1000的内部寄存器地址
** ValueBuf 要写入寄存器的值
** len 要写入sja1000内部寄存器的长度
** 返回值: 1 写入正确
** 0 写入不正确
** 全局变量:
** 调用模块:
** 作 者:
** 日 期:
/*------------------------------------------------------------------------------------------------------*/
bit WriteSJARegBlock(unsigned char RegAdr,unsigned char *ValueBuf,unsigned char len) reentrant
{
unsigned char i;
uchar val0=0xff,val1=0xff,SR_VAL=0xff;
for(i=0;i<len;i++)
{
SR_VAL=*(SJA_CS_Point+2);
*(SJA_CS_Point+RegAdr+i)=ValueBuf[i];
val0=ValueBuf[i];
val1=*(SJA_CS_Point+RegAdr+i);
}
for(i=0;i<len;i++)
{
if(ValueBuf[i]!=*(SJA_CS_Point+RegAdr+i))
return 1; //当出现一个不相等就返回
}
return 0;
}
/*--------------------------------------------------------------------------------------------------------
** 函数原型: unsigned char ReadSJARegBlock(unsigned char RegAdr,unsigned char *ValueBuf,unsigned char len)
** 功能描述: 该函数用 于读一串寄存器的值
** 参数说明: RegAdr 要读的sja1000的内部寄存器地址
** ValueBuf 要存储读出寄存器的值的存储器地址
** len 要读出sja1000内部寄存器的长度
** 返回值: 0 读出正确
** 1 读出不正确
** 全局变量:
** 调用模块:
** 作 者:
** 日 期:
/*------------------------------------------------------------------------------------------------------*/
bit ReadSJARegBlock(unsigned char RegAdr,unsigned char *ValueBuf,unsigned char len)
{
unsigned char i;
for(i=0;i<len;i++)
{
ValueBuf[i]=*(SJA_CS_Point+RegAdr+i);
}
for(i=0;i<len;i++)
{
if(ValueBuf[i]!=*(SJA_CS_Point+RegAdr+i))
return 1; //当出现一个不相等就返回
}
return 0;
}
/**************************************************************************************************************
进入复位模式
**************************************************************************************************************/
bit SJAEntryResetMode(void)
{
unsigned char TempData;
TempData=*SJA_CS_Point;
*SJA_CS_Point=TempData|0x01;
if((*SJA_CS_Point&0x01)==1)
return 0;
else
return 1;
}
/**************************************************************************************************************
进入复位模式
**************************************************************************************************************/
bit SJAQuitResetMode(void)
{
unsigned char TempData;
TempData=*SJA_CS_Point;
*SJA_CS_Point=TempData&0xfe;
if((*SJA_CS_Point&0x01)==1)
return 1;
else
return 0;
}
/*----------------------------------------------------------------------------------------------------------------
**错误闪烁
-------------------------------------------------------------------------------------------------------------------*/
void led(){
uchar i;
for(i=0;i<4;i++){
INIT_ERR_LED=0;
delay_NMS(200);
INIT_ERR_LED=1;
delay_NMS(200);
}
}
/*-----------------------------------------------------------------------------------------------------------------
**初始化函数
--------------------------------------------------------------------------------------------------------------------*/
void SJA1000_Config_Normal() //正常模式的初始化
{
bit i;
BTR0=0x00;
BTR1=0x14;
do{
i=SJAEntryResetMode(); //进入复位模式
if(i)
led();
}while(i);
do{
i=WriteSJAReg(REG_CAN_CDR,0xC8); //配置时钟分频寄存器,选择PeliCAN模式
if(i)
led();
}while(i);
do{
i=WriteSJAReg(REG_CAN_MOD,0x05); //配置模式寄存器,选择双滤波MOD.3=0、正常模式MOD.4=0,MOD.4=1自测模式
if(i)
led();
}while(i);
do{
i=WriteSJARegBlock(16,Send_CAN_Filter,8); //配置验收代码/屏蔽寄存器 --------已经全部屏蔽
if(i)
led();
}while(i);
do{
i=WriteSJAReg(REG_CAN_BTR0,BTR0); //配置总线定时器0
if(i)
led();
}while(i);
do{
i=WriteSJAReg(REG_CAN_BTR1,BTR1); //配置总线定时器1
if(i)
led();
} while(i);
do{
i=WriteSJAReg(REG_CAN_OCR,0x1a); //配置输出管脚
if(i)
led();
}while(i);
do{
i=SJAQuitResetMode(); //退出复位模式,进入工作模式
led();
}while(i);
}
/*--------------------------------------------------------------------------------------------------------
**外部中断初始化
---------------------------------------------------------------------------------------------------------*/
void Init_Cpu( void )
{
PX1=1;
IT1=1;
EX1=1;
EA=1;
}
/*------------------------------------------------------------------------------------------------------
**串口初始化函数
--------------------------------------------------------------------------------------------------------*/
void UART_init(){
SCON=0x50;//工作在方式1,允许接受?
PCON=0x00;
TMOD=0x20;//定时器1工作在方?2
TH1=0xfd;
TL1=0xfd;//实现数据传送速率9600bit/s 11.0592M系统时
TR1=1;
ES=1;
PS=1;
EA=1;
}
/*------------------------------------------------------------------------------------------------------
**硬件复位函数
---------------------------------------------------------------------------------------------------------*/
void SJAHardwareReset(){
RST=1;
delay_NMS(500);
RST=0;
}
/*------------------------------------------------------------------------------------------------------
**接收中断
--------------------------------------------------------------------------------------------------------*/
void Receive_int() interrupt 2 using 2{
uchar x;
x=*(SJA_CS_Point+REG_CAN_IR);
EINT_flag=x;
}
/*----------------------------------------------------------------------------------------------------
**SJA1000发送函数
-----------------------------------------------------------------------------------------------------*/
void send()
{
bit Send_Enable;
unsigned char sr,i;
sr=ReadSJAReg(2);
if((sr&0x0C)==0x0C)
Send_Enable=1;
else
Send_Enable=0;
if(Send_Enable==1)
{
//WriteSJARegBlock(21,Send_CAN_Data,8);
for(i=0;i<8;i++){
*(SJA_CS_Point+21+i)=Send_CAN_Data[i];
}
WriteSJAReg(REG_CAN_CMR,0x012); //使能发送请求,产生字接收性质的发送
while(((ReadSJAReg(REG_CAN_SR))&0x08)!=0x08);
//sr=ReadSJAReg(REG_CAN_IR);
if((ReadSJAReg(REG_CAN_SR)&0x08)==0x08)
led();
else
{
delay_NMS(200); //延时200ms再判断
if((ReadSJAReg(REG_CAN_IR)&0x08)!=0x08) //发送失败,停止发送
Send_Enable=0;
else
led();
}
delay_NMS(100);
}
}
void UART_send(uchar dat){
SBUF=dat;
while(TI==0);
TI=0;
}
void main(){
uchar tes=0xff,i,tes1=0x55;
uchar R_data[8];
//bit test=0,;
P1=0xff; //熄灭指示灯
RST=0;
SJAHardwareReset();
SJA_CS_Point=&CAN_SJA_BaseAdr;
SJA1000_Config_Normal();
while(1){
*(SJA_CS_Point)=0x21;
tes1=*(SJA_CS_Point);
*(SJA_CS_Point+16)=0x22;
tes=*(SJA_CS_Point+16);
}
Init_Cpu();
Send_flag=0;
Rec_flag=0;
WriteSJAReg(REG_CAN_IER,0x01); //0x01使能SJA1000接收中断位,0x02发送中断
// tes=ReadSJAReg(REG_CAN_IER); //使能SJA1000发送中断位
//WriteSJAReg(28,0x12);
//WriteSJAReg(REG_CAN_CMR,1); //使能发送请求
//tes=ReadSJAReg(28);
tes=ReadSJAReg(2);
WriteSJAReg(REG_CAN_CMR,4);
tes=ReadSJAReg(2);
for(i=0;i<5;i++){ //写识别码
*(SJA_CS_Point+16+i)=Send_CAN_Info_ID[i];
}
//tes1=ReadSJAReg(REG_CAN_IR);
// tes=TCON;
send();
tes=ReadSJAReg(REG_CAN_IR);
/* WriteSJAReg(21,0x25);
tes=ReadSJAReg(21);
tes1=ReadSJAReg(REG_CAN_IR);//读取中断状态则INT变高
WriteSJAReg(22,0x26);
tes=ReadSJAReg(22);*/
while(1){
if(ReadSJAReg(REG_CAN_IR)&0x01==0x01){
R_data[0]=ReadSJAReg(21);
R_data[1]=ReadSJAReg(23);
}
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -