STM32 CAN 配置 过滤器测试可用

 

//======================================================================================//

使用32位的掩码模式,但只使用了后16位作为ID 。发送的话我们直接使用32位的扩展ID:

过滤器的ID和掩码MASK需要做按位平移

      CAN_FilterInitStructure.CAN_FilterMode=CAN_FilterMode_IdMask; 
      CAN_FilterInitStructure.CAN_FilterScale=CAN_FilterScale_32bit; //32位 
      CAN_FilterInitStructure.CAN_FilterIdHigh=((Mask_ID<<3) >>16) &0xffff;32位ID
      CAN_FilterInitStructure.CAN_FilterIdLow=(Mask_ID <<3);
      CAN_FilterInitStructure.CAN_FilterMaskIdHigh= 0x0007;//32位MASK
      CAN_FilterInitStructure.CAN_FilterMaskIdLow= 0xFFF8;

下图中红线处是我们要设置的ID位置。

//======================================================================================//

下面是实现程序:

使用头文件:

#ifndef __CAN_H
#define __CAN_H	 
#include "stm32f10x.h"   
#define master 1

#if master 
	#define SEND_ID 0x1314	//从设备ID,用于发送
	#define Mask_ID 0x1315	//过滤器识别ID
#else  
	#define SEND_ID 0x1315	//从设备ID,用于发送
	#define Mask_ID 0x1314	//过滤器识别ID
#endif
		
u8 CAN_Mode_Init(void);//CAN初始化
 
u8 Can_Send_Msg(u8* msg,u8 len);						//发送数据

u8 Can_Receive_Msg(u8 *buf);							//接收数据
#endif

使用c文件:

#include "can.h"
#include "stdio.h"

u8 CAN_Mode_Init(void)//PA11-CAN_RX PA12-CAN_TX
{

	GPIO_InitTypeDef 		GPIO_InitStructure; 
	CAN_InitTypeDef        	CAN_InitStructure;
 	CAN_FilterInitTypeDef  	CAN_FilterInitStructure;
   	NVIC_InitTypeDef  		NVIC_InitStructure;

	RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO | RCC_APB2Periph_GPIOA  ENABLE);//使能PORTA时钟	                   											 

  	RCC_APB1PeriphClockCmd(RCC_APB1Periph_CAN1, ENABLE);//使能CAN1时钟	

    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;	//复用推挽
    GPIO_Init(GPIOA, &GPIO_InitStructure);		//初始化IO
   
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;//上拉输入
    GPIO_Init(GPIOA, &GPIO_InitStructure);//初始化IO
	
	
	CAN_DeInit(CAN1);
 	//CAN单元设置
 	CAN_InitStructure.CAN_TTCM=DISABLE;						 //非时间触发通信模式  //
	CAN_InitStructure.CAN_ABOM=DISABLE;						 //软件自动离线管理	 //
  	CAN_InitStructure.CAN_AWUM=DISABLE;						 //睡眠模式通过软件唤醒(清除CAN->MCR的SLEEP位)//
	CAN_InitStructure.CAN_NART=DISABLE;						 //禁止报文自动传送 //
  	CAN_InitStructure.CAN_RFLM=DISABLE;						 //报文不锁定,新的覆盖旧的 // 
  	CAN_InitStructure.CAN_TXFP=DISABLE;						 //优先级由报文标识符决定 //
  	CAN_InitStructure.CAN_Mode= CAN_Mode_Normal;	         //模式设置: mode:0,普通模式;1,回环模式; //
  	//设置波特率
  	CAN_InitStructure.CAN_SJW=CAN_SJW_1tq;					//重新同步跳跃宽度(Tsjw)为tsjw+1个时间单位  CAN_SJW_1tq	 CAN_SJW_2tq CAN_SJW_3tq CAN_SJW_4tq
  	CAN_InitStructure.CAN_BS1=CAN_BS1_8tq; 					//Tbs1=tbs1+1个时间单位CAN_BS1_1tq ~CAN_BS1_16tq
  	CAN_InitStructure.CAN_BS2=CAN_BS2_7tq;					//Tbs2=tbs2+1个时间单位CAN_BS2_1tq ~CAN_BS2_8tq
  	CAN_InitStructure.CAN_Prescaler=50;            			//分频系数(Fdiv)为brp+1	//
  	CAN_Init(CAN1, &CAN_InitStructure);            			// 初始化CAN1 
	/*= 36000 / ((7+1+8)*50)  =45kps*/
 	CAN_FilterInitStructure.CAN_FilterNumber=0;	  			//过滤器0
 	CAN_FilterInitStructure.CAN_FilterMode=CAN_FilterMode_IdMask; 
  	CAN_FilterInitStructure.CAN_FilterScale=CAN_FilterScale_32bit; //32位 
  	CAN_FilterInitStructure.CAN_FilterIdHigh=((Mask_ID<<3) >>16) &0xffff;32位ID
  	CAN_FilterInitStructure.CAN_FilterIdLow=(Mask_ID <<3);
  	CAN_FilterInitStructure.CAN_FilterMaskIdHigh= 0x0007;//32位MASK
  	CAN_FilterInitStructure.CAN_FilterMaskIdLow= 0xFFF8;
  	CAN_FilterInitStructure.CAN_FilterFIFOAssignment=CAN_Filter_FIFO0;//过滤器0关联到FIFO0
 	CAN_FilterInitStructure.CAN_FilterActivation=ENABLE; //激活过滤器0
  	CAN_FilterInit(&CAN_FilterInitStructure);//滤波器初始化
	
	CAN_ITConfig(CAN1,CAN_IT_FMP0,ENABLE);//FIFO0消息挂号中断允许.	//接收中断允许.		    
	
  	NVIC_InitStructure.NVIC_IRQChannel = USB_LP_CAN1_RX0_IRQn;
  	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;     // 主优先级为1
  	NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;            // 次优先级为0
  	NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
  	NVIC_Init(&NVIC_InitStructure);
	
	return 0;
}   

//中断服务函数			    
void USB_LP_CAN1_RX0_IRQHandler(void)
{
  	CanRxMsg RxMessage;
	int i=0;
    CAN_Receive(CAN1, 0, &RxMessage);
	for(i=0;i<8;i++)
	
	printf("rxbuf[%d]:%d\r\n",i,RxMessage.Data[i]);
}

//can发送一组数据(固定格式:ID为0X12,标准帧,数据帧)	
//len:数据长度(最大为8)				     
//msg:数据指针,最大为8个字节.
u8 Can_Send_Msg(u8* msg,u8 len)
{	
  u8 mbox;
  u16 i=0;
  CanTxMsg TxMessage;
  TxMessage.StdId=0;			// 标准标识符为0
  TxMessage.ExtId=SEND_ID;		// 设置扩展标示符(29位)
  TxMessage.IDE=CAN_ID_EXT;		// 使用扩展标识符
  TxMessage.RTR=CAN_RTR_DATA;	// 消息类型为数据帧,一帧8位
  TxMessage.DLC=len;			// 发送两帧信息
  for(i=0;i<len;i++)
  TxMessage.Data[i]=msg[i];		// 第一帧信息          
  mbox= CAN_Transmit(CAN1, &TxMessage);   
  i=0;
  while((CAN_TransmitStatus(CAN1, mbox)==CAN_TxStatus_Failed)&&(i<0XFFF))i++;	//等待发送结束
  if(i>=0XFFF)return 1;
  return 0;		
}

 

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
STM32F103VETX是一款基于ARM Cortex-M3核的微控制器,它具有CAN(Controller Area Network)。CAN拓展帧是CAN总中的一种数据帧格式,用于传输更多的数据信息。 在STM32F103VETX上初始化CAN拓展帧的函数可以通过以下骤完成: 1. 配置GPIO引脚首先需要配置CAN通信所使用的GPIO引脚。可以使用GPIO_Init函数来配置引脚的模式速度和复用功能。 2. 能CAN时钟:使用RCC_APB1ClockCmd函数来使能CAN控制器的时钟。 3. 初始化CAN控制器:使用CAN_DeInit函数来将CAN控制器的寄存器恢复到默认值。然后使用CAN_Init函数来初始化CAN控制器的参数,包括波特率、工作模式等。 4. 配置CAN过滤器:使用CAN_FilterInit函数来配置CAN过滤器,以过滤接收到的CAN帧。可以设置过滤器的ID、屏蔽位和过滤模式等。 5. 启动CAN控制器:使用CAN_Cmd函数来启动CAN控制器。 下面是一个示例代码,用于初始化STM32F103VETX的CAN拓展帧: ```c #include "stm32f10x.h" void CAN_ExtFrame_Init(void) { GPIO_InitTypeDef GPIO_InitStructure; CAN_InitTypeDef CAN_InitStructure; CAN_FilterInitTypeDef CAN_FilterInitStructure; // 配置CAN引脚 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9 | GPIO_Pin_10; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(GPIOB, &GPIO_InitStructure); // 使能CAN时钟 RCC_APB1PeriphClockCmd(RCC_APB1Periph_CAN1, ENABLE); // 初始化CAN控制器 CAN_DeInit(CAN1); CAN_StructInit(&CAN_InitStructure); CAN_InitStructure.CAN_TTCM = DISABLE; CAN_InitStructure.CAN_ABOM = DISABLE; CAN_InitStructure.CAN_AWUM = DISABLE; CAN_InitStructure.CAN_NART = DISABLE; CAN_InitStructure.CAN_RFLM = DISABLE; CAN_InitStructure.CAN_TXFP = DISABLE; CAN_InitStructure.CAN_Mode = CAN_Mode_Normal; CAN_InitStructure.CAN_SJW = CAN_SJW_1tq; CAN_InitStructure.CAN_BS1 = CAN_BS1_6tq; CAN_InitStructure.CAN_BS2 = CAN_BS2_8tq; CAN_InitStructure.CAN_Prescaler = 4; CAN_Init(CAN1, &CAN_InitStructure); // 配置CAN过滤器 CAN_FilterInitStructure.CAN_FilterNumber = 0; CAN_FilterInitStructure.CAN_FilterMode = CAN_FilterMode_IdMask; CAN_FilterInitStructure.CAN_FilterScale = CAN_FilterScale_32bit; CAN_FilterInitStructure.CAN_FilterIdHigh = 0x0000; CAN_FilterInitStructure.CAN_FilterIdLow = 0x0000; CAN_FilterInitStructure.CAN_FilterMaskIdHigh = 0x0000; CAN_FilterInitStructure.CAN_FilterMaskIdLow = 0x0000; CAN_FilterInitStructure.CAN_FilterFIFOAssignment = 0; CAN_FilterInitStructure.CAN_FilterActivation = ENABLE; CAN_FilterInit(&CAN_FilterInitStructure); // 启动CAN控制器 CAN_Cmd(CAN1, ENABLE); } ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值