本帖最后由 DEMRY 于 2020-4-11 10:09 编辑
STM32F103RCT6
72M
硬件部分:
代码:
配置部分:
GPIO_InitTypeDef GPIO_InitStruct;
NVIC_InitTypeDef NVIC_InitStruct;
CAN_InitTypeDef CAN_InitStruct;
CAN_FilterInitTypeDef CAN_FilterInitStruct;
//时钟配置
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);
RCC_APB1PeriphClockCmd(RCC_APB1Periph_CAN1,ENABLE);
//端口配置
GPIO_InitStruct.GPIO_Pin=GPIO_Pin_11;//RX
GPIO_InitStruct.GPIO_Mode=GPIO_Mode_IPU;
GPIO_Init(GPIOA,&GPIO_InitStruct);
GPIO_InitStruct.GPIO_Pin=GPIO_Pin_12;//TX
GPIO_InitStruct.GPIO_Speed=GPIO_Speed_50MHz;
GPIO_InitStruct.GPIO_Mode=GPIO_Mode_AF_PP;
GPIO_Init(GPIOA,&GPIO_InitStruct);
//中断配置
//NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);
NVIC_InitStruct.NVIC_IRQChannel = USB_LP_CAN1_RX0_IRQn;
NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority = 0;
NVIC_InitStruct.NVIC_IRQChannelSubPriority = 0;
NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStruct);
//CAN配置
CAN_DeInit(CAN1);//将外设CAN的全部寄存器重设为缺省值
CAN_StructInit(&CAN_InitStruct);//把CAN_InitStruct中的每一个参数按缺省值填入
CAN_InitStruct.CAN_TTCM=DISABLE;//关闭时间触发模式
CAN_InitStruct.CAN_ABOM=DISABLE;//关闭自动离线管理
CAN_InitStruct.CAN_AWUM=DISABLE;//关闭自动唤醒模式
CAN_InitStruct.CAN_NART=DISABLE;//禁止报文自动重传
CAN_InitStruct.CAN_RFLM=DISABLE;//溢出时报文覆盖
CAN_InitStruct.CAN_TXFP=DISABLE;//关闭TXFP /*0:优先级由报文的标识符来决定,1优先级由发送请求的顺序来决定。*/
CAN_InitStruct.CAN_Mode=CAN_Mode_Normal;//工作模式(正常)
CAN_InitStruct.CAN_SJW=CAN_SJW_1tq; //重新同步跳跃宽度1个时间单位
CAN_InitStruct.CAN_BS1=CAN_BS1_3tq; //时间段1为3个时间单位
CAN_InitStruct.CAN_BS2=CAN_BS2_2tq; //时间段2为2个时间单位
CAN_InitStruct.CAN_Prescaler = 240; //时间单位长度 //波特率为:72M/240/(1+3+2))=0.05 即波特率为50KBPS
CAN_Init(CAN1,&CAN_InitStruct);//初始化CAN
//接收过滤器
CAN_FilterInitStruct.CAN_FilterNumber=0;//过滤器编号为0
CAN_FilterInitStruct.CAN_FilterMode=CAN_FilterMode_IdMask; //过滤器类型为标识符屏蔽位模式
CAN_FilterInitStruct.CAN_FilterScale=CAN_FilterScale_32bit; //过滤器位宽为32位
CAN_FilterInitStruct.CAN_FilterIdHigh=0x0F00; //要过滤的ID高位
CAN_FilterInitStruct.CAN_FilterIdLow=0; //要过滤的ID高位
CAN_FilterInitStruct.CAN_FilterMaskIdHigh=0x0F00; //过滤器屏蔽标识符的高16位值
CAN_FilterInitStruct.CAN_FilterMaskIdLow=0; //过滤器屏蔽标识符的低16位值
CAN_FilterInitStruct.CAN_FilterFIFOAssignment=CAN_Filter_FIFO0; //过滤器将ID报文关联到FIFO0缓存区中,数据只能从这里导出
CAN_FilterInitStruct.CAN_FilterActivation=ENABLE;//过滤器使能
CAN_FilterInit(&CAN_FilterInitStruct);//初始化过滤器
CAN_ITConfig(CAN1,CAN_IT_FMP0,ENABLE); //接收中断使能
CAN_ITConfig(CAN1,CAN_IT_TME,ENABLE); //发送中断使能
发送部分:
uint8_t i=0;
TxMessage.StdId = 0x00; //标准标识符(11bit)
TxMessage.ExtId = 0x0000; //标准+扩展标识符(29bit)
TxMessage.IDE = CAN_ID_STD; //标识符选择 0启用标准标识符 1启用扩展标识符
TxMessage.RTR = CAN_RTR_DATA; //帧类型 0发送数据帧 1发送远程帧
TxMessage.DLC = hbs_tx_lenth; //数据长度
for(i=0;i<8;i++)
{
TxMessage.Data=HBSTxBuffer;
}
CAN_Transmit(CAN1, &TxMessage); //
中断部分:
void USB_LP_CAN1_RX0_IRQHandler(void)//接收中断 FIFO0
{
CAN_Receive(CAN1,CAN_FIFO0,&RxMessage);//can接收的数据存在FIFO0的RxMessage里
if(RxMessage.RTR == CAN_RTR_Remote)//远程帧
{
//
}
else if(RxMessage.RTR == CAN_RTR_Data)//数据帧
{
//
}
if(RxMessage.DLC)
{
hbs_rece_frame_f=1;
//RxMessage.Data[];
}
CAN_ClearFlag(CAN1, CAN_IT_FMP0);
}
void CAN1_RX1_IRQHandler(void)//接收中断 FIFO1
{
//
}
//
void USB_HP_CAN1_TX_IRQHandler(void) //发送中断
{
if (CAN_GetITStatus(CAN1,CAN_IT_TME)!= RESET)
{
CAN_ClearITPendingBit(CAN1,CAN_IT_TME);
hbs_send_frame_f=1;
}
}
寄存器:
、、、、、、、、、、、、、、、
目前问题是
1 调试打断点无法进入 接收和发送中断函数。
2 如果开启看门狗 就会一直复位。
3 波形单片机的管脚(TX RX)都有波形,且波形相同 看起来波形也是对的。并且此波形一直存在,感觉在不断的发,而我程序中发送函数只调用一次。
4 CAN总线上没有波形。
5 排除了硬件焊错 管脚断路等低级问题
6 回环模式测试: //CAN_InitStruct.CAN_Mode=CAN_Mode_Normal;//工作模式(正常)
CAN_InitStruct.CAN_Mode=CAN_Mode_LoopBack;//回环模式 测试用
使用回环模式 可以触发接收中断 且接收到正确的数据 但是发送中断仍然无法触发。
EXPORT USB_HP_CAN1_TX_IRQHandler [WEAK]
EXPORT USB_LP_CAN1_RX0_IRQHandler [WEAK]
EXPORT CAN1_RX1_IRQHandler [WEAK]
EXPORT CAN1_SCE_IRQHandler [WEAK]
所以证明发送成功了,于是只有两种可能 1发送函数名错了 2发送中断未配置成功。
检查启动文件后1排除。
2的话我一直以为 CAN_ITConfig(CAN1,CAN_IT_TME,ENABLE);这一句就可以配置发送中断,因为发送中断只有一个名称。
但是实际上 也需要配置一下,尝试在程序中增加
NVIC_InitStruct.NVIC_IRQChannel = USB_HP_CAN1_TX_IRQn;
NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority = 0;
NVIC_InitStruct.NVIC_IRQChannelSubPriority = 0;
NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStruct);
问题解决。发送中断可以触发。
|