3、 CAN的收发机制:
发送:
AT32的CAN有3个发送邮箱,用户只需要:
① 通过“发送邮箱空”标志位确认一个空邮箱;
② 然后把需要发送数据帧的数据,ID等信息写入发送邮箱;
③ 写对应邮箱的“发送请求位”。
接收:
AT32F403的CAN有14个接收过滤器。接收过滤器用于过滤ID,用户可配置接收过滤寄存器,来接收想要的ID的帧,而过滤丢弃掉不需要的ID的帧。
AT32的CAN有两个接收FIFO,每个FIFO有3级深度(即每个FIFO可以存储3帧数据)。
① CAN每接收到一帧通过过滤的数据帧,该帧会被存入接收FIFO。此时FIFO变为挂号状态(即接收FIFO非空);
② 用户可以在对应的FIFO挂号中断里面去读取接收邮箱的数据。
③ 用户读取完数据后,通过置位“释放FIFOx”位来释放刚刚读取过的邮箱。
4、基于AT32F403的基础配置:
1)时钟使能:
RCC_APB2PeriphClockCmd(RCC_APB2PERIPH_GPIOB| RCC_APB2PERIPH_AFIO, ENABLE); //使能GPIOB,AFIO时钟
RCC_APB1PeriphClockCmd(RCC_APB1PERIPH_CAN1,ENABLE); //使能CAN1时钟
2)配置CAN对应GPIO口:
GPIO_PinsRemapConfig(GPIO_Remap1_CAN1,ENABLE);//CAN1重映射到PB9-TX,PB8-RX
GPIO_InitStructure.GPIO_Pins = GPIO_Pins_9;
GPIO_InitStructure.GPIO_MaxSpeed =GPIO_MaxSpeed_50MHz;
GPIO_InitStructure.GPIO_Mode =GPIO_Mode_AF_PP;
GPIO_Init(GPIOB, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pins = GPIO_Pins_8;
GPIO_InitStructure.GPIO_Mode =GPIO_Mode_IN_PU;
GPIO_Init(GPIOB, &GPIO_InitStructure);//CAN1对应GPIO配置
3)配置CAN:
CAN_InitType CAN_InitStructure;
CAN_InitStructure.CAN_TTC = DISABLE; //时间触发
通信(时间戳)--失能
CAN_InitStructure.CAN_ABO = ENABLE; //自动离线管理—使能
CAN_InitStructure.CAN_AWU = ENABLE; //自动唤醒—使能
CAN_InitStructure.CAN_NART = ENABLE; // 禁止报文自动重传—使能
CAN_InitStructure.CAN_RFL = DISABLE; // 接收FIFO锁定模式– 失能
CAN_InitStructure.CAN_TFP = DISABLE; // 发送FIFO优先级:DISABLE—标识符决定;ENABLE--发送顺序决定
CAN_InitStructure.CAN_Mode =CAN_Mode_Normal; //CAN工作模式—正常模式
CAN_InitStructure.CAN_SJW = CAN_SJW_2tq; //重同步跳跃宽度(SJW)—2tq
CAN_InitStructure.CAN_BS1 = CAN_BS1_15tq;//时间段1(BS1)--15tq
CAN_InitStructure.CAN_BS2 = CAN_BS2_2tq; //时间段2(BS2)--2tq
CAN_InitStructure.CAN_Prescaler = 4; //波特率分频(BRP)--4 //APB2_CLK=36M,baud=36/4/(1+15+2)=0.5M;
CAN_Init(CAN1, &CAN_InitStructure);
4)接收Filter配置:
CAN_FilterInitType CAN_FilterInitStructure;
CAN_FilterInitStructure.CAN_FilterNumber=7;//使用过滤器组--7
CAN_FilterInitStructure.CAN_FilterMode=CAN_FilterMode_IdList;//过滤模式—列表
CAN_FilterInitStructure.CAN_FilterScale=CAN_FilterScale_16bit;//位宽—16bit
CAN_FilterInitStructure.CAN_FilterIdLow=(u16)0x444<<5;//过滤器n对应ID—0x444
CAN_FilterInitStructure.CAN_FilterIdHigh=(u16)0x555<<5;//过滤器n+2对应ID—0x555
CAN_FilterInitStructure.CAN_FilterMskIdLow=(u16)0x666<<5;//过滤器n+1对应ID—0x666
CAN_FilterInitStructure.CAN_FilterMskIdHigh=(u16)0x777<<5;//过滤器n+3对应ID—0x777
CAN_FilterInitStructure.CAN_FilterFIFOAssignment=CAN_FIFO0;//本过滤器组关联FIFO—FIFO0
CAN_FilterInitStructure.CAN_FilterAc
tivation=ENABLE;//使能过滤器
CAN_FilterInit(&CAN_FilterInitStructure);
5)发送:
CanTxMsg TxMessage;
u8 i,Txbuff[8]={0,1,2,3,4,5,6,7};
TxMessage.ExtId = 0; //扩展ID--0
TxMessage.StdId = 0x123; //标准ID—0x123
TxMessage.IDT = 0; //ID类型选择—0-标准帧,1-扩展帧
TxMessage.RTR = 0; //数据/远程帧选择—0-数据帧,1-远程帧
TxMessage.DLC = 8; //发送数据长度(1~8)--8
for(i = 0; i< DLC; i++)
TxMessage.Data = Txbuff; //数据段—从Txbuff取数据
mbox = CAN_Transmit(CANx, &TxMessage);//选取一个空的发送邮箱,写入TxMessage,并请求发送
6)接收:
CanRxMsg RxMessage;
if( CAN_MessagePending(CAN1, FIFO0) != 0) //判断FIFO0挂起(非空)
CAN_Receive(CAN1, CAN_FIFO0, &RxMessage);//将FIFO0数据写入RxMessage,并释放接收邮箱