#ifndef __CAN_H_
#define __CAN_H_
#ifdef _BSP_CAN_
#define CAN_EXT
#else
#define CAN_EXT extern
#endif
/****************************** CAN 引脚配置参数定义***************************************/
#define macCAN1_TX_GPIO_CLK RCC_APB2Periph_GPIOA
#define macCAN1_TX_GPIO_PORT GPIOA
#define macCAN1_TX_GPIO_PIN GPIO_Pin_12
#define macCAN1_RX_GPIO_CLK RCC_APB2Periph_GPIOA
#define macCAN1_RX_GPIO_PORT GPIOA
#define macCAN1_RX_GPIO_PIN GPIO_Pin_11
#define macCAN1_Rcc_Clock RCC_APB1Periph_CAN1
#define STANDARD_FRAME_TYPE 1
#define EXTENDED_FRAME_TYPE 2
CAN_EXT u8 Can1_Rx_Buf[8];
void Bsp_Can_Config(void);
u8 Can_Send_Msg(u32 Id,u8 Data_type,u8* msg,u8 len);
u8 Can_Receive_Msg(u8 *buf);
#endif
#define _BSP_CAN_
#include "head_all.h"
void Bsp_Can_Config(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
CAN_InitTypeDef CAN_InitStructure;
CAN_FilterInitTypeDef CAN_FilterInitStructure;
NVIC_InitTypeDef NVIC_InitStructure;
/* 配置 CANTX 引脚 */
RCC_APB2PeriphClockCmd ( macCAN1_TX_GPIO_CLK, ENABLE );
GPIO_InitStructure.GPIO_Pin = macCAN1_TX_GPIO_PIN;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_Init ( macCAN1_TX_GPIO_PORT, & GPIO_InitStructure );
/* 配置 CANRX 引脚 */
RCC_APB2PeriphClockCmd ( macCAN1_RX_GPIO_CLK, ENABLE );
GPIO_InitStructure.GPIO_Pin = macCAN1_RX_GPIO_PORT;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
GPIO_Init (macCAN1_TX_GPIO_PORT, & GPIO_InitStructure );
RCC_APB1PeriphClockCmd(macCAN1_Rcc_Clock, ENABLE);
//CAN单元配置
CAN_InitStructure.CAN_TTCM=DISABLE; //非时间触发通讯模式
CAN_InitStructure.CAN_ABOM=DISABLE; //软件自动离线管理
CAN_InitStructure.CAN_AWUM=DISABLE; //睡眠模式通过软件唤醒
CAN_InitStructure.CAN_NART=ENABLE; //禁止报文自动传输
CAN_InitStructure.CAN_RFLM=DISABLE; //报文不锁定
CAN_InitStructure.CAN_TXFP=DISABLE; //优先级由报文标识符决定
CAN_InitStructure.CAN_Mode= 0; //模式设置:0正常模式,1回环模式
//波特率设置
CAN_InitStructure.CAN_SJW=CAN_SJW_1tq; //重新同步跳跃宽度多少个时间单位
CAN_InitStructure.CAN_BS1=CAN_BS2_8tq; //Tbs1=tbs1+1个时间单位CAN_BS1_1tp~CAN_BS1_16tp
CAN_InitStructure.CAN_BS2=CAN_BS1_9tq; //Tbs1=tbs2+1个时间单位CAN_BS1_1tp~CAN_BS1_8tp
CAN_InitStructure.CAN_Prescaler=4; //分频系数
CAN_Init(CAN1, &CAN_InitStructure); //初始化CAN1
//过滤器配置
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=0x0000; //32位ID
CAN_FilterInitStructure.CAN_FilterIdLow=0x0000;
CAN_FilterInitStructure.CAN_FilterMaskIdHigh=0x0000; //32位MASK
CAN_FilterInitStructure.CAN_FilterMaskIdLow=0x0000;
CAN_FilterInitStructure.CAN_FilterFIFOAssignment=CAN_Filter_FIFO0; //过滤器关联到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 = 1; // 主优先级 1
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; // 此优先级 0
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
}
u8 Can_Send_Msg(u32 Id,u8 Data_type,u8* msg,u8 len)
{
u8 mbox;
u16 i=0;
CanTxMsg TxMessage;
if(Data_type == STANDARD_FRAME_TYPE)
{
TxMessage.StdId=Id; // 标准帧标识符
TxMessage.IDE=CAN_Id_Standard; // 标准帧
}
else if(Data_type == EXTENDED_FRAME_TYPE)
{
TxMessage.ExtId=Id; // 扩展帧标识符
TxMessage.IDE=CAN_Id_Extended; // 扩展帧
}
TxMessage.RTR=CAN_RTR_Data; // 数据帧
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;
}
u8 Can_Receive_Msg(u8 *buf)
{
u32 i;
CanRxMsg RxMessage;
if( CAN_MessagePending(CAN1,CAN_FIFO0)==0)return 0; //没有收到数据直接跳出
CAN_Receive(CAN1, CAN_FIFO0, &RxMessage);//读取数据
for(i=0;i<8;i++)
buf[i]=RxMessage.Data[i];
return RxMessage.DLC;
}
这篇博客介绍了如何使用C语言进行CAN模块的配置,包括CAN引脚的配置、CAN单元和过滤器的初始化,以及发送和接收消息的函数实现。通过对GPIO、CAN_InitStructure和CAN_FilterInitStructure结构体的设置,实现了CAN接口的硬件连接和通信功能。
1030

被折叠的 条评论
为什么被折叠?



