本帖最后由 qq302011 于 2012-9-16 21:11 编辑
各位前辈:
我使用STM32控制CAN总线;
硬件环境:
我现在 通过CAN总线给32个模块 发送查询 数据帧,但是实际上我只有一个模块和一个CAN控制器连接到总线,模块的滤波地址为1,控制器是接收所有数据帧,控制器方有120欧姆终端电阻,模块没有终端电阻。
上电后CAN主机按地址 对1-31号模块发送扫描指令,这时候发现,模块1出现 位填充错误 接收错误计数为0XFF,请教如何避免该问题哈?如果不处理该错误,则不能检测到该模块。
我现在的处理方式是 在进入错误中断之后 把CAN外设初始化程序重新运行一遍,运行之后再次扫描则不会出现该问题了。我是用的STM32。请教如何避免该问题的发生?如何再出现问题之后,使用最简单最快速的语句初始化CAN外设?
以下是我的CAN总线程序,请相关高手不吝赐教。谢谢。
void CAN_SetBaudRate(uint8_t iBaud)
{
CAN_StructInit(&CAN_InitStructure);
CAN_InitStructure.CAN_TTCM = DISABLE;
CAN_InitStructure.CAN_ABOM = ENABLE; //ENABLE:一旦硬件检测到128 次11位连续的隐性位,则自动退出离线状态
CAN_InitStructure.CAN_AWUM = ENABLE;//ENABLE硬件自动唤醒
CAN_InitStructure.CAN_NART = DISABLE;//DISABLE:CAN报文一直重传直到成功
CAN_InitStructure.CAN_RFLM = ENABLE;//EANBLE:FIFO满之后再次接收到的报文将被丢弃
CAN_InitStructure.CAN_TXFP=ENABLE;//enable:优先级由发送请求的顺序决定
// CAN_InitStructure.CAN_TTCM = DISABLE;
// CAN_InitStructure.CAN_ABOM = DISABLE; //ENABLE:一旦硬件检测到128 次11位连续的隐性位,则自动退出离线状态
// CAN_InitStructure.CAN_AWUM = DISABLE;//ENABLE硬件自动唤醒
// CAN_InitStructure.CAN_NART = DISABLE;//DISABLE:CAN报文一直重传直到成功
// CAN_InitStructure.CAN_RFLM = DISABLE;//EANBLE:FIFO满之后再次接收到的报文将被丢弃
// CAN_InitStructure.CAN_TXFP=DISABLE;//enable:优先级由发送请求的顺序决定
CAN_InitStructure.CAN_Mode =CAN_Mode_Normal;//CAN_Mode_LoopBack;//
if(36000000==SystemCoreClock)
{
switch (iBaud)
{
case 0://5K
CAN_InitStructure.CAN_SJW = CAN_SJW_1tq;
CAN_InitStructure.CAN_BS1 = CAN_BS1_13tq;//CAN_BS1_3tq;
CAN_InitStructure.CAN_BS2 = CAN_BS2_2tq;//CAN_BS2_5tq;
CAN_InitStructure.CAN_Prescaler = 450;
break;
case 1://10K
CAN_InitStructure.CAN_SJW = CAN_SJW_1tq;
CAN_InitStructure.CAN_BS1 = CAN_BS1_13tq;//CAN_BS1_3tq;
CAN_InitStructure.CAN_BS2 = CAN_BS2_2tq;//CAN_BS2_5tq;
CAN_InitStructure.CAN_Prescaler = 225;
break;
case 2: //50K
CAN_InitStructure.CAN_SJW = CAN_SJW_1tq;
CAN_InitStructure.CAN_BS1 = CAN_BS1_6tq;//CAN_BS1_3tq;
CAN_InitStructure.CAN_BS2 = CAN_BS2_1tq;//CAN_BS2_5tq;
CAN_InitStructure.CAN_Prescaler = 45;
break;
case 3: //100K
CAN_InitStructure.CAN_SJW = CAN_SJW_1tq;
CAN_InitStructure.CAN_BS1 = CAN_BS1_14tq;//CAN_BS1_3tq;
CAN_InitStructure.CAN_BS2 = CAN_BS2_3tq;//CAN_BS2_5tq;
CAN_InitStructure.CAN_Prescaler = 10;
break;
case 4://125K
CAN_InitStructure.CAN_SJW = CAN_SJW_1tq;
CAN_InitStructure.CAN_BS1 = CAN_BS1_13tq;//CAN_BS1_3tq;
CAN_InitStructure.CAN_BS2 = CAN_BS2_2tq;//CAN_BS2_5tq;
CAN_InitStructure.CAN_Prescaler = 9;
break;
case 5: //250K
CAN_InitStructure.CAN_SJW = CAN_SJW_1tq;
CAN_InitStructure.CAN_BS1 = CAN_BS1_6tq;//CAN_BS1_3tq;
CAN_InitStructure.CAN_BS2 = CAN_BS2_1tq;//CAN_BS2_5tq;
CAN_InitStructure.CAN_Prescaler = 9;
break;
case 6://500K
CAN_InitStructure.CAN_SJW = CAN_SJW_1tq;
CAN_InitStructure.CAN_BS1 = CAN_BS1_8tq;//CAN_BS1_3tq;
CAN_InitStructure.CAN_BS2 = CAN_BS2_3tq;//CAN_BS2_5tq;
CAN_InitStructure.CAN_Prescaler = 3;
break;
case 7: //1M
CAN_InitStructure.CAN_SJW = CAN_SJW_1tq;
CAN_InitStructure.CAN_BS1 = CAN_BS1_14tq;//CAN_BS1_3tq;
CAN_InitStructure.CAN_BS2 = CAN_BS2_3tq;//CAN_BS2_5tq;
CAN_InitStructure.CAN_Prescaler = 1;
break;
default://125K
CAN_InitStructure.CAN_SJW = CAN_SJW_1tq;
CAN_InitStructure.CAN_BS1 = CAN_BS1_13tq;//CAN_BS1_3tq;
CAN_InitStructure.CAN_BS2 = CAN_BS2_2tq;//CAN_BS2_5tq;
CAN_InitStructure.CAN_Prescaler = 9;
break;
}
}
else
{
switch (iBaud)
{
case 0://5K
CAN_InitStructure.CAN_SJW = CAN_SJW_1tq;
CAN_InitStructure.CAN_BS1 = CAN_BS1_13tq;//CAN_BS1_3tq;
CAN_InitStructure.CAN_BS2 = CAN_BS2_2tq;//CAN_BS2_5tq;
CAN_InitStructure.CAN_Prescaler = 450;
break;
case 1://10K
CAN_InitStructure.CAN_SJW = CAN_SJW_1tq;
CAN_InitStructure.CAN_BS1 = CAN_BS1_13tq;//CAN_BS1_3tq;
CAN_InitStructure.CAN_BS2 = CAN_BS2_2tq;//CAN_BS2_5tq;
CAN_InitStructure.CAN_Prescaler = 225;
break;
case 2: //50K
CAN_InitStructure.CAN_SJW = CAN_SJW_1tq;
CAN_InitStructure.CAN_BS1 = CAN_BS1_13tq;//CAN_BS1_3tq;
CAN_InitStructure.CAN_BS2 = CAN_BS2_2tq;//CAN_BS2_5tq;
CAN_InitStructure.CAN_Prescaler = 45;
break;
case 3: //100K
CAN_InitStructure.CAN_SJW = CAN_SJW_1tq;
CAN_InitStructure.CAN_BS1 = CAN_BS1_14tq;//CAN_BS1_3tq;
CAN_InitStructure.CAN_BS2 = CAN_BS2_3tq;//CAN_BS2_5tq;
CAN_InitStructure.CAN_Prescaler = 20;
break;
case 4://125K
CAN_InitStructure.CAN_SJW = CAN_SJW_1tq;
CAN_InitStructure.CAN_BS1 = CAN_BS1_13tq;//CAN_BS1_3tq;
CAN_InitStructure.CAN_BS2 = CAN_BS2_2tq;//CAN_BS2_5tq;
CAN_InitStructure.CAN_Prescaler = 18;
break;
case 5: //250K
CAN_InitStructure.CAN_SJW = CAN_SJW_1tq;
CAN_InitStructure.CAN_BS1 = CAN_BS1_13tq;//CAN_BS1_3tq;
CAN_InitStructure.CAN_BS2 = CAN_BS2_2tq;//CAN_BS2_5tq;
CAN_InitStructure.CAN_Prescaler = 9;
break;
case 6://500K
CAN_InitStructure.CAN_SJW = CAN_SJW_1tq;
CAN_InitStructure.CAN_BS1 = CAN_BS1_6tq;//CAN_BS1_3tq;
CAN_InitStructure.CAN_BS2 = CAN_BS2_1tq;//CAN_BS2_5tq;
CAN_InitStructure.CAN_Prescaler = 9;
break;
case 7: //1M
CAN_InitStructure.CAN_SJW = CAN_SJW_1tq;
CAN_InitStructure.CAN_BS1 = CAN_BS1_8tq;//CAN_BS1_3tq;
CAN_InitStructure.CAN_BS2 = CAN_BS2_3tq;//CAN_BS2_5tq;
CAN_InitStructure.CAN_Prescaler = 3;
break;
default://125K
CAN_InitStructure.CAN_SJW = CAN_SJW_1tq;
CAN_InitStructure.CAN_BS1 = CAN_BS1_13tq;//CAN_BS1_3tq;
CAN_InitStructure.CAN_BS2 = CAN_BS2_2tq;//CAN_BS2_5tq;
CAN_InitStructure.CAN_Prescaler = 18;
break;
}
}
CAN_Init(CAN1, &CAN_InitStructure);
}
void CAN_SetAddr(uint8_t addr)
{
uint32_t address;
//uint32_t addrmask;
address=addr;
address=address<<(13+3);
//addrmask=(0xff<<(13+3));
CAN_FilterInitStructure.CAN_FilterNumber=0;
CAN_FilterInitStructure.CAN_FilterMode=CAN_FilterMode_IdMask;
CAN_FilterInitStructure.CAN_FilterScale=CAN_FilterScale_32bit;
CAN_FilterInitStructure.CAN_FilterIdHigh = (((u32)address)&0xFFFF0000)>>16;
CAN_FilterInitStructure.CAN_FilterIdLow = (((u32)address)|CAN_ID_EXT|CAN_RTR_DATA)&0xFFFF;
CAN_FilterInitStructure.CAN_FilterMaskIdHigh = 0x00ff;
CAN_FilterInitStructure.CAN_FilterMaskIdLow = 0x05;
//CAN_FilterInitStructure.CAN_FilterMaskIdHigh = 0;
//CAN_FilterInitStructure.CAN_FilterMaskIdLow = 0;
CAN_FilterInitStructure.CAN_FilterFIFOAssignment=0;
CAN_FilterInitStructure.CAN_FilterActivation=ENABLE;
CAN_FilterInit(&CAN_FilterInitStructure);
}
void CAN_InitEx(uint8_t addr,uint8_t uBaud)
{
GPIO_InitTypeDef GPIO_InitStructure;
NVIC_InitTypeDef NVIC_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO |RCC_APB2Periph_GPIO_CAN1, ENABLE);
RCC_APB1PeriphClockCmd(RCC_APB1Periph_CAN1, ENABLE);
#ifndef AMP12_CAN
GPIO_PinRemapConfig(GPIO_Remap1_CAN1 , ENABLE);
#endif
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_CAN_RX;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIO_CAN, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_CAN_TX;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIO_CAN, &GPIO_InitStructure);
NVIC_InitStructure.NVIC_IRQChannel = USB_LP_CAN1_RX0_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x0;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x0;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
NVIC_InitStructure.NVIC_IRQChannel = CAN1_SCE_IRQn;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
CAN_DeInit(CAN1);
CAN_SetBaudRate(uBaud);
CAN_SetAddr(addr);
CAN_ITConfig(CAN1, CAN_IT_BOF|CAN_IT_EPV |CAN_IT_EWG | CAN_IT_ERR, ENABLE);
}
void ICAN_Reset(void)
{
uint8_t param=*((uint8_t*)(0x1FFFF806));
uint8_t baud=0;
uint8_t addr=0;
GPIO_InitTypeDef GPIO_InitStructure;
NVIC_InitTypeDef NVIC_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO |RCC_APB2Periph_GPIO_CAN1, ENABLE);
RCC_APB1PeriphClockCmd(RCC_APB1Periph_CAN1, ENABLE);
if(param==0xff)
{
baud=4;
addr=0x1;
}
else
{
addr=0x1F¶m;
baud=param>>5;
}
CAN_DeInit(CAN1);
CAN_SetBaudRate(baud);
CAN_SetAddr(addr);
CAN_ITConfig(CAN1, CAN_IT_BOF|CAN_IT_EPV |CAN_IT_EWG | CAN_IT_ERR, ENABLE);
}
void CAN1_SCE_IRQHandler(void)
{
static uint8_t error;
if(CAN_GetFlagStatus(CAN1,CAN_FLAG_BOF) == SET)
{
CAN_ClearITPendingBit(CAN1,CAN_IT_BOF);
}
else if(CAN_GetITStatus(CAN1,CAN_IT_ERR))
{
CAN_ClearITPendingBit(CAN1,CAN_IT_ERR);
}
else if(CAN_GetFlagStatus(CAN1,CAN_FLAG_EPV) == SET)
{
CAN_ClearITPendingBit(CAN1,CAN_IT_EPV);
}
else if(CAN_GetFlagStatus(CAN1,CAN_FLAG_EWG) == SET)
{
CAN_ClearITPendingBit(CAN1,CAN_IT_EWG);
}
else
{
CAN_ClearITPendingBit(CAN1,CAN_IT_EWG);
CAN_ClearITPendingBit(CAN1,CAN_IT_EPV);
CAN_ClearITPendingBit(CAN1,CAN_IT_BOF);
CAN_ClearITPendingBit(CAN1,CAN_IT_ERR);
}
error=CAN_GetLastErrorCode(CAN1);
error=error;
ICAN_Init();
}
|