您的位置 首页 动态

STM32_MDK_bxCAN

今天整理下CAN方面的资料,首先使用的是stm32f103vet6,只有一个CAN(2.0A2.0B)。CAN本身是工作的数据链路层的总线,有很多优势就不…

今日收拾下CAN方面的材料,首要运用的是stm32f103vet6,只需一个CAN(2.0A & 2.0B)。CAN自身是作业的数据链路层的总线,有许多优势就不再一一介绍了,随意买本书看看都有。

根底的CAN的常识就不赘述了,这些是必要的能够自己去买书了解,现在来看下STM32下对CAN的驱动,STM32自身包含了CAN的数据链路层,然后物理层便是CAN收发器用的是TJA1050,对错容错CAN。终端电阻用120欧姆。

说道CAN最首要的是CAN的初始化,他包含两个首要的部分,一个是根本特点的声明,另一部分便是过滤器的设置。见如下代码:


/*******************************************************************************
* Function Name : bxCAN_Port_Configuration
* Description : CAN端口设置
* Input : None
* Output : None
* Return : None
*******************************************************************************/
void bxCAN_Port_Configuration(void)
{
GPIO_InitTypeDef GPIO_InitStructure_bxCAN;

GPIO_PinRemapConfig(GPIO_Remap1_CAN1 , ENABLE); //端口复用为CAN1

GPIO_InitStructure_bxCAN.GPIO_Pin = GPIO_Pin_8; //PB8:CAN-RX
GPIO_InitStructure_bxCAN.GPIO_Mode = GPIO_Mode_IPU; //输入上拉
GPIO_InitStructure_bxCAN.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOB, &GPIO_InitStructure_bxCAN);

GPIO_InitStructure_bxCAN.GPIO_Pin = GPIO_Pin_9; //PB9:CAN-TX
GPIO_InitStructure_bxCAN.GPIO_Mode = GPIO_Mode_AF_PP; //复用形式
GPIO_InitStructure_bxCAN.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOB, &GPIO_InitStructure_bxCAN);
}

/*******************************************************************************
* Function Name : bxCAN_Property_Configuration
* Description : CAN装备详细特点
* Input : None
* Output : None
* Return : None
*******************************************************************************/
void bxCAN_Property_Configuration(void)
{
CAN_InitTypeDef CAN_InitStructure;
CAN_FilterInitTypeDef CAN_FilterInitStructure;

/* CAN register init */
CAN_DeInit(CAN1);
CAN_StructInit(&CAN_InitStructure);

/* CAN cell init */
CAN_InitStructure.CAN_TTCM=DISABLE; //MCR-TTCM 制止时刻触发通讯形式
CAN_InitStructure.CAN_ABOM=DISABLE;//MCR-ABOM 制止主动离线办理
CAN_InitStructure.CAN_AWUM=DISABLE;//MCR-AWUM 经过铲除CAN_MCR_SLEEP位进入主动唤醒形式
CAN_InitStructure.CAN_NART=DISABLE;//MCR-NART 制止报文主动重传 0-主动重传 1-报文只传一次
CAN_InitStructure.CAN_RFLM=DISABLE;//MCR-RFLM 接纳FIFO 确定形式 0-溢出时新报文会掩盖原有报文 1-溢出时,新报文丢掉
CAN_InitStructure.CAN_TXFP=DISABLE;//MCR-TXFP 发送FIFO优先级 0-优先级取决于报文标明符 1-优先级取决于发送恳求的次序
CAN_InitStructure.CAN_Mode=CAN_Mode_LoopBack;//BTR-SILM/LBKM CAN环回形式
// CAN_InitStructure.CAN_Mode=CAN_Mode_Normal;// CAN正常形式
CAN_InitStructure.CAN_SJW=CAN_SJW_1tq; //BTR-SJW 从头同步跳动宽度 1个时刻单元
CAN_InitStructure.CAN_BS1=CAN_BS1_2tq;//BTR-TS1 时刻段1 占用了2个时刻单元
CAN_InitStructure.CAN_BS2=CAN_BS2_3tq;//BTR-TS1 时刻段2 占用了3个时刻单元

#if CAN_BAUDRATE == 1000 /* 1MBps *///BTR-BRP 波特率分频器 界说了时刻单元的时刻长度 36/(1+2+3)/6=1Mbps
CAN_InitStructure.CAN_Prescaler = 6;
#elif CAN_BAUDRATE == 500 /* 500KBps */
CAN_InitStructure.CAN_Prescaler = 12;
#elif CAN_BAUDRATE == 250 /* 250KBps */
CAN_InitStructure.CAN_Prescaler = 24;
#elif CAN_BAUDRATE == 125 /* 125KBps */
CAN_InitStructure.CAN_Prescaler = 48;
#elif CAN_BAUDRATE == 100 /* 100KBps */
CAN_InitStructure.CAN_Prescaler = 60;
#elif CAN_BAUDRATE == 50 /* 50KBps */
CAN_InitStructure.CAN_Prescaler = 120;
#elif CAN_BAUDRATE == 20 /* 20KBps */
CAN_InitStructure.CAN_Prescaler = 300;
#elif CAN_BAUDRATE == 10 /* 10KBps */
CAN_InitStructure.CAN_Prescaler = 600;
#endif
CAN_Init(CAN1, &CAN_InitStructure);//初始化CAN寄存器

/* CAN filter init */
CAN_FilterInitStructure.CAN_FilterNumber=1; // 挑选过滤器编号
CAN_FilterInitStructure.CAN_FilterMode=CAN_FilterMode_IdMask;// 挑选过滤器类型为屏蔽位形式
CAN_FilterInitStructure.CAN_FilterScale=CAN_FilterScale_32bit; // 挑选过滤器位宽为一个32位过滤器
CAN_FilterInitStructure.CAN_FilterIdHigh=0x0000;// 标识符匹配
CAN_FilterInitStructure.CAN_FilterIdLow=0x0000;
CAN_FilterInitStructure.CAN_FilterMaskIdHigh=0x0000;// 标识符屏蔽位,1:有必要匹配,0:不必关怀
CAN_FilterInitStructure.CAN_FilterMaskIdLow=0x0000;
CAN_FilterInitStructure.CAN_FilterFIFOAssignment=CAN_FIFO0; // 挑选存放在相关的FIFO为FIFO0
CAN_FilterInitStructure.CAN_FilterActivation=ENABLE;// 激活过滤器
CAN_FilterInit(&CAN_FilterInitStructure);// 初始化过滤器

/* CAN FIFO0 message pending interrupt enable */
CAN_ITConfig(CAN1, CAN_IT_FMP0, ENABLE);// 设置CAN1,FIFO0接纳中止使能
// CAN_ITConfig(CAN1, CAN_IT_FMP0, DISABLE);
}

/*******************************************************************************
* Function Name : bxCAN_Configuration
* Description : CAN初始化
* Input : None
* Output : None
* Return : None
*******************************************************************************/
void bxCAN_Configuration(void)
{
bxCAN_Port_Configuration();
bxCAN_Property_Configuration();
}

/*******************************************************************************
* Function Name : Interrupt_Handle_bxCAN
* Description : 中止服务函数
* Input : None
* Output : None
* Return : None
*******************************************************************************/
void Interrupt_Handle_bxCAN(void)
{
CanRxMsg RxMessage;

RxMessage.StdId=0x00;
RxMessage.ExtId=0x00;
RxMessage.IDE=0;
RxMessage.DLC=0;
RxMessage.FMI=0;
RxMessage.Data[0]=0x00;
RxMessage.Data[1]=0x00;

CAN_Receive(CAN1, CAN_FIFO0, &RxMessage);
}

初始化榜首部分根本特点设置,要看下datasheet中,CAN的发送流程和承受流程,然后看下他相关的状况寄存器就知道其含义了。在过滤器设置部分,要了解他两种形式的不同之处,屏蔽位形式便是给出 一个参考值然后用屏蔽特点去匹配,列表形式便是直接依据寄存器的参考值进行全匹配。这儿对屏蔽位我也没有做特别的设置,就设置悉数承受。
本进程只完成了发送规范帧,扩展帧,承受帧数据。
接纳程序运用中止方法,见上面代码函数Interrupt_Handle_bxCAN(),发送代码如下:


void Send_Std_KLS_KL15(unsigned char value)
{
CanTxMsg TxMessage;

TxMessage.StdId=0x570;
TxMessage.IDE=CAN_ID_STD;
TxMessage.RTR=CAN_RTR_DATA;
TxMessage.DLC=8;
TxMessage.Data[0]=value;
TxMessage.Data[1]=0x00;
TxMessage.Data[2]=0x00;
TxMessage.Data[3]=0x00;
TxMessage.Data[4]=0x00;
TxMessage.Data[5]=0x00;
TxMessage.Data[6]=0x00;
TxMessage.Data[7]=0x00;

CAN_Transmit(CAN1, &TxMessage);
}

这个是发送一个规范帧,假如发送扩展帧 如下:


void Send_Exd_message(void)
{
CanTxMsg TxMessage;

TxMessage.StdId=0x0000;
TxMessage.ExtId=0x1234;
TxMessage.IDE=CAN_ID_EXT;
TxMessage.RTR=CAN_RTR_DATA;
TxMessage.DLC=2;
TxMessage.Data[0]=0xDE;
TxMessage.Data[1]=0xCA;
CAN_Transmit(CAN1, &TxMessage);
}

因为CAN通明化了数据链路层,所以在实践运用中只需用好屏蔽位就能够高效的运用CAN网络。

声明:本文内容来自网络转载或用户投稿,文章版权归原作者和原出处所有。文中观点,不代表本站立场。若有侵权请联系本站删除(kf@86ic.com)https://www.86ic.net/news/dongtai/252248.html

为您推荐

联系我们

联系我们

在线咨询: QQ交谈

邮箱: kf@86ic.com

关注微信
微信扫一扫关注我们

微信扫一扫关注我们

返回顶部