CAN通信机制
1.CAN通信是實現不同目標板之間的通信,因此需要相同的時鐘頻率。因此需要進行時鐘配置,一般在configPll中進行配置。進行倍頻,分頻處理等,得到合適的波特率。
2.CAN通信流程:
CAN_INIT();
對CAN進行初始化配置,包括模式,中斷等,一般為接收中斷。
? ? ? CAN_Exception();
CAN中斷處理,接收中斷,按照CAN的幀傳輸方式接收數據。
void CAN2_Exception(void)
{
??CAN2ICR &= ~0x0001;
? ?OS_ENTER_CRITICAL();
? ? pDest = (uint32 *)&MsgBuf_RX2[CanFrameCount];
? ?*pDest = CAN2RFS; ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?// Frame
? ? pDest++;
? ? *pDest = CAN2RID; ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? // ID
? ? pDest++;
? ? *pDest = CAN2RDA; ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? // Data A
? ? pDest++;
? ? *pDest = CAN2RDB; ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? // Data B
? ? CAN2CMR = 0x04; ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ??
??
VICVectAddr = 0;
OS_EXIT_CRITICAL();
}
3.CAN接收濾波器特性:
分為三種:關閉模式,旁路模式,工作模式和FullCAN模式。
一般使用旁路模式,即廣播模式。
CAN 模式選擇函數:
void CAN_SetACCF( uint32 ACCFMode )
{
? ? switch ( ACCFMode )
? ? {
? ?case ACCF_OFF:
? ? ? ?CAN_AFMR = ACCFMode;
? ? ? ?CAN1MOD = CAN2MOD = 1; // Reset CAN
? ? ? ?CAN1IER = CAN2IER = 0; // Disable Receive Interrupt
? ? ? ?CAN1GSR = CAN2GSR = 0; // Reset error counter when CANxMOD is in reset
? ?break;
? ?case ACCF_BYPASS:
? ? ? ?CAN_AFMR = ACCFMode;
? ?break;
? ?case ACCF_ON:
? ?case ACCF_FULLCAN:
? ? ? ?CAN_AFMR = ACCF_OFF;
? ? ? ?CAN_SetACCF_Lookup(); ?//Fu'llCAN模式,由驗收濾波器來訪問,硬件驗收過濾。需要進行ID查找。
? ? ? ?CAN_AFMR = ACCFMode;
? ? ? ?break;
? ?default:
? ? ? ?break;
? }
? return;
}
Fu'llCAN模式下,ID的查找函數:
void CAN_SetACCF_Lookup( void )
{
? ? uint32 address = 0;
? ? uint32 i;
? ? uint32 ID_high, ID_low;
? ? // Set explicit standard Frame
? ? CAN_SFF_SA = address;
? ? for ( i = 0; i < ACCF_IDEN_NUM; i += 2 )
? ? {
? ?ID_low = (i << 29) | (EXP_STD_ID << 16);
? ?ID_high = ((i+1) << 13) | (EXP_STD_ID << 0);
? ?*((volatile uint32 *)(CAN_MEM_BASE + address)) = ID_low | ID_high;
? ?address += 4;
? ? }
? ? // Set group standard Frame
? ? CAN_SFF_GRP_SA = address;
? ? for ( i = 0; i < ACCF_IDEN_NUM; i += 2 )
? ? {
? ? ? ? ID_low = (i << 29) | (GRP_STD_ID << 16);
? ?ID_high = ((i+1) << 13) | (GRP_STD_ID << 0);
? ?*((volatile uint32 *)(CAN_MEM_BASE + address)) = ID_low | ID_high;
? ?address += 4;
? ? }
? ? // Set explicit extended Frame
? ? CAN_EFF_SA = address;
? ? for ( i=0; i<ACCF_IDEN_NUM; i++)
? ? {
? ?ID_low = (i << 29) | (EXP_EXT_ID << 0);
? ?*((volatile uint32 *)(CAN_MEM_BASE + address)) = ID_low;
? ?address += 4;
? ? }
? ? // Set group extended Frame
? ? CAN_EFF_GRP_SA = address;
? ? for ( i = 0; i < ACCF_IDEN_NUM; i++ ?)
? ? {
? ?ID_low = (i << 29) | (GRP_EXT_ID << 0);
? ?*((volatile uint32 *)(CAN_MEM_BASE + address)) = ID_low;
? ?address += 4;
? ? }
? ? // Set End of Table
? ? CAN_EOT = address;
? ? return;
}
4,CAN2的發送函數:
INT32U CAN2_Send( CAN_MSG *pTxBuf )
{
? ? INT32U CANStatus;
? ? CANStatus = CAN2SR;
? ? if ( CANStatus & 0x00000004 )
? ? {
? ?CAN2TFI1 = pTxBuf->Frame & 0xC00F0000;
? ?CAN2TID1 = pTxBuf->MsgID;
? ?CAN2TDA1 = pTxBuf->DataA;
? ?CAN2TDB1 = pTxBuf->DataB;
? ?CAN2CMR = 0x21;
? ?return ( TRUE );
? ? }
? ? else if ( CANStatus & 0x00000400 )
? ? {
? ? ? ? CAN2TFI2 = pTxBuf->Frame & 0xC00F0000;
? ? ? ? CAN2TID2 = pTxBuf->MsgID;
? ? ? ? CAN2TDA2 = pTxBuf->DataA;
? ? ? ? CAN2TDB2 = pTxBuf->DataB;
? ? ? ? CAN2CMR = 0x41;
? ? ? ? return ( TRUE );
? ? }
? ? else if ( CANStatus & 0x00040000 )
? ? {
? ? ? ? CAN2TFI3 = pTxBuf->Frame & 0xC00F0000;
? ? ? ? CAN2TID3 = pTxBuf->MsgID;
? ? ? ? CAN2TDA3 = pTxBuf->DataA;
? ? ? ? CAN2TDB3 = pTxBuf->DataB;
? ? ? ? CAN2CMR = 0x81;
? ? ? ? return ( TRUE );
? ? }
? ? return ( FALSE );
}
5,注意:CAN的接收中斷實現時,在接收到數據后,先關掉CAN中斷使能,等數據處理完后,再打開CAN中斷使能。這樣做是防止CAN數據傳輸快,而導致之前接收到的數據未處理完,就接收到下一組數據。產生數據混亂。
總結
- 上一篇: itextsharp 获取文本_使用it
- 下一篇: 客户成功 | 数据解码技能提升,Smar