📄 sja1000.c
字号:
/*
****************************************Copyright (c)**************************************************
** 广州致远电子有限公司
** CAN开发组
** http://www.zyinside.com
**
**
**--------------文件信息--------------------------------------------------------------------------------
**文 件 名: SJA1000.c
**创 建 人: 滕欣欣
**创 建 日 期: 2005-04-13
**描 述: SJA1000 CAN控制器操作函数定义
**最后修改日期: 2006-03-03
**原 始 版 本: v1.0
**最 后 版 本: v1.2
**--------------历史修改--------------------------------------------------------------------------------
**修 改 人:
**修 改 日 期:
**修 改 原 因:
**修 改 版 本:
********************************************************************************************************
*/
#include "sja1000.h"
#include "config.h"
extern stcSJA1000_BufInfo SJA1000_RxBuf;
/*
********************************************************************************************************************
**函数原型 : BOOL SJA_SoftRst(BOOL bIsRst)
**参数说明 : bIsRst -> TURE SJA1000进入软件复位模式
** : FALSE SJA1000退出软件复位模式
**返回值 : TURE -> 成功完成相应设置
** : FALSE -> 设置失败
**说 明 :
********************************************************************************************************************
*/
BOOL SJA_SoftRst(BOOL IsRst)
{
uRsgMod ModTemp;
INT8U Statu;
ModTemp.Byte = Read_SJA1000(MOD)&0x1F;
ModTemp.Bits.RM = (TRUE == IsRst)? 1:0;
Write_SJA1000(ModTemp.Byte, MOD);
ModTemp.Byte = Read_SJA1000(MOD)&0x1F;
Statu = (ModTemp.Bits.RM == 1)? TRUE:FALSE;
return (Statu == IsRst)? TRUE:FALSE;
}
/*
********************************************************************************************************************
**函数原型 : BOOL SetModeReg(INT8U Val, BOOL bIsEn)
**参数说明 : Val -> 设置模式值 MOD_LOM 只听模式
** : MOD_STM 自测试模式
** : MOD_AFM_SIG 单滤波方式
** : MOD_AFM_DOB 双滤波方式
** : bIsEn -> 设定方式 TRUE 使能设定
** ; FALSE 禁能设定
**返回值 : TURE -> 成功完成相应设置
** : FALSE -> 设置失败
**说 明 : 该函数设定SJA1000模式,必须在软件复位模式中调用,否则失败,模式值可并联使用
********************************************************************************************************************
*/
BOOL SetModeReg(INT8U Val, BOOL bIsEn)
{
uRsgMod ModTemp;
ModTemp.Byte = Read_SJA1000(MOD)&0x1F;
if(ModTemp.Bits.RM)
{
if(Val&MOD_LOM)
{
ModTemp.Bits.LOM = (TRUE == bIsEn)? 1:0;
}
if(Val&MOD_STM)
{
ModTemp.Bits.STM = (TRUE == bIsEn)? 1:0;
}
if(Val&MOD_AFM_SIG)
{
ModTemp.Bits.AFM = 1;
}
if(Val&MOD_AFM_DOB)
{
ModTemp.Bits.AFM = 0;
}
}
else
return FALSE;
Write_SJA1000(ModTemp.Byte,MOD);
if(ModTemp.Byte == (Read_SJA1000(MOD)&0x1F))
{
return TRUE;
}
else
return FALSE;
}
/*
********************************************************************************************************************
**函数原型 : BOOL EnterSleepMod(BOOL IsEn)
**参数说明 : IsEn -> SJA1000请求进入复位模式
**返回值 : TURE -> 成功完成相应设置
** : FALSE -> 设置失败
**说 明 : 该函数必须在工作模式下调用,否则失败
********************************************************************************************************************
*/
BOOL EnterSleepMod(BOOL IsEn)
{
uRsgMod ModTemp;
INT8U Statu;
ModTemp.Byte = Read_SJA1000(MOD)&0x1F;
if(ModTemp.Bits.RM) return FALSE;
ModTemp.Bits.SM = (TRUE == IsEn)? 1:0;
Write_SJA1000(ModTemp.Byte,MOD);
ModTemp.Byte = Read_SJA1000(MOD)&0x1F;
Statu = (ModTemp.Bits.SM == 1)? TRUE:FALSE;
return (Statu == IsEn)? TRUE:FALSE;
}
/*
********************************************************************************************************************
**函数原型 : BOOL SetCommand(INT8U Cmd)
**参数说明 : Cmd -> 命令字 CMR_NOM_SD 正常发送
** : CMR_SIG_SD 单次发送
** : CMR_SLF_SD 自发自收
** : CMR_CL_BUF 释放接收缓缓冲区
** : CMR_CL_DATA 清除数据溢出状态
**返回值 : 无
**说 明 : 每次调用该函数只能发送一条命令值
********************************************************************************************************************
*/
void SetCommand(INT8U Cmd)
{
uRsgCmd CMRTemp;
CMRTemp.Byte = 0;
switch(Cmd)
{
case CMR_SIG_SD:
CMRTemp.Bits.AT = 1;
case CMR_NOM_SD:
if(1 == (Read_SJA1000(MOD)&0x04))
{
while(TRUE != SJA_SoftRst(TRUE));
while(TRUE != SetModeReg(MOD_STM,FALSE));
while(TRUE != SJA_SoftRst(FALSE));
}
CMRTemp.Bits.TR = 1;
break;
case CMR_SLF_SD:
if(0 == (Read_SJA1000(MOD)&0x04))
{
while(TRUE != SJA_SoftRst(TRUE));
while(TRUE != SetModeReg(MOD_STM,TRUE));
while(TRUE != SJA_SoftRst(FALSE));
}
CMRTemp.Bits.SRR = 1;
CMRTemp.Bits.AT = 1;
break;
case CMR_CL_BUF:
CMRTemp.Bits.RR = 1;
break;
case CMR_CL_DATA:
CMRTemp.Bits.CDO = 1;
break;
default:
break;
}
Write_SJA1000(CMRTemp.Byte,CMR);
}
/*
********************************************************************************************************************
**函数原型 : BOOL SetInterrupt(INT8U Val, BOOL IsEn)
**参数说明 : Val -> 中断值 IER_RC--IER_BE
** : IsEn -> 是否使能该中断
**返回值 :
**说 明 : 中断值可并联使用,全部使能,禁能中断时可使用 IER_ALL
********************************************************************************************************************
*/
BOOL SetInterrupt(INT8U Val, BOOL IsEn)
{
INT8U IntVal;
INT8U temp;
if(TRUE == IsEn)
{
Write_SJA1000(Val,IER);
temp = Read_SJA1000(IER);
if(temp == Val)
{
return TRUE;
}
else
{
return FALSE;
}
}
else
{
IntVal = Read_SJA1000(IER);
IntVal &= ~Val;
Write_SJA1000(IntVal,IER);
return (IntVal == Read_SJA1000(IER))? TRUE:FALSE;
}
}
/*
********************************************************************************************************************
**函数原型 : BOOL SetBaudRate(INT16U BaudVal)
**参数说明 : BaudVal -> 波特率值,由 定时器0<<8|定时器1 组成
**返回值 :
**说 明 : 该函必须在软件复位模式下调用
********************************************************************************************************************
*/
BOOL SetBaudRate(INT16U BaudVal)
{
INT16U h, l;
if(1 == (Read_SJA1000(MOD)&0x01))
{
Write_SJA1000((INT8U)(BaudVal>>8),BTR0);
Write_SJA1000((INT8U)(BaudVal&0xFF),BTR1);
h = Read_SJA1000(BTR0) << 8;
l = Read_SJA1000(BTR1);
if(BaudVal == (h + l))
{
return TRUE;
}
else
{
return FALSE;
}
}
else
return FALSE;
}
/*
********************************************************************************************************************
**函数原型 : BOOL SetOutPutMod(INT8U Val)
**参数说明 : Val -> 输出模式值
**返回值 :
**说 明 : 通常设为0x1A
********************************************************************************************************************
*/
BOOL SetOutPutMod(INT8U Val)
{
Write_SJA1000(Val,OCR);
return (Val == Read_SJA1000(OCR))? TRUE:FALSE;
}
/*
********************************************************************************************************************
**函数原型 : BOOL SetClkDiv(INT8U CAN_Mod,BOOL bRxINTEn,BOOL bClkOFF,INT8U Div)
**参数说明 : CAN_Mod -> CAN模式值 BAIS_CAN
** : PELI_CAN
** : bRxINTEn -> 是否使用Tx1引脚作为接收中断指示
** : bClkOFF -> 是否使用频率输出引脚
** : Div -> 0-7,表示(Val+1)*2分频
**返回值 :
**说 明 : 该函数必须在软件复位模式下调用
********************************************************************************************************************
*/
BOOL SetClkDiv(INT8U CAN_Mod,BOOL bRxINTEn,BOOL bClkOFF,INT8U Div)
{
INT8U CDRTemp = 0;
INT8U RxINTTemp = (bRxINTEn == TRUE)? 1:0;
INT8U ClkOffTemp = (bClkOFF == TRUE)? 1:0;
if(1 == (Read_SJA1000(MOD)&0x01))
{
CDRTemp = CAN_Mod<<7|0x01<<6|RxINTTemp<<5|ClkOffTemp<<3|Div;
Write_SJA1000(CDRTemp,CDR);
}
else
return FALSE;
return ((CDRTemp == Read_SJA1000(CDR))? TRUE:FALSE);
}
/*
********************************************************************************************************************
**函数原型 : void SetTxBuf(stcSJA1000_TxInfo *pTxInfo)
**参数说明 : pTxInfo -> 发送数据的结构体指针
**返回值 :
**说 明 : 调用该函数写入欲发送的数据
********************************************************************************************************************
*/
void SetTxBuf(stcSJA1000_BufInfo *pTxInfo)
{
INT8U i;
INT32U IDTemp;
Write_SJA1000(pTxInfo->FrIf.Byte,TXBUF);
if(1 == pTxInfo->FrIf.Bits.FF)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -