这些小活动你都参加了吗?快来围观一下吧!>>
电子产品世界 » 论坛首页 » 嵌入式开发 » STM32 » 基于AT32F403的CAN入门(STM32F103类似)

共3条 1/1 1 跳转至

基于AT32F403的CAN入门(STM32F103类似)

菜鸟
2020-12-14 19:19:32     打赏

1、  CAN的硬件结构:常说的CAN总线的总线就是下图的CANHCANL两根线组成的双绞线,两端通常会分别串联两个终端电阻(常见阻值为120Ω)。各个节点就通过CANHCANL两条线并到总线上,各节点可以随时插拔而不影响其他节点。每个节点都可以往总线上发送信息,总线上其他节点都可以接收这条信息。而如果两个节点同一时间发送信息,就会进行仲裁,优先级高(即ID数值小的节点)的节点仲裁胜出继续发送信息,仲裁失败的节点立即转入接收状态。

2、  CAN数据帧格式:

CAN数据帧分为两种:标准帧(对应标准ID11位)和扩展帧(对应扩展ID29位)。

以标准帧为例,一帧完整的CAN数据就包括 下图所示部分:

CAN帧结构.png


3、  CAN的收发机制:

发送:

AT32CAN3个发送邮箱,用户只需要:

   通过“发送邮箱空”标志位确认一个空邮箱;

   然后把需要发送数据帧的数据,ID等信息写入发送邮箱;

   写对应邮箱的“发送请求位”。

接收:

AT32F403CAN14个接收过滤器。接收过滤器用于过滤ID,用户可配置接收过滤寄存器,来接收想要的ID的帧,而过滤丢弃掉不需要的ID的帧。

AT32CAN有两个接收FIFO,每个FIFO3级深度(即每个FIFO可以存储3帧数据)。

   CAN每接收到一帧通过过滤的数据帧,该帧会被存入接收FIFO。此时FIFO变为挂号状态(即接收FIFO非空);

   用户可以在对应的FIFO挂号中断里面去读取接收邮箱的数据。

   用户读取完数据后,通过置位“释放FIFOx”位来释放刚刚读取过的邮箱。

4、基于AT32F403的基础配置:

1)时钟使能:

RCC_APB2PeriphClockCmd(RCC_APB2PERIPH_GPIOB | RCC_APB2PERIPH_AFIO, ENABLE); //使能GPIOBAFIO时钟

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; //时间段1BS1--15tq

CAN_InitStructure.CAN_BS2 = CAN_BS2_2tq; //时间段2BS2--2tq

CAN_InitStructure.CAN_Prescaler = 4; //波特率分频(BRP--4   //APB2_CLK=36Mbaud=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_FilterActivation=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[i] = Txbuff[i]; //数据段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,并释放接收邮箱

 







关键词: AT32F403     STM32F103     CAN    

工程师
2020-12-14 22:40:45     打赏
2楼

不错的产品


工程师
2020-12-16 22:33:34     打赏
3楼

感谢分享


共3条 1/1 1 跳转至

回复

匿名不能发帖!请先 [ 登陆 注册 ]