参考网站:https://www.cnblogs.com/craigtao/p/3645148.html
https://blog.csdn.net/qq_29413829/article/details/53230716
https://blog.csdn.net/qq_36355662/article/details/80607453
void CAN1_Init(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
NVIC_InitTypeDef NVIC_InitStructure;
CAN_InitTypeDef CAN_InitStructure;
CAN_FilterInitTypeDef CAN_FilterInitStructure;
/* 复用功能和GPIOD端口时钟使能*/
RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO | RCC_APB2Periph_GPIOD, ENABLE);
/* CAN1 模块时钟使能*/
RCC_APB1PeriphClockCmd(RCC_APB1Periph_CAN1, ENABLE);
/CAN 重映射–/
GPIO_PinRemapConfig(GPIO_Remap2_CAN1, ENABLE);
/**************************************************************************************************
CAN 重映射根据需要修改
CASE 1: CAN_RX mapped to PB8, CAN_TX mapped to PB9 (not available on 36-pin package)
#define GPIO_Remap1_CAN1 ((uint32_t)0x001D4000) /*!< CAN1 Alternate Function mapping /
CASE 2: CAN_RX mapped to PD0, CAN_TX mapped to PD1
#define GPIO_Remap2_CAN1 ((uint32_t)0x001D6000) /!< CAN1 Alternate Function mapping */
***********************************************************************************************************/
/ Configure CAN pin: RX / // PD0
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
GPIO_Init(GPIOD, &GPIO_InitStructure);
/ Configure CAN pin: TX */ // PD1
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;
GPIO_Init(GPIOD, &GPIO_InitStructure);
/* enabling interrupt */
NVIC_InitStructure.NVIC_IRQChannel = CAN1_RX0_IRQn;
;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 3;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 2;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
CAN_DeInit(CAN1);
//can 反初始化
CAN_StructInit(&CAN_InitStructure);
/* CAN cell init */
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;
//接收FIFO锁定模式
CAN_InitStructure.CAN_TXFP=DISABLE;
//发送FIFO优先级
CAN_InitStructure.CAN_Mode=CAN_Mode_Normal;
//CAN设置为正常模式
CAN_InitStructure.CAN_SJW=CAN_SJW_1tq;
//重新同步跳跃宽度1个时间单位
CAN_InitStructure.CAN_BS1=CAN_BS1_3tq;
//时间段1为3个时间单位
CAN_InitStructure.CAN_BS2=CAN_BS2_2tq;
//时间段2为2个时间单位
CAN_InitStructure.CAN_Prescaler=60;
//时间长度为60
CAN_Init(CAN1,&CAN_InitStructure);
//波特率72/2/(60(1+3+2))=0.1 即波特率为100kbps
//APB1操作速度限于36MHz, APB2操作于全速(最高72MHz)//过滤器不过滤任何邮箱ID
CAN_FilterInitStructure.CAN_FilterNumber=0;
CAN_FilterInitStructure.CAN_FilterMode=CAN_FilterMode_IdMask;
//掩码模式
CAN_FilterInitStructure.CAN_FilterScale=CAN_FilterScale_32bit;
CAN_FilterInitStructure.CAN_FilterIdHigh=0X0000;
//要过滤的ID高位
CAN_FilterInitStructure.CAN_FilterIdLow= CAN_ID_EXT|CAN_RTR_DATA;
//要过滤的ID低位
CAN_FilterInitStructure.CAN_FilterMaskIdHigh=0x0000;
//过滤器屏蔽标识符高16位值
CAN_FilterInitStructure.CAN_FilterMaskIdLow=0x0000;
//过滤器屏蔽标识符低16位值
CAN_FilterInitStructure.CAN_FilterFIFOAssignment=CAN_FIFO0;
//设定指向过滤器的FIFO为0
CAN_FilterInitStructure.CAN_FilterActivation=ENABLE;
//使能过滤器
CAN_FilterInit(&CAN_FilterInitStructure);
//初始化过滤器/* CAN FIFO0 message pending interrupt enable */
CAN_ITConfig(CAN1,CAN_IT_FMP0, ENABLE);
//使能FIFO消息挂号中断
CAN_ITConfig(CAN1,CAN_IT_TME,ENABLE);
//发送中断使能
【STM32F107 CAN调试笔记 标准库】}
uint8_t CAN_SendMsg(CAN_TypeDef* CANx, uint8_t IDdata ,uint8_t* data,uint8_t size)
{
u8 mbox;
u16 i=0;
CanTxMsg TxMessage;
TxMessage.StdId= IDdata;
TxMessage.ExtId=0x00;
TxMessage.IDE =CAN_ID_STD;
TxMessage.RTR=CAN_RTR_DATA;
TxMessage.DLC=size;
memcpy(TxMessage.Data,data,size);
mbox= CAN_Transmit(CANx, &TxMessage);
while((CAN_TransmitStatus(CAN1, mbox)==CAN_TxStatus_Failed)&&(i<0XFFF))i++;
if(i>=0XFFF)return 1;
return 0;
}
//CAN1中断
void CAN1_RX0_IRQHandler(void)
{
CanRxMsg RxMessage;
CAN_Receive(CAN1,CAN_FIFO0, &RxMessage);
CAN_ClearITPendingBit(CAN1,CAN_IT_FMP0);
}