本帖最后由 stm1024 于 2018-2-28 09:30 编辑
手头有一块开发板,用的是STM32F103ZET6,确认使用的CAN1 RX和TX是标准的PA11和PA12,驱动电路为TJA1040。然后想学习一下CAN的发送和接收,以下是代码:
CAN函数
已经将其配置为环回模式,然后也在NVIC中打开了相应的中断。
- #include "XDCAN.h"
- void XDCAN_Config(void)
- {
- XDCAN_GPIO_Config();
- XDCAN_NVIC_config();
-
- XDCAN_Mode_Config();
- XDCAN_Add_Filter(0x6666,14);
- }
- //config PA11 and PA12 for CAN1
- void XDCAN_GPIO_Config(void)
- {
- GPIO_InitTypeDef GPIO_InitStruct;
- RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_AFIO, ENABLE);
- //PA11 For CAN1-RX
- GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IPU;
- GPIO_InitStruct.GPIO_Pin = GPIO_Pin_11;
- GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
- GPIO_Init(GPIOA, &GPIO_InitStruct);
-
- //PA12 For CAN1-TX
- GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF_PP;
- GPIO_InitStruct.GPIO_Pin = GPIO_Pin_12;
- GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
- GPIO_Init(GPIOA, &GPIO_InitStruct);
- }
- //config NVIC for CAN1
- void XDCAN_NVIC_config(void)
- {
- NVIC_InitTypeDef NVIC_InitStruct;
- //NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);
- NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority = 0;
- NVIC_InitStruct.NVIC_IRQChannelSubPriority = 0;
- NVIC_InitStruct.NVIC_IRQChannel = USB_LP_CAN1_RX0_IRQn;
- NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE;
- NVIC_Init(&NVIC_InitStruct);
-
- //CAN interrupt sources
- CAN_ITConfig(CAN1, CAN_IT_FMP0, ENABLE);
-
- }
- //Config CAN1 work mode, baudrate 250kbps
- void XDCAN_Mode_Config(void)
- {
- CAN_InitTypeDef CAN_InitStruct;
- RCC_APB1PeriphClockCmd(RCC_APB1Periph_CAN1, ENABLE);
- CAN_DeInit(CAN1);
- CAN_StructInit(&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;
- CAN_InitStruct.CAN_Mode = CAN_Mode_LoopBack;
- CAN_InitStruct.CAN_SJW = CAN_SJW_1tq;
-
- /*
- APB1 36MHz
- 36M/((1+3+2)*24)=250kbps
- */
- CAN_InitStruct.CAN_BS1 = CAN_BS1_3tq;
- CAN_InitStruct.CAN_BS2 = CAN_BS2_2tq;
- CAN_InitStruct.CAN_Prescaler = 24;
- CAN_Init(CAN1, &CAN_InitStruct);
-
- }
- //
- void XDCAN_Add_Filter(uint32_t id,uint8_t fn)
- {
- CAN_FilterInitTypeDef CAN_FilterInitStruct;
- CAN_FilterInitStruct.CAN_FilterNumber=fn;//filter number,can be 0-13
- CAN_FilterInitStruct.CAN_FilterMode=CAN_FilterMode_IdMask;
- CAN_FilterInitStruct.CAN_FilterScale=CAN_FilterScale_32bit;
- CAN_FilterInitStruct.CAN_FilterIdHigh=0x0000;
- CAN_FilterInitStruct.CAN_FilterIdLow=0x0000;
- //do not Match
- CAN_FilterInitStruct.CAN_FilterMaskIdHigh=0x0000;
- CAN_FilterInitStruct.CAN_FilterMaskIdLow=0x0000;
-
- CAN_FilterInitStruct.CAN_FilterFIFOAssignment=CAN_Filter_FIFO0;
- CAN_FilterInitStruct.CAN_FilterActivation=ENABLE;
-
- CAN_FilterInit(&CAN_FilterInitStruct);
- //CAN_ITConfig(CAN1, CAN_IT_FMP0, ENABLE); //FIF0消息挂号中断允许
- }
- //Send a CAN Message, Extended Data Frame
- uint8_t XDCAN_SendMsg(uint32_t id, uint8_t len, uint8_t *dat)
- {
- uint8_t i = 0,tm;
- CanTxMsg TxMsg;
- if(len > 8)
- return 0xff;
- TxMsg.ExtId=id;
- TxMsg.RTR = CAN_RTR_DATA;
- TxMsg.IDE = CAN_ID_EXT;
- TxMsg.DLC = len;
- for(i=0; i<len; i++)
- {
- TxMsg.Data[i] = *dat;
- dat++;
- }
- tm=CAN_Transmit(CAN1, &TxMsg);
- return tm;
- }
复制代码
main函数
- #include "stm32f10x.h"
- #include "XDUtility.h"//Delay_ms
- #include "led.h"
- #include "XDCAN.h"
- uint8_t MSGBUFF[8]="666";
- uint8_t rb[8];
- void USER_Config(void)
- {
- //TO DO: Add User Configuration Here
- USART1_Config();
- LED_GPIO_Config();
- XDCAN_Config();
- }
- int main(void)
- {
- uint8_t ts,tmb,cnt=0,Status;
- uint32_t can_id=0;
- CanRxMsg RxMsg;
- USER_Config();
- LED_On();
- //XD_Delay_ms(500);
- LED_Off();
- while (1)
- {
- LED_On();
- tmb=XDCAN_SendMsg(can_id,3,MSGBUFF);
- XD_Delay_ms(100);
- LED_Off();
- can_id++;
- ts=CAN_TransmitStatus(CAN1,tmb);
- if(ts==CAN_TxStatus_Ok)
- {
- cnt++;
- }
- XD_Delay_ms(1000);
- } //while
- }
复制代码
stm32f10x_it.c中的中断函数
- void USB_LP_CAN1_RX0_IRQHandler(void)
- {
- CanRxMsg RxMsg;
- CAN_Receive(CAN1,CAN_FIFO0,&RxMsg);
- CAN_ClearITPendingBit(CAN1, CAN_IT_FMP0);
- XD_Delay_ms(500);
- }
复制代码 首先,调试可以发现发送是OK的:
然而,不管是用Simulator还是JLink调试,总是进不去中断,接收邮箱也一直是空的(见下图)不知道是怎么回事?
是否在环回模式下不支持这种功能?有碰到过类似问题并解决过的兄弟,能否讲解一下?
另外,我也试过在main函数中直接用polling的方式接收,然而发送完成之后使用CAN_MessagePending每次返回的结果都是0……
|
把此处的 14 改为 0-13 的数试试。
此处有提到。
此处不应屏蔽,否则进不了中断。
参考手册上多次提到非互联型产品只有0-13个过滤器可用。
STM32F103ZET6是非互联型产品。
评分
查看全部评分
感谢您的认真回复。
第一个地方,我确实是一开始使用的第0组过滤器,然而并不成功。
CAN_IT_Config那个,我把它放在了void XDCAN_NVIC_config(void)的最后一句中,然后我在调试的时候也检查过IER寄存器,FMPIE0是打开的:
另外,我不知道之前怎么鬼改改的,现在发送的状态都一直是CAN_TxStatus_Pending,这么看来发送都不成功了?
评分
查看全部评分
老早就解决了,是供电问题,必须要用5V供电,我用的是3.3V
接收屏蔽怎么设置的,我的也是回环模式不能进入中断。发送完成中断和接收中断都不能进入,头都大了