📄 car_3.c
字号:
return(SJAREG_data);
}
//-------------------------------------------------
// 函数名称 SJA1000_init
// 操作寄存器 1)控制寄存器(地址00)
// 2)收代码寄存器ACR(地址04)
// 3)验收屏蔽寄存器AMR(地址05)
// 4)总线定时寄存器BTR0(地址06)
// 5)总线定时寄存器BTR1(地址07)
// 6)输出控制寄存器OCR(地址08)
// 7)测试寄存器(地址09)
// 8)和时钟分频寄存器CDR(地址31)
// 函数功能 SJA1000初始化设置
// 特殊要求 在复位模式进行,初始化结束进入工作状态
//---------------------------------------------------
void SJA1000_init(void)
{
while(connect_OK==0)
{
SJAconnect_judge(); //检测设备连接
}
while(SJA_workmode)
{
setting_SJA_resetmode(); //置SJA1000为复位工作模式
}
while(setting_rate_success==0)
{
setting_SJA_rate(); //设置总线波特率
}
while(setting_dataselect_success==0)
{
setting_SJA_dataselect(); //设置SJA接收数据的格式(标示位)
}
while(setting_clk_success==0)
{
setting_SJA_CLK(); //设置SJA输出始终的形式
}
setting_SJA_interrupt(); //设置SJA中断类型
}
//---------------------------------------
// 函数名称 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; //连接故障
}
}
//-----------------------------------------
// 函数名称 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; //置工作模式失败
}
}
//-----------------------------
// 函数名称 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; //置复位模式失败
}
}
//-----------------------------------------
// 函数名称 setting_SJA_rate
// 操作寄存器 总线定时寄存器BTR1(地址07)和BTR0(地址06)
// 函数功能 设置SJA波特率
// 特殊要求 只能在复位工作模式下设置
//----------------------------------------
void setting_SJA_rate(void)
{
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_rate_success=1; //波特率设置成功
}
else
{
setting_rate_success=0; //波特率设置失败
}
}
//----------------------------------------------
// 函数名称 setting_SJA_dataselect
// 操作寄存器 验收代码寄存器ACR(地址04)和验收屏蔽寄存器AMR(地址05)
// 函数功能 设置SJA接收数据类型
// 特殊要求 只能在复位工作模式下设置
//--------------------------------------------
void setting_SJA_dataselect(void)
{
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_dataselect_success=1; //滤波器设置成功
}
else
{
setting_dataselect_success=0; //滤波器设置失败
}
}
//-------------------------------------------
// 函数名称 setting_SJA_CLK
// 操作寄存器 输出控制寄存器OCR(地址08)和时钟分频寄存器CDR(地址31)
// 函数功能 设置SJA输出始终类型
// 特殊要求 只能在复位工作模式下设置
//-----------------------------------------
void setting_SJA_CLK(void)
{
while(SJA_workmode)
{
setting_SJA_resetmode(); //设置SJA工作在复位模式
}
CANREG_write(0x08,SJA_OCR);
CANREG_write(31,SJA_CDR);
if((CANREG_read(0x08)==SJA_OCR)&(CANREG_read(31)==SJA_CDR))
{
setting_clk_success=1; //滤波器设置成功
}
else
{
setting_clk_success=0; //滤波器设置失败
}
}
//-------------------------------------------
// 函数名称 setting_SJA_interrupt
// 操作寄存器 控制寄存器(00)
// 函数功能 设置SJA中断类型和中断状态
// 特殊要求 只能在复位工作模式下设置
//-------------------------------------------
void setting_SJA_interrupt(void)
{
while(SJA_workmode)
{
setting_SJA_resetmode(); //设置SJA工作在复位模式
}
CANREG_write(0x00,0x1E); //使能溢出中断,错误中断,接收中断,禁止发送中断
}
//---------------------------------------
// 函数名称 Write_SJAsendBUF
// 操作寄存器 接收缓存器(20-29)状态寄存器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(0x10,send_BUF.FrameID_H);
CANREG_write(0x11,(send_BUF.FrameLENTH<<4)||(send_BUF.FrameKIND<<3)||(send_BUF.FrameID_L3));
if(send_BUF.FrameKIND==0)
{for(i=0;i<send_BUF.FrameLENTH,i<8;i++)
CANREG_write(0x12+i,send_BUF.Frame_Data[i]);
}
setting_success=1; //发送寄存器写成功
}
}
return(setting_success);
}
//---------------------------------------
// 函数名称 read_SJAreceiveBUF
// 操作寄存器 接收缓存器(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.FrameID_H=CANREG_read(0x20);
receive_BUF.FrameLENTH=((CANREG_read(0x21)&0xF0)>>4);
receive_BUF.FrameKIND=((CANREG_read(0x21)&0x08)>>3);
receive_BUF.FrameID_L3=(CANREG_read(0x21)&0x07);
if(receive_BUF.FrameKIND==0)
{for(i=0;i<receive_BUF.FrameLENTH,i<8;i++)
receive_BUF.Frame_Data[i]=CANREG_read(0x22+i);
}
setting_success=1; //接收寄存器读成功
}
}
return(setting_success);
}
//---------------------------------------
// 函数名称 cansend
// 函数功能 写CAN发送缓冲区并启动发送
// 特殊要求 只能在工作模式下写
//----------------------------------------
void cansend(void)
{
send_BUF.FrameID_H=0x01; //封装CAN标准数据帧
send_BUF.FrameLENTH=0x01;
send_BUF.FrameKIND=0x00;
send_BUF.FrameID_L3=0x00;
send_BUF.Frame_Data[0]=Car_weight;
Write_SJAsendBUF(); //写SJA发送缓冲区
BCAN_CMD_PRG(TR_CMD); //启动SJA发送
}
//---------------------------------------
//函数名称 BCAN_CMD_PRG
//操作寄存器: 命令寄存器(03)
//函数功能 执行sja1000命令(01 发送请求
// 02 中止发送
// 04 释放接收缓冲区
// 08 清除超载状态
// 0x10 进入睡眠状态
// )
//特殊要求 只能在工作模式下写
//---------------------------------------
bit BCAN_CMD_PRG(unsigned char cmd)
{
CANREG_write(0x01,cmd); //访问地址指向命令寄存器,写入命令字
switch(cmd)
{
case TR_CMD: //发送请求命令
return 0;
break;
case AT_CMD: //夭折发送命令
if((CANREG_read(0x01)&0x20)==0) //访问地址指向状态寄存器, 判断是否正在发送
{
return 0;
}
else
{
return 1;
}
break;
case RRB_CMD: //释放接收缓冲区
if((CANREG_read(0x01)&0x01)==1) //访问地址指向状态寄存器, 判断是否释放成功
{
return 1;
}
else
{
return 0;
}
break;
case COS_CMD: //清除超载状态
if((CANREG_read(0x01)&0x02)==0) //访问地址指向状态寄存器,判断清除超载是否成功
{
return 0;
}
else
{
return 1;
}
break;
case GTS_CMD: //进入睡眠状态命令
return 0;
break;
default:
return 1;
break;
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -