can的初始化我是把之前用的103zet6的程序拿过来的。
就是用的引脚不同,引脚的初始化不同,rbt6使用的是PA11,PA12,是默认功能,不需要复用。PB8,PB9是复用(CANRX,CANTX在Remap栏)
所以初始化的时候用了
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB | RCC_APB2Periph_AFIO,ENABLE);
/GPIO_PinRemapConfig(GPIO_Remap1_CAN1,ENABLE);
//CAN初始化
//tsjw:重新同步跳跃时间单元.范围:CAN_SJW_1tq~ CAN_SJW_4tq
//tbs2:时间段2的时间单元. 范围:CAN_BS2_1tq~CAN_BS2_8tq;
//tbs1:时间段1的时间单元. 范围:CAN_BS1_1tq ~CAN_BS1_16tq
//brp :波特率分频器.范围:1~1024; tq=(brp)*tpclk1
//波特率=Fpclk1/((tbs1+1+tbs2+1+1)*brp);
//mode:CAN_Mode_Normal,普通模式;CAN_Mode_LoopBack,回环模式;
//Fpclk1的时钟在初始化的时候设置为36M,如果设置CAN_Mode_Init(CAN_SJW_1tq,CAN_BS2_8tq,CAN_BS1_9tq,4,CAN_Mode_LoopBack);
//则波特率为:36M/((8+9+1)*4)=500Kbps
//返回值:0,初始化OK;
//其他,初始化失败;
/*
CAN_RX--PA11
CAN_TX--PA12
与主控器不同之处:主控器板子用的PB8,PB9,是复用引脚,PA11 PA12的默认功能里有can,不用复用
*/
u8 CAN_Mode_Init(u8 tsjw,u8 tbs2,u8 tbs1,u16 brp,u8 mode)
{
GPIO_InitTypeDef GPIO_InitStructure;
CAN_InitTypeDef CAN_InitStructure;
CAN_FilterInitTypeDef CAN_FilterInitStructure;
#if CAN_RX0_INT_ENABLE
NVIC_InitTypeDef NVIC_InitStructure;
#endif
/* CAN Periph clock enable */
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA ,ENABLE); //| RCC_APB2Periph_AFIO
RCC_APB1PeriphClockCmd(RCC_APB1Periph_CAN1, ENABLE);
// GPIO_PinRemapConfig(GPIO_Remap1_CAN1,ENABLE);
/* Configure CAN pin: RX */
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
GPIO_Init(GPIOA, &GPIO_InitStructure);
/* Configure CAN pin: TX */
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_Init(GPIOA, &GPIO_InitStructure);
//CAN单元设置
CAN_InitStructure.CAN_TTCM=DISABLE; //非时间触发通信模式
CAN_InitStructure.CAN_ABOM=ENABLE; //软件自动离线管理 ENABLE:离线自动恢复
CAN_InitStructure.CAN_AWUM=DISABLE; //睡眠模式通过软件唤醒(清除CAN->MCR的SLEEP位)
CAN_InitStructure.CAN_NART=DISABLE; //允许报文自动传送 ENABLE:禁止
CAN_InitStructure.CAN_RFLM=DISABLE; //报文不锁定,新的覆盖旧的
CAN_InitStructure.CAN_TXFP=ENABLE; //优先级由报文标识符决定 ENABLE:优先级由发送的请求顺序来决定
CAN_InitStructure.CAN_Mode= mode; //模式设置: mode:0,普通模式;1,回环模式;
//设置波特率
CAN_InitStructure.CAN_SJW=tsjw; //重新同步跳跃宽度(Tsjw)为tsjw+1个时间单位 CAN_SJW_1tq CAN_SJW_2tq CAN_SJW_3tq CAN_SJW_4tq
CAN_InitStructure.CAN_BS1=tbs1; //Tbs1=tbs1+1个时间单位CAN_BS1_1tq ~CAN_BS1_16tq
CAN_InitStructure.CAN_BS2=tbs2; //Tbs2=tbs2+1个时间单位CAN_BS2_1tq ~ CAN_BS2_8tq
CAN_InitStructure.CAN_Prescaler=brp; //分频系数(Fdiv)为brp+1
CAN_Init(CAN1, &CAN_InitStructure); //初始化CAN1 CAN时钟是36M
// 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=0x01 <<5; //32位ID
// CAN_FilterInitStructure.CAN_FilterIdLow=0x0000;
// CAN_FilterInitStructure.CAN_FilterMaskIdHigh=0x1f <<5; //32位MASK
// CAN_FilterInitStructure.CAN_FilterMaskIdLow=0x0000;
// CAN_FilterInitStructure.CAN_FilterFIFOAssignment=CAN_Filter_FIFO0; //过滤器0关联到FIFO0
// CAN_FilterInitStructure.CAN_FilterActivation=ENABLE; //激活过滤器0
CAN_FilterInitStructure.CAN_FilterMode = CAN_FilterMode_IdMask; //设定过滤器组为列表模式
CAN_FilterInitStructure.CAN_FilterScale = CAN_FilterScale_32bit; //过滤器位宽为16位过滤器一个
CAN_FilterInitStructure.CAN_FilterIdHigh = 0; //设定过滤器标识符高位(32为高位段,16位为第一个)
CAN_FilterInitStructure.CAN_FilterIdLow = 0x01 << 3 | CAN_ID_EXT; // 扩展帧
CAN_FilterInitStructure.CAN_FilterMaskIdHigh= 0; //只管低5位,其他都是0
CAN_FilterInitStructure.CAN_FilterMaskIdLow= 0x1f << 3; //
CAN_FilterInitStructure.CAN_FilterFIFOAssignment = CAN_Filter_FIFO0;//过滤器FIFO0指向过滤器0
CAN_FilterInitStructure.CAN_FilterNumber = 1; //指定待初始化的过滤器,范围1~13
CAN_FilterInitStructure.CAN_FilterActivation = ENABLE; //使能过滤器
CAN_FilterInit(&CAN_FilterInitStructure); //滤波器初始化
#if CAN_RX0_INT_ENABLE
CAN_ITConfig(CAN1,CAN_IT_FMP0,ENABLE); //FIFO0消息挂号中断允许.
NVIC_InitStructure.NVIC_IRQChannel = USB_LP_CAN1_RX0_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1; // 主优先级为2
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; // 次优先级为0
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
#endif
return 0;
}