龙哥你好 请教你一个问题可以吗
用USB转CAN调试的时候只有过滤器5、6可以调通可它7、8、9、10、11、12都调试不通,感觉各过滤器配置基本相同,中断子函数中各模块的函数代码功能一样,可只有5,、6号过滤器可以调通,想请教一下是哪里出现了问题?
调试结果如图:
如图所示只有5、6号过滤器可以发送和接收数据 其他各过滤器只能发送数据接收不到数据
代码如下:
void USB_LP_CAN1_RX0_IRQHandler(void)
{
CanRxMsg RxMessage;
//初始化接收
Init_RxMes(&RxMessage);
//接收总线上的数据 释放接收FIFO
CAN_Receive(CAN1,CAN_FIFO0, &RxMessage);
//处理接收到的数据
switch(RxMessage.ExtId)
{
case PUMP_CTL_SAMP_EXT_ID: //采样泵控制 接收一个控制字节
if(RxMessage.RTR == CAN_RTR_DATA) //数据桢
{
//置Pump_Flag=1
  ump_Flag[0] =1;
//接收数据
  ump_Num[0] = RxMessage.Data[0];
//返回接收到的数据
CAN_Send_Byte(PUMP_CTL_SAMP_EXT_ID,Pump_Num[0]);
}
else if(RxMessage.RTR == CAN_RTR_REMOTE) //远程帧
{
//获取当前控制泵的状态返回给显示主板
CAN_Send_Byte(PUMP_CTL_SAMP_EXT_ID,Pump_Num[0]);
}
break;
case PIPE_SAMP_NUM_EXT_ID: //采样管路号 1字节数据
if(RxMessage.RTR == CAN_RTR_DATA)
{
//置采样标志位
Samp_Flag = 1;
//接收数据
SampPipe_Num = RxMessage.Data[0]; //刷新变量
//返回接收到的数据
CAN_Send_Byte(PIPE_SAMP_NUM_EXT_ID,SampPipe_Num); //应答ACK
}
else if(RxMessage.RTR == CAN_RTR_REMOTE)
{
//发送数据
CAN_Send_Byte(PIPE_SAMP_NUM_EXT_ID,SampPipe_Num); //应答ACK
}
break;
case FLUX_SAMP_EXT_ID: //采样流量 4字节数据
if(RxMessage.RTR == CAN_RTR_DATA)
{
//接受数据
}
else if(RxMessage.RTR == CAN_RTR_REMOTE)
{
//更新发送缓冲区
UpdateSampFlux(Samp_Flux);
//远程帧相当于读取命令,发送采样流量给显示主板
CAN_Send_Data(FLUX_SAMP_EXT_ID,4,SampFlux);
}
break;
case PRESS_SAMP_EXT_ID: //采样压力 4字节数据
if(RxMessage.RTR == CAN_RTR_DATA)
{
}
else if(RxMessage.RTR == CAN_RTR_REMOTE)
{
//更新发送缓冲区
UpdateSampPress(Samp_Press);
//读采样压力,发送采样压力给显示主板,先将采样值按位提取数字
CAN_Send_Data(PRESS_SAMP_EXT_ID,4,SampPress);
}
break;
case PUMP_CTL_YUC_EXT_ID: //预抽泵控制
if(RxMessage.RTR == CAN_RTR_DATA)
{
//置Pump_Flag=1
  ump_Flag[1] =1;
//接收数据
  ump_Num[1] = RxMessage.Data[0];
//返回接收到的数据
CAN_Send_Byte(PUMP_CTL_YUC_EXT_ID,Pump_Num[1]);
}
else if(RxMessage.RTR == CAN_RTR_REMOTE)
{
CAN_Send_Byte(PUMP_CTL_YUC_EXT_ID,Pump_Num[1]);
}
break;
case PIPE_YUC_NUM_EXT_ID: //预抽管路号
if(RxMessage.RTR == CAN_RTR_DATA)
{
//置采样标志位
YuChou_Flag = 1;
//接收数据
YuChouPipe_Num = RxMessage.Data[0]; //刷新变量
//返回接收到的数据
CAN_Send_Byte(PIPE_YUC_NUM_EXT_ID,YuChouPipe_Num);
}
else if(RxMessage.RTR == CAN_RTR_REMOTE)
{
CAN_Send_Byte(PIPE_YUC_NUM_EXT_ID,YuChouPipe_Num);
}
break;
case FLUX_YUC_EXT_ID: //预抽流量
if(RxMessage.RTR == CAN_RTR_DATA)
{
//存储数据到缓冲区
}
else if(RxMessage.RTR == CAN_RTR_REMOTE)
{
//更新发送缓冲区
UpdateYuChouFlux(YuChou_Flux);
CAN_Send_Data(FLUX_YUC_EXT_ID,4,YuChouFlux);//发送
}
break;
case PRESS_YUC_EXT_ID: //预抽压力
if(RxMessage.RTR == CAN_RTR_DATA)
{
//存储数据到缓冲区
}
else if(RxMessage.RTR == CAN_RTR_REMOTE)
{
UpdateYuChouPress(YuChou_Press);
CAN_Send_Data(PRESS_YUC_EXT_ID,4,YuChouPress);
}
break;
default:
break;
}
}
中断中用到的子函数如下
void CAN_Send_Data(uint32_t id,uint8_t dlc,uint8_t *data)
{
CanTxMsg TxMessage;
uint8_t i,TransmitMailbox;
TxMessage.StdId=0; //标准ID
TxMessage.ExtId=id; //不使用扩展ID
TxMessage.IDE=CAN_ID_EXT; //使用标准ID
TxMessage.RTR=CAN_RTR_DATA; //数据帧
TxMessage.DLC=dlc; //数据长度
for(i=0;i<dlc;i++)
{
TxMessage.Data=*data; //数据1
data++;
}
TransmitMailbox=CAN_Transmit(CAN1, &TxMessage);
while((CAN_TransmitStatus(CAN1,TransmitMailbox)!=CANTXOK)&&(i!=0xff))
{
i++;
}
}
void CAN_Send_Byte(uint32_t id,uint8_t data)
{
CanTxMsg TxMessage;
uint8_t i,TransmitMailbox;
TxMessage.StdId=0; //不使用标准ID
TxMessage.ExtId=id; //使用扩展ID
TxMessage.IDE=CAN_ID_EXT; //使用标准ID
TxMessage.RTR=CAN_RTR_DATA; //数据帧
TxMessage.DLC=1; //数据长度
TxMessage.Data[1]=data; //数据1
TransmitMailbox=CAN_Transmit(CAN1, &TxMessage);
while((CAN_TransmitStatus(CAN1,TransmitMailbox)!=CANTXOK)&&(i!=0xff))
{
i++;
}
}
void CAN_Send_Remote(uint32_t id)
{
CanTxMsg TxMessage;
uint8_t i,TransmitMailbox;
TxMessage.StdId=0; //标准ID
TxMessage.ExtId=id; //不使用扩展ID
TxMessage.IDE=CAN_ID_STD; //使用标准ID
TxMessage.RTR=CAN_RTR_REMOTE; //数据帧
TxMessage.DLC=0; //数据长度
TransmitMailbox=CAN_Transmit(CAN1, &TxMessage);
while((CAN_TransmitStatus(CAN1,TransmitMailbox)!=CANTXOK)&&(i!=0xff))
{
i++;
}
}
void Init_RxMes(CanRxMsg *RxMessage)
{
uint8_t i = 0;
RxMessage->StdId = 0;
RxMessage->ExtId = 0;
RxMessage->IDE = 0;
RxMessage->RTR = 0;
RxMessage->DLC = 0;
RxMessage->FMI = 0;
for (i = 0; i < 8; i++)
{
RxMessage->Data = 0;
}
}
各ID号定义如下
#define PUMP_CTL_SAMP_EXT_ID ((uint32_t)0x0005)
#define PIPE_SAMP_NUM_EXT_ID ((uint32_t)0x0006)
#define FLUX_SAMP_EXT_ID ((uint32_t)0x0007)
#define PRESS_SAMP_EXT_ID ((uint32_t)0x0008)
#define PUMP_CTL_YUC_EXT_ID ((uint32_t)0x0009)
#define PIPE_YUC_NUM_EXT_ID ((uint32_t)0x000A)
#define FLUX_YUC_EXT_ID ((uint32_t)0x000B)
#define PRESS_YUC_EXT_ID ((uint32_t)0x000C)
#define ADC_ID ((uint32_t)0x000D)
CAN及各过滤器配置如下
void CanConfiguration(void)
{
CAN_InitTypeDef CAN_InitStructure;
CAN_FilterInitTypeDef CAN_FilterInitStructure;
GPIO_InitTypeDef GPIO_InitStructure;
//是能CAN总线时钟
RCC_APB1PeriphClockCmd(RCC_APB1Periph_CAN1,ENABLE); //CAN1时钟
//stm32f103c8没有端口复用重映射,所以不需要下面语句
//GPIO_PinRemapConfig(GPIO_Remap1_CAN1 , ENABLE); //端口复用为CAN1
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11; //PA11:CAN-RX
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU; //输入上拉
GPIO_Init(GPIOA, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12; //PA12:CAN-TX
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; //复用模式
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &GPIO_InitStructure);
/* CAN寄存器初始化 */
CAN_DeInit(CAN1);
CAN_StructInit(&CAN_InitStructure);
/* CAN单元初始化 */
CAN_InitStructure.CAN_TTCM=DISABLE; //MCR-TTCM 时间触发通信模式使能
CAN_InitStructure.CAN_ABOM=DISABLE; //MCR-ABOM 自动离线管理
CAN_InitStructure.CAN_AWUM=DISABLE; //MCR-AWUM 自动唤醒模式
CAN_InitStructure.CAN_NART=ENABLE; //MCR-NART 禁止报文自动重传 0-自动重传 1-报文只传一次
CAN_InitStructure.CAN_RFLM=DISABLE; //MCR-RFLM 接收FIFO 锁定模式 0-溢出时新报文会覆盖原有报文 1-溢出时,新报文丢弃
CAN_InitStructure.CAN_TXFP = ENABLE; //MCR-TXFP 发送FIFO优先级 0-优先级取决于报文标示符 1-优先级取决于发送请求的顺序
CAN_InitStructure.CAN_Mode = CAN_Mode_Normal; //BTR-SILM/LBKM CAN正常通信模式
//CAN_InitStructure.CAN_TXFP=DISABLE;
//CAN_InitStructure.CAN_Mode=CAN_Mode_LoopBack;
CAN_InitStructure.CAN_SJW=CAN_SJW_1tq; //BTR-SJW 重新同步跳跃宽度 1个时间单元
CAN_InitStructure.CAN_BS1=CAN_BS1_6tq; //BTR-TS1 时间段1 占用了2个时间单元
CAN_InitStructure.CAN_BS2=CAN_BS2_4tq; //BTR-TS1 时间段2 占用了3个时间单元
//20KPS 11.0592/((1+6+4)*50)=20KPS
CAN_InitStructure.CAN_Prescaler =50; //BTR-BRP 波特率分频器 定义了时间单元的时间长度 36/(1+2+3)/6=1Mbps
CAN_Init(CAN1, &CAN_InitStructure);
// CAN过滤器初始化 只接收扩展帧,包括扩展数据帧和远程帧都不会被过滤掉
//采样泵控制过滤器初始化
CAN_FilterInitStructure.CAN_FilterNumber=5; //
CAN_FilterInitStructure.CAN_FilterMode=CAN_FilterMode_IdMask; //FM1R 过滤器组0的工作模式。
CAN_FilterInitStructure.CAN_FilterScale=CAN_FilterScale_32bit; //FS1R 过滤器组0(13~0)的位宽。
CAN_FilterInitStructure.CAN_FilterIdHigh=((PUMP_CTL_SAMP_EXT_ID<<3)&0xFFFF0000)>>16; //要过滤的ID高位
CAN_FilterInitStructure.CAN_FilterIdLow=((PUMP_CTL_SAMP_EXT_ID<<3)|CAN_ID_EXT)&0xFFFF;//要过滤的ID低位
CAN_FilterInitStructure.CAN_FilterMaskIdHigh=0xffff;
CAN_FilterInitStructure.CAN_FilterMaskIdLow=0xfffc; //取消对帧类型的屏蔽
CAN_FilterInitStructure.CAN_FilterFIFOAssignment=CAN_FIFO0; //将被存放到其关联的FIFO中
CAN_FilterInitStructure.CAN_FilterActivation=ENABLE; //使能过滤器
CAN_FilterInit(&CAN_FilterInitStructure); //初始化过滤器5
//采样管路号过滤器初始化
CAN_FilterInitStructure.CAN_FilterNumber=6; //
CAN_FilterInitStructure.CAN_FilterMode=CAN_FilterMode_IdMask; //FM1R 过滤器组0的工作模式。
CAN_FilterInitStructure.CAN_FilterScale=CAN_FilterScale_32bit; //FS1R 过滤器组0(13~0)的位宽。
CAN_FilterInitStructure.CAN_FilterIdHigh=((PIPE_SAMP_NUM_EXT_ID<<3)&0xFFFF0000)>>16; //要过滤的ID高位
CAN_FilterInitStructure.CAN_FilterIdLow=((PIPE_SAMP_NUM_EXT_ID<<3)|CAN_ID_EXT)&0xFFFF;//要过滤的ID低位
CAN_FilterInitStructure.CAN_FilterMaskIdHigh=0xffff;
CAN_FilterInitStructure.CAN_FilterMaskIdLow=0xfffc; //取消对帧类型的屏蔽
CAN_FilterInitStructure.CAN_FilterFIFOAssignment=CAN_FIFO0; //将被存放到其关联的FIFO中
CAN_FilterInitStructure.CAN_FilterActivation=ENABLE; //使能过滤器
CAN_FilterInit(&CAN_FilterInitStructure);
//采样流量过滤器初始化
CAN_FilterInitStructure.CAN_FilterNumber=7; //
CAN_FilterInitStructure.CAN_FilterMode=CAN_FilterMode_IdMask; //FM1R 过滤器组0的工作模式。
CAN_FilterInitStructure.CAN_FilterScale=CAN_FilterScale_32bit; //FS1R 过滤器组0(13~0)的位宽。
CAN_FilterInitStructure.CAN_FilterIdHigh=((FLUX_SAMP_EXT_ID<<3)&0xFFFF0000)>>16; //要过滤的ID高位
CAN_FilterInitStructure.CAN_FilterIdLow=((FLUX_SAMP_EXT_ID<<3)|CAN_ID_EXT)&0xFFFF;//要过滤的ID低位
CAN_FilterInitStructure.CAN_FilterMaskIdHigh=0xffff;
CAN_FilterInitStructure.CAN_FilterMaskIdLow=0xfffc; //取消对帧类型的屏蔽
CAN_FilterInitStructure.CAN_FilterFIFOAssignment=CAN_FIFO0; //将被存放到其关联的FIFO中
CAN_FilterInitStructure.CAN_FilterActivation=ENABLE; //使能过滤器
//采样压力过滤器初始化
CAN_FilterInitStructure.CAN_FilterNumber=8; //
CAN_FilterInitStructure.CAN_FilterMode=CAN_FilterMode_IdMask; //FM1R 过滤器组0的工作模式。
CAN_FilterInitStructure.CAN_FilterScale=CAN_FilterScale_32bit; //FS1R 过滤器组0(13~0)的位宽。
CAN_FilterInitStructure.CAN_FilterIdHigh=((PRESS_SAMP_EXT_ID<<3)&0xFFFF0000)>>16; //要过滤的ID高位
CAN_FilterInitStructure.CAN_FilterIdLow=((PRESS_SAMP_EXT_ID<<3)|CAN_ID_EXT)&0xFFFF;//要过滤的ID低位
CAN_FilterInitStructure.CAN_FilterMaskIdHigh=0xffff;
CAN_FilterInitStructure.CAN_FilterMaskIdLow=0xfffc; //取消对帧类型的屏蔽
CAN_FilterInitStructure.CAN_FilterFIFOAssignment=CAN_FIFO0; //将被存放到其关联的FIFO中
CAN_FilterInitStructure.CAN_FilterActivation=ENABLE; //使能过滤器
//预抽泵控制过滤器初始化
CAN_FilterInitStructure.CAN_FilterNumber=9; //
CAN_FilterInitStructure.CAN_FilterMode=CAN_FilterMode_IdMask; //FM1R 过滤器组0的工作模式。
CAN_FilterInitStructure.CAN_FilterScale=CAN_FilterScale_32bit; //FS1R 过滤器组0(13~0)的位宽。
CAN_FilterInitStructure.CAN_FilterIdHigh=((PUMP_CTL_YUC_EXT_ID<<3)&0xFFFF0000)>>16; //要过滤的ID高位
CAN_FilterInitStructure.CAN_FilterIdLow=((PUMP_CTL_YUC_EXT_ID<<3)|CAN_ID_EXT)&0xFFFF;//要过滤的ID低位
CAN_FilterInitStructure.CAN_FilterMaskIdHigh=0xffff;
CAN_FilterInitStructure.CAN_FilterMaskIdLow=0xfffc; //取消对帧类型的屏蔽
CAN_FilterInitStructure.CAN_FilterFIFOAssignment=CAN_FIFO0; //将被存放到其关联的FIFO中
CAN_FilterInitStructure.CAN_FilterActivation=ENABLE; //使能过滤器
//预抽管路号过滤器初始化
CAN_FilterInitStructure.CAN_FilterNumber=10; //
CAN_FilterInitStructure.CAN_FilterMode=CAN_FilterMode_IdMask; //FM1R 过滤器组0的工作模式。
CAN_FilterInitStructure.CAN_FilterScale=CAN_FilterScale_32bit; //FS1R 过滤器组0(13~0)的位宽。
CAN_FilterInitStructure.CAN_FilterIdHigh=((PIPE_YUC_NUM_EXT_ID<<3)&0xFFFF0000)>>16; //要过滤的ID高位
CAN_FilterInitStructure.CAN_FilterIdLow=((PIPE_YUC_NUM_EXT_ID<<3)|CAN_ID_EXT)&0xFFFF;//要过滤的ID低位
CAN_FilterInitStructure.CAN_FilterMaskIdHigh=0xffff;
CAN_FilterInitStructure.CAN_FilterMaskIdLow=0xfffc; //取消对帧类型的屏蔽
CAN_FilterInitStructure.CAN_FilterFIFOAssignment=CAN_FIFO0; //将被存放到其关联的FIFO中
CAN_FilterInitStructure.CAN_FilterActivation=ENABLE; //使能过滤器
//预抽流量过滤器初始化
CAN_FilterInitStructure.CAN_FilterNumber=11; //
CAN_FilterInitStructure.CAN_FilterMode=CAN_FilterMode_IdMask; //FM1R 过滤器组0的工作模式。
CAN_FilterInitStructure.CAN_FilterScale=CAN_FilterScale_32bit; //FS1R 过滤器组0(13~0)的位宽。
CAN_FilterInitStructure.CAN_FilterIdHigh=((FLUX_YUC_EXT_ID<<3)&0xFFFF0000)>>16; //要过滤的ID高位
CAN_FilterInitStructure.CAN_FilterIdLow=((FLUX_YUC_EXT_ID<<3)|CAN_ID_EXT)&0xFFFF;//要过滤的ID低位
CAN_FilterInitStructure.CAN_FilterMaskIdHigh=0xffff;
CAN_FilterInitStructure.CAN_FilterMaskIdLow=0xfffc; //取消对帧类型的屏蔽
CAN_FilterInitStructure.CAN_FilterFIFOAssignment=CAN_FIFO0; //将被存放到其关联的FIFO中
CAN_FilterInitStructure.CAN_FilterActivation=ENABLE;
//预抽压力过滤器初始化
CAN_FilterInitStructure.CAN_FilterNumber=12; //
CAN_FilterInitStructure.CAN_FilterMode=CAN_FilterMode_IdMask; //FM1R 过滤器组0的工作模式。
CAN_FilterInitStructure.CAN_FilterScale=CAN_FilterScale_32bit; //FS1R 过滤器组0(13~0)的位宽。
CAN_FilterInitStructure.CAN_FilterIdHigh=((PRESS_YUC_EXT_ID<<3)&0xFFFF0000)>>16; //要过滤的ID高位
CAN_FilterInitStructure.CAN_FilterIdLow=((PRESS_YUC_EXT_ID<<3)|CAN_ID_EXT)&0xFFFF;//要过滤的ID低位
CAN_FilterInitStructure.CAN_FilterMaskIdHigh=0xffff;
CAN_FilterInitStructure.CAN_FilterMaskIdLow=0xfffc; //取消对帧类型的屏蔽
CAN_FilterInitStructure.CAN_FilterFIFOAssignment=CAN_FIFO0; //将被存放到其关联的FIFO中
CAN_FilterInitStructure.CAN_FilterActivation=ENABLE;
/* CAN FIFO0 接收中断使能 */
CAN_ITConfig(CAN1, CAN_IT_FMP0, ENABLE);
}
|