1# high0006
我前些日子也也做了CAN,挺顺利的,中间也遇到了LZ所说的问题,LOOPBACK正常但NORMAL不正常。这个是由于CAN总线在发送出错达到一定数量的时候(128?)会自动关闭这个节点来保护整个总线不被堵死。
如果只有一个节点的话,一下子就bus off了,当然是看不到波形的。我用的设置程序帖下面,LZ可以参考一下,已经调通了。
另外CAN_InitStructure.CAN_ABOM=DISABLE;
这句是我当时bus off的主因。
库里面附带的那个说明文件中说:
Enable or disable the automatic bus-off management. This parameter can be set either to ENABLE or DISABLE.
#include "can_init.h"
void can_init(uint32_t nLocalCanId)
{
can_rcc_init();
can_gpio_init();
can_can_init(nLocalCanId);
can_it_init();
}
void can_rcc_init(void)
{
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_AFIO, ENABLE);
RCC_APB1PeriphClockCmd(RCC_APB1Periph_CAN1, ENABLE);
}
void can_gpio_init(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
/* Configure CAN pin: RX */
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11;
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_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
//这句别忘了,结构体没有赋值完整是灾难性的
GPIO_Init(GPIOA, &GPIO_InitStructure);
}
void can_can_init(uint32_t nLocalCanId)
{
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;
CAN_InitStructure.CAN_ABOM=DISABLE;
CAN_InitStructure.CAN_AWUM=DISABLE;
CAN_InitStructure.CAN_NART=DISABLE;
CAN_InitStructure.CAN_RFLM=ENABLE;
CAN_InitStructure.CAN_TXFP=ENABLE;
CAN_InitStructure.CAN_Mode=CAN_Mode_Normal;
CAN_InitStructure.CAN_SJW=CAN_SJW_1tq;//重新同步跳跃宽度1个时间单位
CAN_InitStructure.CAN_BS1=CAN_BS1_8tq;//时间段1为8个时间单位
CAN_InitStructure.CAN_BS2=CAN_BS2_7tq;//时间段2为7个时间单位
CAN_InitStructure.CAN_Prescaler = 9; //(pclk1/((1+8+7)*9)) = 36Mhz/16/9 = 250Kbits设定了一个时间单位的长度9
CAN_Init(CAN1,&CAN_InitStructure);
/* CAN filter init 过滤器初始化*/
CAN_FilterInitStructure.CAN_FilterNumber=0;//指定了待初始化的过滤器0
CAN_FilterInitStructure.CAN_FilterMode=CAN_FilterMode_IdMask;//指定了过滤器将被初始化到的模式标识符屏蔽位模式
CAN_FilterInitStructure.CAN_FilterScale=CAN_FilterScale_32bit;//给出了过滤器位宽1个32位过滤器
CAN_FilterInitStructure.CAN_FilterIdHigh=(((uint32_t)nLocalCanId<<3)&0xFFFF0000)>>16;
CAN_FilterInitStructure.CAN_FilterIdLow=(((uint32_t)nLocalCanId<<3)|CAN_ID_EXT|CAN_RTR_DATA)&0xFFFF;
CAN_FilterInitStructure.CAN_FilterMaskIdHigh=0x0000;
CAN_FilterInitStructure.CAN_FilterMaskIdLow=0x00ff; //对最低的8位,即收件人名称进行过滤
CAN_FilterInitStructure.CAN_FilterFIFOAssignment=CAN_FIFO0;//设定了指向过滤器的FIFO0
CAN_FilterInitStructure.CAN_FilterActivation=ENABLE;//使能过滤器
CAN_FilterInit(&CAN_FilterInitStructure);
}
void can_it_init(void)
{
NVIC_InitTypeDef NVIC_InitStructure;
/*设定发送中断与接收中断*/
/* Enable CAN1 RX0 interrupt IRQ channel */
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);
NVIC_InitStructure.NVIC_IRQChannel=USB_LP_CAN1_RX0_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
/*Tx interrupt*/
NVIC_InitStructure.NVIC_IRQChannel=USB_HP_CAN1_TX_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 4;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
} |