?? ican_interface.c
字號:
#include "config.h"
extern INT8U deviceinf[];
extern iCANSLV iCANdeviceList[];
extern ican_respond(INT8U *p,iCANSLV *p_iCANSLV);
/************************數組復制函數*************************************
作者:張森
日期:2008年4月1日
p1 指向源指針
p2 指向目標指針
d_long 復制長度
**************************************************************************/
void array_copy(INT8U *p1,INT8U *p2,INT8U d_long)
{
for(;d_long>0;d_long--)
{
*p2=*p1;
p1++;
p2++;
}
}
/************************iCAN數據格式與芯片空間格式轉換(發送)****************
作者:張森
日期:2008年4月2日
SrcMACID 源地址
DestMACID 目標地址
iCAN_ACK 請求響應
FunCID 功能ID
SourceID 資源ID
segFlag 分段標志
p 數據指針
D_long 數據長度(*p 長度)
注意:不同的芯片CAN報文在寄存器的映射不同
**************************************************************************/
void ican_send_interface(SrcMACID,DestMACID,iCAN_ACK,FunCID,SourceID,segFlag,p,D_long)
INT8U SrcMACID;
INT8U DestMACID;
INT8U iCAN_ACK;
INT8U FunCID;
INT8U SourceID;
INT8U segFlag;
INT8U *p;
INT8U D_long;
{
stcTxBUF CTBuf;
CTBuf.TxFrameInfo.Bits.PRIO_BIT=0; //緩沖區數據發送優先級的值
CTBuf.TxFrameInfo.Bits.RTR_BIT=0;//遠程幀、數據幀辨別位(RTR=0數據幀,RTR=1遠程幀)
CTBuf.TxFrameInfo.Bits.FF_BIT=1; //擴展幀、標準幀辨別位(FF=0標準幀,FF=1擴展幀)
CTBuf.TxFrameInfo.Bits.DLC_BIT=D_long+1;//發送數據長度
CTBuf.TxCANID.FrameFm.stcICAN.SourceID =SourceID;
CTBuf.TxCANID.FrameFm.stcICAN.FuncID =FunCID;
CTBuf.TxCANID.FrameFm.stcICAN.ACK =iCAN_ACK;
CTBuf.TxCANID.FrameFm.stcICAN.DestMACID =DestMACID;
CTBuf.TxCANID.FrameFm.stcICAN.SrcMACID =SrcMACID;
CTBuf.CANTDA.Bits.Data1_BIT=segFlag;
CTBuf.CANTDA.Bits.Data2_BIT=p[0];
CTBuf.CANTDA.Bits.Data3_BIT=p[1];
CTBuf.CANTDA.Bits.Data4_BIT=p[2];
CTBuf.CANTDB.Bits.Data1_BIT=p[3];
CTBuf.CANTDB.Bits.Data2_BIT=p[4];
CTBuf.CANTDB.Bits.Data3_BIT=p[5];
CTBuf.CANTDB.Bits.Data4_BIT=p[6];
CANSendData(CAN1,0,&CTBuf);
}
/************************iCAN報文分段發送函數*******************************
作者:張森
日期:2008年4月2日
DestMACID 目標地址
iCAN_ACK 請求響應
FunCID 功能ID
SourceID 資源ID
p 數據指針
D_long 數據長度(*p 長度) 0<D_long<65 程序不判斷<0的情況 如需要請自行修改
**************************************************************************/
void ican_send(INT8U DestMACID,INT8U iCAN_ACK,INT8U FunCID,INT8U SourceID,INT8U *p,char D_long)
{
INT8U segFlag=0,i,l;
if(D_long<8)
{
ican_send_interface(deviceinf[0x0e],DestMACID,iCAN_ACK,FunCID,SourceID,segFlag,p,D_long);
}
else
{
segFlag=0x40;
l=7;
for(i=0;D_long>0;)
{
if(D_long<8)
{
l=D_long;
segFlag=0xc0|i;
// D_long=0;
ican_send_interface(deviceinf[0x0e],DestMACID,iCAN_ACK,FunCID,SourceID,segFlag,p,l);
break;
}
ican_send_interface(deviceinf[0x0e],DestMACID,iCAN_ACK,FunCID,SourceID,segFlag,p,l);
i++;
segFlag=0x80|i;
D_long=D_long-7;
p=p+7;
}
}
}
/************************尋找對應從站緩沖區********************************
作者:張森
日期:2008年4月1日
SrcMAC_id 要搜索的ID
p 結構體指針
**************************************************************************/
void *find_id_buff(INT8U SrcMAC_id,iCANSLV *p)
{ INT8U i;
for(i=0;i<ICAN_SLV_NUM+1;i++)
{if(p->SlvID==SrcMAC_id)
{
return p;
}
p++;
}
return (NULL);
}
/************************iCAN數據格式與芯片空間格式轉換(接收)*********************
作者:張森
日期:2008年4月1日
**************************************************************************/
void ican_rec_interface(P_stcRxBUF rx_Buf)
{
ReadCanRxBuf(CAN1,rx_Buf);
RelCanRecBuf(CAN1);//釋放接收緩沖區
}
/************************iCAN接收數據處理******************************
作者:張森
日期:2008年4月3日
返回值:0x00 接收成功
0x01 動態內存空間不足
0x02 不支持此從站ID
0x03 消息隊列已滿
0x04 分段錯誤
0x05 非法數據格式
**************************************************************************/
INT8U ican_rec()
{
stcRxBUF ican_rec_buf;
iCANSLV *p_sla_buf;
INT8U ican_rec_transfrom_buf[13],flag_char_buf;
ican_rec_interface(&ican_rec_buf);
#if ican_soft_filter //軟件濾波宏控制
if(ican_rec_buf.RxCANID.FrameFm.stcICAN.DestMACID==deviceinf[0x0e])//&&(從站信息列表||)在此添加從站信息比對
{
#endif
if(ican_rec_buf.CANRcvFS.Bits.FF_BIT==1)//擴展數據幀
{
flag_char_buf=ican_rec_buf.CANRDA.Bits.Data1_BIT;
if(flag_char_buf==0)//沒有分段
{
/*--------------------------------------------非分段數據處理---------------------------------------------------*/
#if ican_auto_search_slave_list //自動搜獲從站列表中相應的從站空間位置返回從站列表位置
p_sla_buf=find_id_buff(ican_rec_buf.RxCANID.FrameFm.stcICAN.SrcMACID,iCANdeviceList);
if(p_sla_buf==NULL)
{
return 0x02;
}
#else
p_sla_buf=&iCANdeviceList[ican_rec_buf.RxCANID.FrameFm.stcICAN.SrcMACID];
#endif
/***************************格式整理******************************************/
ican_rec_transfrom_buf[0]=0x01;//0xff;//標志此消息是數據信息
ican_rec_transfrom_buf[1]=ican_rec_buf.CANRcvFS.Bits.DLC_BIT-1; //數據長度為 CAN數據區內容減去減去分段標號長度
ican_rec_transfrom_buf[2]=ican_rec_buf.RxCANID.FrameFm.stcICAN.SrcMACID;//源地址
ican_rec_transfrom_buf[3]=ican_rec_buf.RxCANID.FrameFm.stcICAN.ACK;//響應位
ican_rec_transfrom_buf[4]=ican_rec_buf.RxCANID.FrameFm.stcICAN.FuncID;//功能號
ican_rec_transfrom_buf[5]=ican_rec_buf.RxCANID.FrameFm.stcICAN.SourceID;//資源ID號
ican_rec_transfrom_buf[6]=ican_rec_buf.CANRDA.Bits.Data2_BIT;//數據內容1
ican_rec_transfrom_buf[7]=ican_rec_buf.CANRDA.Bits.Data3_BIT;//數據內容2
ican_rec_transfrom_buf[8]=ican_rec_buf.CANRDA.Bits.Data4_BIT;//數據內容3
ican_rec_transfrom_buf[9]=ican_rec_buf.CANRDB.Bits.Data1_BIT;//數據內容4
ican_rec_transfrom_buf[10]=ican_rec_buf.CANRDB.Bits.Data2_BIT;//數據內容5
ican_rec_transfrom_buf[11]=ican_rec_buf.CANRDB.Bits.Data3_BIT;//數據內容6
ican_rec_transfrom_buf[12]=ican_rec_buf.CANRDB.Bits.Data4_BIT;//數據內容7
/***************************格式整理結束****************************************/
//UART0_SendNByte(ican_rec_transfrom_buf,ican_rec_transfrom_buf[1]+6);
ican_respond(ican_rec_transfrom_buf,p_sla_buf);
return 0x00;
/*------------------------------------以上是非分段處理-----------------------------------------------------------*/
}
else //收到為分段幀
{
#if ican_auto_search_slave_list //自動搜獲從站列表中相應的從站空間位置返回從站列表位置
p_sla_buf=find_id_buff(ican_rec_buf.RxCANID.FrameFm.stcICAN.SrcMACID,iCANdeviceList);
if(p_sla_buf==NULL)
{
return 0x02;
}
#else
p_sla_buf=&iCANdeviceList[ican_rec_buf.RxCANID.FrameFm.stcICAN.SrcMACID];
#endif
/***************************格式整理******************************/
ican_rec_transfrom_buf[0]=0x01;//0xff;
ican_rec_transfrom_buf[1]=ican_rec_buf.CANRcvFS.Bits.DLC_BIT-1; //數據長度為CAN數據區內容 -分段標號
ican_rec_transfrom_buf[2]=ican_rec_buf.RxCANID.FrameFm.stcICAN.SrcMACID;//源地址
ican_rec_transfrom_buf[3]=ican_rec_buf.RxCANID.FrameFm.stcICAN.ACK;//響應位
ican_rec_transfrom_buf[4]=ican_rec_buf.RxCANID.FrameFm.stcICAN.FuncID;//功能號
ican_rec_transfrom_buf[5]=ican_rec_buf.RxCANID.FrameFm.stcICAN.SourceID;//資源ID號
ican_rec_transfrom_buf[6]=ican_rec_buf.CANRDA.Bits.Data2_BIT;//數據內容1
ican_rec_transfrom_buf[7]=ican_rec_buf.CANRDA.Bits.Data3_BIT;//數據內容2
ican_rec_transfrom_buf[8]=ican_rec_buf.CANRDA.Bits.Data4_BIT;//數據內容3
ican_rec_transfrom_buf[9]=ican_rec_buf.CANRDB.Bits.Data1_BIT;//數據內容4
ican_rec_transfrom_buf[10]=ican_rec_buf.CANRDB.Bits.Data2_BIT;//數據內容5
ican_rec_transfrom_buf[11]=ican_rec_buf.CANRDB.Bits.Data3_BIT;//數據內容6
ican_rec_transfrom_buf[12]=ican_rec_buf.CANRDB.Bits.Data4_BIT;//數據內容7
// ican_rec_transfrom_buf[13]=ican_rec_buf.CANRDA.Bits.Data1_BIT;
/****************************************************************************/
if((flag_char_buf & 0xc0)==0x40)//第一分段幀
{
if((flag_char_buf & 0x3f)!=0x00)//分段嗎不為零 分段錯誤
{
return 0x04;
}
array_copy(ican_rec_transfrom_buf,(*p_sla_buf).BUF,13);//放入從機分段緩沖區
}
if(flag_char_buf>0x80)//后段數據
{
if((flag_char_buf & 0x3f)*7 !=(*p_sla_buf).BUF[1])//如果分段不是比上段大1
{
//UART0_SendNByte(&(*p_sla_buf).BUF[1],1);
return 0x04;
}
array_copy(&ican_rec_transfrom_buf[6],&(*p_sla_buf).BUF[(*p_sla_buf).BUF[1]+6],ican_rec_transfrom_buf[1]);//考入對應的位置
(*p_sla_buf).BUF[1]=(*p_sla_buf).BUF[1]+ican_rec_transfrom_buf[1];//更改存入的數據長度
if(flag_char_buf>0xc0)//最后分段
{
ican_respond((*p_sla_buf).BUF,p_sla_buf);
return 0x00;
}
}
}
}
#if ican_soft_filter //軟件濾波宏控制
}//控制宏
#endif
return 0x05;
}
/************************iCAN濾波校驗初始化******************************
作者:張森
日期:2008年4月3日
**************************************************************************/
void ican_master_af(INT8U myid,INT8U chna)
{
INT32U i,u=0;
uCANAFMR afmr;
INT32U bakAfmr;
ican_stcAF_EFF_CELL mask = {-1,-1,-1,-1};
ican_stcAF_EFF_CELL *pU32= (ican_stcAF_EFF_CELL *)((INT32U)CANAFRAM_GADR + (INT32U)(CANEFF_GRP_sa)) ;
afmr.Word = CANAFMR;
bakAfmr = afmr.Word;
afmr.Bits.AccBP_BIT = 1;
CANAFMR = afmr.Word;
for(i=0;i<((CANENDofTable- CANEFF_GRP_sa)/4);i++)
{
*(pU32 + i) = mask; // disable all AF cell
}
for(i=0;i<63;i++)
{
(*(pU32 + u)).myid = myid;
(*(pU32 + u)).otherid=i;
(*(pU32 + u)).other=0;
(*(pU32 + u)).RSV_bit=chna;
// set filter cell
u++;
(*(pU32 + u)).myid = myid;
(*(pU32 + u)).otherid=i;
(*(pU32 + u)).other=-1;
(*(pU32 + u)).RSV_bit=chna;
u++;
}
CANAFMR = bakAfmr;
}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -