#include "user_can.h" #include "user_config.h" #include "dip_sw.h" tmosTaskID user_can_task_id = INVALID_TASK_ID; static uint16_t user_can_task_process_event(uint8_t task_id, uint16_t events); static vUser_can_recv_data_func xRecv_data = NULL; static uint8_t can_node_id = 0x00; static user_can_work_s user_can_work = { .sendData = {0}, .sendSize = 0, .RxMessage = {0}, }; /******************************************************************************* * @函数名称 prvUser_can_gpio_Init * @函数说明 GPIO初始化 * @输入参数 无 * @输出参数 无 * @返回参数 无 *******************************************************************************/ static void prvUser_can_gpio_Init(void) { GPIO_InitTypeDef GPIO_InitStructure = {0}; CAN_InitTypeDef CAN_InitSturcture = {0}; NVIC_InitTypeDef NVIC_InitStructure; USER_CAN_GPIO_RCC_ENABLE; USER_CAN_RCC_ENABLE; #ifdef USER_CAN_REMAPCONFIG_ENABLE USER_CAN_REMAPCONFIG_ENABLE; #endif GPIO_InitStructure.GPIO_Pin = CAN_TX_PIN; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(CAN_TX_GPIO, &GPIO_InitStructure); GPIO_InitStructure.GPIO_Pin = CAN_RX_PIN; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(CAN_RX_GPIO, &GPIO_InitStructure); CAN_InitSturcture.CAN_TTCM = DISABLE; CAN_InitSturcture.CAN_ABOM = ENABLE; // 自动离线管理 CAN_InitSturcture.CAN_AWUM = ENABLE; // 自动唤醒 CAN_InitSturcture.CAN_NART = ENABLE; // 自动重传 CAN_InitSturcture.CAN_RFLM = DISABLE; // 不锁定接收FIFO CAN_InitSturcture.CAN_TXFP = ENABLE; // 优先级由标识符决定 CAN_InitSturcture.CAN_Mode = CAN_Mode_Normal; // 正常模式 CAN_InitSturcture.CAN_SJW = CAN_SJW_1tq; switch(user_config_param.can_baud) { case CAN_BAUD_100:{ CAN_InitSturcture.CAN_BS1 = CAN_BS1_5tq; CAN_InitSturcture.CAN_BS2 = CAN_BS2_2tq; CAN_InitSturcture.CAN_Prescaler = 60; }break; case CAN_BAUD_150:{ CAN_InitSturcture.CAN_BS1 = CAN_BS1_5tq; CAN_InitSturcture.CAN_BS2 = CAN_BS2_2tq; CAN_InitSturcture.CAN_Prescaler = 40; }break; case CAN_BAUD_200:{ CAN_InitSturcture.CAN_BS1 = CAN_BS1_5tq; CAN_InitSturcture.CAN_BS2 = CAN_BS2_2tq; CAN_InitSturcture.CAN_Prescaler = 30; }break; case CAN_BAUD_250:{ CAN_InitSturcture.CAN_BS1 = CAN_BS1_5tq; CAN_InitSturcture.CAN_BS2 = CAN_BS2_2tq; CAN_InitSturcture.CAN_Prescaler = 24; }break; case CAN_BAUD_300:{ CAN_InitSturcture.CAN_BS1 = CAN_BS1_5tq; CAN_InitSturcture.CAN_BS2 =CAN_BS2_2tq; CAN_InitSturcture.CAN_Prescaler = 20; }break; case CAN_BAUD_400:{ CAN_InitSturcture.CAN_BS1 = CAN_BS1_5tq; CAN_InitSturcture.CAN_BS2 = CAN_BS2_2tq; CAN_InitSturcture.CAN_Prescaler = 15; }break; case CAN_BAUD_500:{ CAN_InitSturcture.CAN_BS1 = CAN_BS1_5tq; CAN_InitSturcture.CAN_BS2 = CAN_BS2_2tq; CAN_InitSturcture.CAN_Prescaler = 12; }break; case CAN_BAUD_666:{ CAN_InitSturcture.CAN_BS1 = CAN_BS1_5tq; CAN_InitSturcture.CAN_BS2 = CAN_BS2_2tq; CAN_InitSturcture.CAN_Prescaler = 9; }break; case CAN_BAUD_800:{ CAN_InitSturcture.CAN_BS1 = CAN_BS1_7tq; CAN_InitSturcture.CAN_BS2 = CAN_BS2_2tq; CAN_InitSturcture.CAN_Prescaler = 6; }break; case CAN_BAUD_1000: default:{ CAN_InitSturcture.CAN_BS1 = CAN_BS1_5tq; CAN_InitSturcture.CAN_BS2 = CAN_BS2_2tq; CAN_InitSturcture.CAN_Prescaler = 6; }break; } CAN_Init(CAN_TYPE, &CAN_InitSturcture); // 配置CAN接收中断 NVIC_InitStructure.NVIC_IRQChannel = USB_LP_CAN1_RX0_IRQn; NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1; NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1; NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; NVIC_Init(&NVIC_InitStructure); } /******************************************************************************* * @函数名称 prvUser_can_filter * @函数说明 设置过滤 * @输入参数 无 * @输出参数 无 * @返回参数 无 *******************************************************************************/ static void prvUser_can_filter(void) { CAN_FilterInitTypeDef CAN_FilterInitstructure = {0}; CAN_FilterInitstructure.CAN_FilterNumber = 0; CAN_FilterInitstructure.CAN_FilterMode = CAN_FilterMode_IdMask; CAN_FilterInitstructure.CAN_FilterScale = CAN_FilterScale_32bit; CAN_FilterInitstructure.CAN_FilterIdHigh = ((CAN_SDO_RX + can_node_id) << 5); CAN_FilterInitstructure.CAN_FilterIdLow = 0x0000; CAN_FilterInitstructure.CAN_FilterMaskIdHigh = 0x7FF << 5; CAN_FilterInitstructure.CAN_FilterMaskIdLow = 0x0000; CAN_FilterInitstructure.CAN_FilterFIFOAssignment = CAN_Filter_FIFO0; CAN_FilterInitstructure.CAN_FilterActivation = ENABLE; CAN_FilterInit(&CAN_FilterInitstructure); } /********************************************************************* * @fn CAN_Send_Msg * * @brief CAN Transmit function. * * @param msg - Transmit data buffer. * len - Data length. * * @return 0 - Send successful. * 1 - Send failed. */ uint8_t ucCAN_Send_Msg(uint8_t *msg, uint8_t len) { uint8_t mbox; if(len > 8) { return 0; } CanTxMsg CanTxStructure; CanTxStructure.StdId = CAN_SDO_TX + can_node_id; CanTxStructure.IDE = CAN_Id_Standard; CanTxStructure.RTR = CAN_RTR_Data; CanTxStructure.DLC = len; for(uint8_t i = 0; i < len; i++) { CanTxStructure.Data[i] = msg[i]; } mbox = CAN_Transmit(CAN1, &CanTxStructure); uint16_t timeout = 0; while((CAN_TransmitStatus(CAN_TYPE, mbox) != CAN_TxStatus_Ok) && (timeout < 0xFFF)) { timeout++; } if(timeout == 0xFFF) { return 0; } else { return len; } } /******************************************************************************* * @函数名称 user_charge_task_process_event * @函数说明 task的event处理回调函数,需要在注册task时候,传进去 * @输入参数 task_id:任务ID events:事件 * @输出参数 无 * @返回参数 无 *******************************************************************************/ static uint16_t user_can_task_process_event(uint8_t task_id, uint16_t events) { //event 处理 if(events & (1 << CAN_QUEUE_SEND)) { ucCAN_Send_Msg(user_can_work.sendData, user_can_work.sendSize); return (events ^ (1 << CAN_QUEUE_SEND)); //异或的方式清除该事件运行标志,并返回未运行的事件标志 } if(events & (1 << CAN_QUEUE_RECIEVE)) { // 从FIFO0读取消息 // PRINT("STDID=0x%X,DLC=%d\n",user_can_work.RxMessage.StdId, user_can_work.RxMessage.DLC); // PRINT("DATA=%02X %02X %02X %02X %02X %02X %02X %02X\n", user_can_work.RxMessage.Data[0], user_can_work.RxMessage.Data[1], // user_can_work.RxMessage.Data[2], user_can_work.RxMessage.Data[3], // user_can_work.RxMessage.Data[4], user_can_work.RxMessage.Data[5], // user_can_work.RxMessage.Data[6], user_can_work.RxMessage.Data[6]); if(xRecv_data != NULL) { xRecv_data(user_can_work.RxMessage.Data, user_can_work.RxMessage.DLC); } return (events ^ (1 << CAN_QUEUE_RECIEVE)); //异或的方式清除该事件运行标志,并返回未运行的事件标志 } if(events & (1 << CAN_QUEUE_TIME)) { ucCAN_Send_Msg(user_can_work.sendData, user_can_work.sendSize); return (events ^ (1 << CAN_QUEUE_TIME)); //异或的方式清除该事件运行标志,并返回未运行的事件标志 } dipsw_task_process_event(task_id, events); return 0; } /******************************************************************************* * @函数名称 set_user_can_Queue * @函数说明 开始can任务event * @输入参数 无 * @输出参数 无 * @返回参数 无 *******************************************************************************/ static void set_user_can_Queue(USER_CAN_QUEUE_TYPE type) { if(can_node_id > 0) { bStatus_t stat = tmos_start_task(user_can_task_id, (1 << type), MS1_TO_SYSTEM_TIME(1)); } } /******************************************************************************* * @函数名称 vUser_can_send_data * @函数说明 惨数据发送 * @输入参数 data:数据 * size:长度 * @输出参数 无 * @返回参数 无 *******************************************************************************/ void vUser_can_send_data(uint8_t *data, uint8_t size) { if(size <= 8) { memcpy(user_can_work.sendData, data, size); user_can_work.sendSize = size; set_user_can_Queue(CAN_QUEUE_SEND); } } /******************************************************************************* * @函数名称 vUser_can_recv_data * @函数说明 can数据接收 * @输入参数 无 * @输出参数 无 * @返回参数 无 *******************************************************************************/ void vUser_can_recv_data(CanRxMsg *RxMessage) { memcpy((void *)&(user_can_work.RxMessage), (void *)RxMessage, sizeof(CanRxMsg)); set_user_can_Queue(CAN_QUEUE_RECIEVE); } /******************************************************************************* * @函数名称 vUser_can_set_recv_data_func * @函数说明 设置CAN接收数据上报回调函数 * @输入参数 func:函数指针 * @输出参数 无 * @返回参数 无 *******************************************************************************/ void vUser_can_set_recv_data_func(vUser_can_recv_data_func func) { xRecv_data = func; } /******************************************************************************* * @函数名称 vUser_can_set_addr * @函数说明 设置CAN Node id * @输入参数 无 * @输出参数 无 * @返回参数 无 *******************************************************************************/ void vUser_can_set_addr(uint8_t addr) { if(addr != can_node_id) { can_node_id = addr; PRINT("Node ID=%d\n", can_node_id); if(addr == 0) { CAN_ITConfig(CAN_TYPE, CAN_IT_FMP0, DISABLE); } else{ prvUser_can_filter(); CAN_ITConfig(CAN_TYPE, CAN_IT_FMP0, ENABLE); // 启用CAN接收 // bStatus_t stat = tmos_start_reload_task(user_can_task_id, (1 << CAN_QUEUE_TIME), MS1_TO_SYSTEM_TIME(3000)); } } } /******************************************************************************* * @函数名称 user_charge_init * @函数说明 Charge初始化 * @输入参数 无 * @输出参数 无 * @返回参数 无 *******************************************************************************/ void vUser_can_init(void) { prvUser_can_gpio_Init(); user_can_task_id = TMOS_ProcessEventRegister(user_can_task_process_event); PRINT("user_can_task_id=%d\n", user_can_task_id); }