u8 CAN1_Mode_Init(u8 tsjw, u8 tbs2,u8 tbs1, u16 brp, u8 mode)
{
? ? /* gpio结构体 */
? ? GPIO_InitTypeDef GPIO_InitStructure;
? ? /* can 初始化结构体 */
? ? CAN_InitTypeDef ? ? ? ?CAN_InitStructure;
? ? /* can过滤器结构体 */
? ? CAN_FilterInitTypeDef ?CAN_FilterInitStructure;
? ? /* 使能时钟 */
? ? RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE); ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?
? ? RCC_APB1PeriphClockCmd(RCC_APB1Periph_CAN1, ENABLE);
?
? ? /* 初始化gpio
? ? ? ? 设置引脚
? ? ? ? 复用模式
? ? ? ? 推挽
? ? ? ? 速率100
? ? ? ? 上拉
? ? */
? ? GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11| GPIO_Pin_12;
? ? GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
? ? GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
? ? GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;
? ? GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
? ? GPIO_Init(GPIOA, &GPIO_InitStructure);
? ? /* 复用pa11 pa12为can功能 */
? ? GPIO_PinAFConfig(GPIOA, GPIO_PinSource11, GPIO_AF_CAN1);
? ? GPIO_PinAFConfig(GPIOA, GPIO_PinSource12, GPIO_AF_CAN1);
? ? /* 初始化can结构体 */
? ? /*事件触发消息传输机制
? ? 在TTCAN模式下,CAN硬件的内部定时器被激活,并且被用于产生发送与接收邮箱的)时间戳
? ? 为了使can满足,适合实时性和可靠性要求特别高或有安全性要求的场合
? ? 路上各节点取得同步后, 消息只能根据调度表在规定的时间隙传输, 避免了消息传输的冲突、仲裁,消息传输时延短, 且可预知
? ? */
? ? CAN_InitStructure.CAN_TTCM=DISABLE;
? ? /* 软件自动离线管理
? ? ENABLE:一旦硬件检测到128 次11位连续的隐性位,则自动退出离线状态
? ? 将ABOM设1后,一旦检测到条件会自动恢复的,不需要人工干预
? ? 如果ABOM位为’1’,bxCAN进入离线状态后,就自动开启恢复过程。
? ? 如果ABOM位为’0’,软件必须先请求bxCAN进入然后再退出初始化模式,随后恢复过程才被开启
? ? */
? ? CAN_InitStructure.CAN_ABOM=DISABLE;
? ? /* 睡眠模式禁用
? ? 软件通过对CAN_MCR寄存器的SLEEP位置’1’,来请求进入这一模式。在该模式下,bxCAN的时钟停止了,但软件仍然可以访问邮箱寄存器。
? ? 当bxCAN处于睡眠模式,软件必须对CAN_MCR寄存器的INRQ位置’1’并且同时对SLEEP位清’0’,才能进入初始化模式。
? ? 有2种方式可以唤醒(退出睡眠模式)bxCAN:通过软件对SLEEP位清’1’,或硬件检测到CAN总线的活动。
? ? 如果CAN_MCR寄存器的AWUM位为’1’,一旦检测到CAN总线的活动,硬件就自动对SLEEP位清’0’来唤醒bxCAN。如果CAN_MCR寄存器的AWUM位为’0’,软件必须在唤醒中断里对SLEEP位清’0’才能退出睡眠状态。
? ? 注: 如果唤醒中断被允许(CAN_IER寄存器的WKUIE位为’1’),那么一旦检测到CAN总线活动就会产生唤醒中断,而不管硬件是否会自动唤醒bxCAN。
? ? 在对SLEEP位清’0’后,睡眠模式的退出必须与CAN总线同步,当硬件对SLAK位清’0’时,就确认了睡眠模式的退出。
? ? */
? ? CAN_InitStructure.CAN_AWUM=DISABLE;
? ? /* 自动重传使能
? ? 该模式主要用于满足CAN标准中,时间触发通信选项的需求。通过对CAN_MCR寄存器的NART位置’1’,来让硬件工作在该模式。
? ? 在该模式下,发送操作只会执行一次。如果发送操作失败了,不管是由于仲裁丢失或出错,硬件都不会再自动发送该报文。
? ? */
? ? CAN_InitStructure.CAN_NART=ENABLE;
? ? /*
? ? 报文不锁定,新报文覆盖旧报文
? ? */
? ? CAN_InitStructure.CAN_RFLM=DISABLE;
? ? /* 优先级由报文标识符决定
? ? 本成员用于选择CAN报文发送优先级判定方法
? ? 用于选择CAN报文发送优先级判定方法
? ? */
? ? CAN_InitStructure.CAN_TXFP=DISABLE;
? ? /*
? ? ? ? #define CAN_Mode_Normal ? 正常模式
? ? ? ? #define CAN_Mode_LoopBack 回环模式 自己发,自己收
? ? ? ? 回环模式下,它自己的输出端的所有内容都直接传输到自己的输入端,输出端的内容同时也会被传输到总线上,
? ? ? ? 即也可使用总线监测它的发送内容。输入端只接收自己发送端的内容,不接收来自总线上的内容。使用回环模式可以进行自检。
? ? ? ? #define CAN_Mode_Silent ? 静默模式
? ? ? ? 静默模式下,它自己的输出端的逻辑 0 数据会直接传输到它自己的输入端,逻辑1
? ? ? ? 可以被发送到总线,所以它不能向总线发送显性位(逻辑 0),只能发送隐性位(逻辑 1)。
? ? ? ? 输入端可以从总线接收内容。由于它只可发送的隐性位不会强制影响总线的状态,
? ? ? ? 所以把它称为静默模式。这种模式一般用于监测,它可以用于分析总线上的流量,但又不会因为发送显性位而影响总线
? ? ? ? #define CAN_Mode_Silent_LoopBack ? ?静默回环模式
? ? ? ? 回环静默模式是以上两种模式的结合,自己的输出端的所有内容都直接传输到自己的输入端,并且不会向总线发送显性位影响总线,
? ? ? ? 不能通过总线监测它的发送内容。输入端只接收自己发送端的内容,不接收来自总线上的内容。
? ? ? ? 这种方式可以在“热自检”时使用,即自我检查的时候,不会干扰总线
? ? */
? ? CAN_InitStructure.CAN_Mode= mode;
? ? /*
? ? ? ? 重新同步跳跃宽度(SJW) 。定义了在每位中可以延长或缩短多少个时间单元的上限。其值可以编程为1到4个时间单元
? ? */
? ? CAN_InitStructure.CAN_SJW=tsjw;
? ? /*
? ? ? ? 时间段1(BS1):定义采样点的位置。其值可以编程为1到16个时间单元,但也可以被自动延长,
? ? ? ? 以补偿因为网络中不同节点的频率差异所造成的相位的正向漂移。
? ? */
? ? CAN_InitStructure.CAN_BS1=tbs1;
? ? /*
? ? ? ? 时间段2(BS2):定义发送点的位置。其值可以编程为1到8个时间单元,但也可以被自动缩短以补偿相位的负向漂移。
? ? */
? ? CAN_InitStructure.CAN_BS2=tbs2;
? ? /*
? ? ? ? 分频率
? ? */
? ? CAN_InitStructure.CAN_Prescaler=brp;
? ? /* 初始化结构体 */
? ? CAN_Init(CAN1, &CAN_InitStructure);
? ?
? ? /* 初始化过滤器 */
? ? /*
? ? ? 选择过滤器0~13 for one can register
? ? */
? ? CAN_FilterInitStructure.CAN_FilterNumber = 0;
? ? /*
? ? ? ? 屏蔽位模式和标识符列表模式
? ? ? ? #define CAN_FilterMode_IdMask ? ? ? ((uint8_t)0x00) ?
? ? ? ? #define CAN_FilterMode_IdList ? ? ? ((uint8_t)0x01)
? ? */
? ? CAN_FilterInitStructure.CAN_FilterMode=CAN_FilterMode_IdMask;
? ? /* ?过滤器的位数
? ? ? ? #define CAN_FilterScale_16bit ? ? ? ((uint8_t)0x00)
? ? ? ? #define CAN_FilterScale_32bit ? ? ? ((uint8_t)0x01)
? ? */
? ? CAN_FilterInitStructure.CAN_FilterScale=CAN_FilterScale_32bit;
? ? /*
? ? ? ? 32位ID 高位
? ? */
? ? CAN_FilterInitStructure.CAN_FilterIdHigh=0x0000;32??ID
? ? /*
? ? ? ? 32位ID 低位
? ? */
? ? CAN_FilterInitStructure.CAN_FilterIdLow=0x0000;
? ? /* 屏蔽位高字节 */
? ? CAN_FilterInitStructure.CAN_FilterMaskIdHigh=0x0000;
? ? /* 屏蔽位低字节 */
? ? CAN_FilterInitStructure.CAN_FilterMaskIdLow=0x0000;
? ? /* 设定接收FIFO */
? ? CAN_FilterInitStructure.CAN_FilterFIFOAssignment = CAN_Filter_FIFO0;
? ? /* 激活过滤组 */
? ? CAN_FilterInitStructure.CAN_FilterActivation = ENABLE;
? ? /* 初始化过滤器 */
? ? CAN_FilterInit(&CAN_FilterInitStructure);
? ?
? ? /* 配置can中断*/
? ? NVIC_InitTypeDef ?NVIC_InitStructure;
? ? CAN_ITConfig(CAN1,CAN_IT_FMP0,ENABLE);
? ? NVIC_InitStructure.NVIC_IRQChannel = CAN1_RX0_IRQn;
? ? NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
? ? NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; ?
? ? NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
? ? NVIC_Init(&NVIC_InitStructure);
? ? return 0;
} ?