硬汉F103CAN历程原版是几个设备进行CAN收发,来控制蜂鸣器和LED,最近在移植的时候遇到了一些问题,原版例程里的CAN Stdid都是0x321,我在刚刚移植的时候也是都用的0x321,今天调试的时候把两个CAN的Stdid改了下,发现只要进入CAN接受中断,百分比程序跑飞,代码如下,代码比较长,C文件放在附件里了 //FreeRTOS任务调用函数,用于发送数据 void can_demo(void) { uint8_t data_temp[8]; data_temp[0]=0x01; data_temp[1]=0x01; can_data_send(0x320,0x01,2,data_temp); } //CAN数据发送函数 void can_data_send(uint32_t stdid,uint32_t extid,uint8_t dlc_len,uint8_t dlc_data[]) { uint8_t i; g_tCanTxMsg.StdId = stdid; g_tCanTxMsg.ExtId = extid; g_tCanTxMsg.RTR = CAN_RTR_DATA; g_tCanTxMsg.IDE = CAN_ID_STD; g_tCanTxMsg.DLC = dlc_len; if(dlc_len>8) { } for(i=0;i<dlc_len;i++) { g_tCanTxMsg.Data = dlc_data; } CAN_Transmit(CAN1, &g_tCanTxMsg); }
void bsp_can_init(void) { can_config(); can_NVIC_Config(); }
static void can_config(void) { GPIO_InitTypeDef GPIO_InitStructure; CAN_InitTypeDef CAN_InitStructure; CAN_FilterInitTypeDef CAN_FilterInitStructure;
//GPIO重新映射,使用PB8,PB9作为CAN的RX和TX收发引脚 #if Default_CAN_Interface == 0 /* PB8,PB9口线设置为AFIO模式, 切换到CAN功能 */ RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE); /* 使能GPIO时钟 */ RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
/* 配置CAN信号接收引脚: RX */ GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU; /* GPIO配置为上拉输入模式 */ GPIO_Init(GPIOB, &GPIO_InitStructure); /* 配置CAN信号发送引脚: TX */ GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; /* 配置为复用推挽输出 */ GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; /* 设置GPIO最大速度 */ GPIO_Init(GPIOB, &GPIO_InitStructure); /* 原生的CAN引脚和USB引脚是相同的口线,使用引脚的重映射功能将CAN引脚切换到PB8,PB9 */ GPIO_PinRemapConfig(GPIO_Remap1_CAN1 , ENABLE); /* 使能CAN1的重映射 */ #endif
#if Default_CAN_Interface == 1 RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE); /* 配置CAN信号接收引脚: RX */ GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU; /* GPIO配置为上拉输入模式 */ GPIO_Init(GPIOA, &GPIO_InitStructure); /* 配置CAN信号发送引脚: TX */ GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; /* 配置为复用推挽输出 */ GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; /* 设置GPIO最大速度 */ GPIO_Init(GPIOA, &GPIO_InitStructure); #endif /* 使能CAN外设时钟 */ RCC_APB1PeriphClockCmd(RCC_APB1Periph_CAN1, ENABLE); CAN_DeInit(CAN1); /* 复位CAN寄存器 */ CAN_StructInit(&CAN_InitStructure); /* 填充CAN参数结构体成员为缺省值 */ /* TTCM = time triggered communication mode ABOM = automatic bus-off management AWUM = automatic wake-up mode NART = no automatic retransmission RFLM = receive FIFO locked mode TXFP = transmit FIFO priority */ CAN_InitStructure.CAN_TTCM = DISABLE; /* 禁止时间触发模式(不生成时间戳), T */ CAN_InitStructure.CAN_ABOM = DISABLE; /* 禁止自动总线关闭管理 */ CAN_InitStructure.CAN_AWUM = DISABLE; /* 禁止自动唤醒模式 */ CAN_InitStructure.CAN_NART = DISABLE; /* 禁止仲裁丢失或出错后的自动重传功能 */ CAN_InitStructure.CAN_RFLM = DISABLE; /* 禁止接收FIFO加锁模式 */ CAN_InitStructure.CAN_TXFP = DISABLE; /* 禁止传输FIFO优先级 */ CAN_InitStructure.CAN_Mode = CAN_Mode_Normal; /* 设置CAN为正常工作模式 */ /* CAN 波特率 = RCC_APB1Periph_CAN / Prescaler / (SJW + BS1 + BS2); SJW = synchronisation_jump_width BS = bit_segment CAN 波特率 = 360000000 / 3 / (1 + 6 + 5) / = 1Mbps */ CAN_InitStructure.CAN_SJW = CAN_SJW_1tq; CAN_InitStructure.CAN_BS1 = CAN_BS1_6tq; CAN_InitStructure.CAN_BS2 = CAN_BS2_5tq; CAN_InitStructure.CAN_Prescaler = 3; CAN_Init(CAN1, &CAN_InitStructure); //滤波器序号,0-13,共14个滤波器 CAN_FilterInitStructure.CAN_FilterNumber = 0; //设置ID掩码模式 CAN_FilterInitStructure.CAN_FilterMode = CAN_FilterMode_IdMask; //32位滤波 CAN_FilterInitStructure.CAN_FilterScale = CAN_FilterScale_32bit; CAN_FilterInitStructure.CAN_FilterIdHigh = 0x0000; /* 掩码后ID的高16bit */ CAN_FilterInitStructure.CAN_FilterIdLow = 0x0000; /* 掩码后ID的低16bit */ CAN_FilterInitStructure.CAN_FilterMaskIdHigh = 0x0000; /* ID掩码值高16bit */ CAN_FilterInitStructure.CAN_FilterMaskIdLow = 0x0000; /* ID掩码值低16bit */ CAN_FilterInitStructure.CAN_FilterFIFOAssignment = CAN_FIFO0; CAN_FilterInitStructure.CAN_FilterActivation = ENABLE; CAN_FilterInit(&CAN_FilterInitStructure); }
static void can_NVIC_Config(void) { NVIC_InitTypeDef NVIC_InitStructure; NVIC_InitStructure.NVIC_IRQChannel = USB_LP_CAN1_RX0_IRQn; NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x01; NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x00; NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; NVIC_Init(&NVIC_InitStructure); /* CAN FIFO0 消息接收中断使能 */ CAN_ITConfig(CAN1, CAN_IT_FMP0, ENABLE); }
void USB_LP_CAN1_RX0_IRQHandler(void) { BaseType_t xHigherPriorityTaskWoken = pdFALSE; CAN_Receive(CAN1, CAN_FIFO0, &g_tCanRxMsg); if ((g_tCanRxMsg.StdId == 0x320) && (g_tCanRxMsg.IDE == CAN_ID_STD)&& (g_tCanRxMsg.DLC == 2)) { //将 Date[0]的数据压入队列1 xQueueSendFromISR(xQueue1, (void *)&(g_tCanRxMsg.Data[0]), &xHigherPriorityTaskWoken); //将 Date[1]的数据压入队列2 xQueueSendFromISR(xQueue2, (void *)&(g_tCanRxMsg.Data[1]), &xHigherPriorityTaskWoken);
/* 如果xHigherPriorityTaskWoken = pdTRUE,那么退出中断后切到当前最高优先级任务执行 */ portYIELD_FROM_ISR(xHigherPriorityTaskWoken); } }
|