(二)CAN通信协议代码-升级版

    技术2022-07-11  67

    CAN代码-升级版

    (1)can.c(2)can.h

    (1)can.c

    #define CAN_BUS_ENABLE 1 #define CAN_BUS_DISABLE 0 #define CAN2_FILTER_S 14 typedef struct __can_gpio_pin_t{ uint32_t pin_bit; uint32_t gpio_rcc; GPIO_TypeDef *gpio_port; }can_gpio_pin_t; typedef struct __send_status_t{ uint8_t mbox_s; }send_status_t; typedef struct _can_cfg_t{ uint8_t can_dev_id; uint8_t pin_map; uint8_t fifo_no; uint8_t filter_start; can_gpio_pin_t r_pin; can_gpio_pin_t t_pin; uint32_t can_rcc; CAN_TypeDef* can_ch; send_status_t txs; uint8_t irq; uint8_t it_flag; uint8_t res[2]; }can_cfg_t; /*--- 设置常用CAN波特率 ---*/ typedef struct __can_tq_t { uint16_t can_baudrate; uint16_t can_prescaler; uint8_t can_syn_jump_width; uint8_t can_time_bit_seg1; uint8_t can_time_bit_seg2; uint8_t can_res; }can_tq_t; static can_tq_t can_baud_array[] = { { 5, 400, CAN_SJW_2tq, CAN_BS1_9tq, CAN_BS2_8tq }, { 10, 200, CAN_SJW_2tq, CAN_BS1_9tq, CAN_BS2_8tq }, { 20, 100, CAN_SJW_2tq, CAN_BS1_9tq, CAN_BS2_8tq }, { 40, 50, CAN_SJW_2tq, CAN_BS1_9tq, CAN_BS2_8tq }, { 50, 40, CAN_SJW_2tq, CAN_BS1_9tq, CAN_BS2_8tq }, { 80, 25, CAN_SJW_2tq, CAN_BS1_9tq, CAN_BS2_8tq }, { 100, 20, CAN_SJW_2tq, CAN_BS1_9tq, CAN_BS2_8tq }, { 125, 16, CAN_SJW_2tq, CAN_BS1_9tq, CAN_BS2_8tq }, { 200, 10, CAN_SJW_2tq, CAN_BS1_9tq, CAN_BS2_8tq }, { 250, 36, CAN_SJW_2tq, CAN_BS1_2tq, CAN_BS2_1tq }, { 400, 5, CAN_SJW_2tq, CAN_BS1_9tq, CAN_BS2_8tq }, { 500, 4, CAN_SJW_2tq, CAN_BS1_9tq, CAN_BS2_8tq }, { 666, 3, CAN_SJW_2tq, CAN_BS1_9tq, CAN_BS2_8tq }, { 800, 11, CAN_SJW_2tq, CAN_BS1_2tq, CAN_BS2_1tq }, { 1000, 9, CAN_SJW_2tq, CAN_BS1_2tq, CAN_BS2_1tq }, { 0 }, }; static can_cfg_t can_cfg[CAN_DEV_CNT]={ [CAN_DEV1] = { .can_dev_id = CAN_DEV1, .fifo_no = CAN_Filter_FIFO0, .t_pin = { GPIO_Pin_12, RCC_APB2Periph_GPIOA, GPIOA }, // CAN1_TX PA12 .r_pin = { GPIO_Pin_11, RCC_APB2Periph_GPIOA, GPIOA }, // CAN1_RX PA11 .pin_map = 0, .can_rcc = RCC_APB1Periph_CAN1, .can_ch = CAN1, .filter_start = 0,//0~13 .irq = CAN1_RX0_IRQn, .it_flag = CAN_IT_FMP0, }, [CAN_DEV2] = { .can_dev_id = CAN_DEV2, .fifo_no = CAN_Filter_FIFO1, .t_pin = { GPIO_Pin_13, RCC_APB2Periph_GPIOB, GPIOB }, // CAN2_TX PB13 .r_pin = { GPIO_Pin_12, RCC_APB2Periph_GPIOB, GPIOB }, // CAN2_RX PB12 .pin_map = 0, .can_rcc = RCC_APB1Periph_CAN2, .can_ch = CAN2, .filter_start = CAN2_FILTER_S,//14~27 .irq = CAN2_RX1_IRQn, .it_flag = CAN_IT_FMP1, } }; static can_tq_t *__get_tp(int br) { int i = 0; while(can_baud_array[i].can_baudrate != 0){ if(can_baud_array[i].can_baudrate == br){ return &can_baud_array[i]; } i++; } return NULL; } static void __can_enable(int can_dev, u32 val) { if(can_dev == CAN_DEV1){ if(val == CAN_BUS_ENABLE){ _debug(SYS_INFO, "CAN_1 bus enable\n"); pp_ctrl_set(PIN_CAN1_STB,0);/*0 enable*/ }else{ pp_ctrl_set(PIN_CAN1_STB,1);/*1 disable*/ } }else if(can_dev == CAN_DEV2){ if(val == CAN_BUS_ENABLE){ _debug(SYS_INFO, "CAN_2 bus enable\n"); pp_ctrl_set(PIN_CAN2_STB,0);/*0 enable*/ }else{ pp_ctrl_set(PIN_CAN2_STB,1);/*1 disable*/ } } } int can_dev_init(int can_dev, int can_mode, int brp) { GPIO_InitTypeDef GPIO_InitStructure; CAN_InitTypeDef CAN_InitStructure; NVIC_InitTypeDef NVIC_InitStructure; can_cfg_t* pparam = &can_cfg[can_dev]; _debug(SYS_INFO, "CAN%d Init start\n", pparam->can_dev_id + 1); CAN_DeInit(pparam->can_ch); /* 使能GPIO、CANx外设复用功能时钟使能 */ RCC_APB1PeriphClockCmd(pparam->can_rcc, ENABLE); RCC_APB2PeriphClockCmd(pparam->r_pin.gpio_rcc | pparam->t_pin.gpio_rcc, ENABLE); // RCC_APB1PeriphClockCmd(RCC_APB1Periph_CAN1 | RCC_APB1Periph_CAN2, ENABLE); /* GPIO 复用功能初始化:Rx */ GPIO_InitStructure.GPIO_Pin = pparam->r_pin.pin_bit; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; GPIO_Init(pparam->r_pin.gpio_port, &GPIO_InitStructure); /* GPIO 复用功能初始化:Tx */ GPIO_InitStructure.GPIO_Pin = pparam->t_pin.pin_bit; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; // 复用推挽输出 GPIO_Init(pparam->t_pin.gpio_port, &GPIO_InitStructure); /* CAN 初始化 */ u8 ret_can; can_tq_t* pcan_baud = __get_tp(brp); if (pcan_baud == NULL) { _debug(SYS_INFO, "Setting BaudRate param is unqualified %d\n",brp); return -1; } CAN_InitStructure.CAN_Prescaler = pcan_baud->can_prescaler; CAN_InitStructure.CAN_SJW = pcan_baud->can_syn_jump_width; CAN_InitStructure.CAN_BS1 = pcan_baud->can_time_bit_seg1; CAN_InitStructure.CAN_BS2 = pcan_baud->can_time_bit_seg2; _debug(SYS_INFO, "BaudRate = %dKHZ, can_prescaler = %d, CAN_SJW_%dtq, CAN_BS1_%dtq, CAN_BS2_%dtq \n", pcan_baud->can_baudrate, pcan_baud->can_prescaler, pcan_baud->can_syn_jump_width + 1, pcan_baud->can_time_bit_seg1 + 1, pcan_baud->can_time_bit_seg2 + 1); CAN_InitStructure.CAN_Mode = can_mode; CAN_InitStructure.CAN_TTCM = DISABLE; //can_time_trigger_communication; CAN_InitStructure.CAN_ABOM = DISABLE; //can_auto_bus_off; CAN_InitStructure.CAN_AWUM = DISABLE; //can_auto_wakeup; CAN_InitStructure.CAN_NART = ENABLE; //can_no_auto_retransmit;(开启不自动重发) CAN_InitStructure.CAN_RFLM = DISABLE; //can_recv_fifo_lock; CAN_InitStructure.CAN_TXFP = DISABLE; //can_transmit_fifo_priority; ret_can = CAN_Init(pparam->can_ch, &CAN_InitStructure); if (ret_can == 0) { _debug(SYS_INFO, "CAN%d Initialize is failed \n", pparam->can_dev_id + 1); return -1; } #if 1 /* 接收中断参数配置 */ CAN_ITConfig(pparam->can_ch, pparam->it_flag, ENABLE); //FIFO0消息挂号中断允许 NVIC_InitStructure.NVIC_IRQChannel = pparam->irq; NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1; //抢占优先级1 NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1; //子优先级0 NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //接收IRQ通道使能 NVIC_Init(&NVIC_InitStructure); //初始化接收中断配置 #endif _debug(SYS_INFO, "CAN%d Init end\n", pparam->can_dev_id + 1); return 0; } int p_can_open(int can_dev,int bps) { int ret = can_dev_init(can_dev,CAN_Mode_Normal,bps); if(ret == 0){ __can_enable(can_dev,CAN_BUS_ENABLE); } return ret; } void p_can_close(int can_dev) { NVIC_InitTypeDef NVIC_InitStructure = {0}; can_cfg_t* pparam = &can_cfg[can_dev]; __can_enable(can_dev,CAN_BUS_DISABLE); CAN_ITConfig(pparam->can_ch, pparam->it_flag, DISABLE); NVIC_InitStructure.NVIC_IRQChannel = pparam->irq; NVIC_InitStructure.NVIC_IRQChannelCmd = DISABLE; NVIC_Init(&NVIC_InitStructure); CAN_DeInit(pparam->can_ch); } int p_can_read(int can_dev, can_msg_t* msg) { can_cfg_t* pparam = &can_cfg[can_dev]; CanRxMsg RxMessage; /* 判别是哪个接收邮箱有数据挂起 */ if (CAN_MessagePending(pparam->can_ch, CAN_FIFO0)) { CAN_Receive(pparam->can_ch, CAN_FIFO0, &RxMessage); } else if (CAN_MessagePending(pparam->can_ch, CAN_FIFO1)) { CAN_Receive(pparam->can_ch, CAN_FIFO1, &RxMessage); } else { _error("read error can msg"); return 0; } if(CAN_Id_Standard == RxMessage.IDE){ msg->id_type = CAN_ID_ST; msg->id = RxMessage.StdId; _debug(SYS_INFO, "CAN%d FIFO0 receive msg Std_id = 0x%x ...\n", pparam->can_dev_id + 1, RxMessage.StdId); }else{ msg->id_type = CAN_ID_EX; msg->id = RxMessage.ExtId; _debug(SYS_INFO, "CAN%d FIFO1 receive msg EXT_id = 0x%x ...\n", pparam->can_dev_id + 1, RxMessage.ExtId); } if(CAN_RTR_Data == RxMessage.RTR){ msg->id_frame = CAN_FR_DATA; }else{ msg->id_frame = CAN_FR_REMOTE; } msg->len = RxMessage.DLC; memcpy(msg->data,RxMessage.Data, RxMessage.DLC); return RxMessage.DLC; } int p_can_send(int can_dev, can_msg_t* msg) { can_cfg_t* pparam = &can_cfg[can_dev]; CanTxMsg TxMsg = {0}; if(msg->id_type == CAN_ID_ST){ TxMsg.IDE = CAN_Id_Standard; TxMsg.StdId = msg->id; }else{ TxMsg.IDE = CAN_Id_Extended; TxMsg.ExtId = msg->id; } if(msg->id_frame == CAN_FR_DATA){ TxMsg.RTR = CAN_RTR_Data; }else{ TxMsg.RTR = CAN_RTR_Remote; } TxMsg.DLC = msg->len; memcpy(TxMsg.Data,msg->data,TxMsg.DLC); pparam->txs.mbox_s = CAN_TxStatus_NoMailBox; uint8_t tx_mbox = CAN_Transmit(pparam->can_ch, &TxMsg); if (tx_mbox == CAN_TxStatus_NoMailBox) { _debug(SYS_INFO, "CAN Transmit Status is No MailBox\n"); return -1; } pparam->txs.mbox_s = tx_mbox; return 0; } int p_can_send_ok(int can_dev) { can_cfg_t* pparam = &can_cfg[can_dev]; if(pparam->txs.mbox_s == CAN_TxStatus_NoMailBox){ return -1; } if(CAN_TransmitStatus(pparam->can_ch, pparam->txs.mbox_s) == CAN_TxStatus_Failed){ return 0; } return 1; } #define CAN_ID_STD_STD CAN_ID_ST #define CAN_ID_EXT_EXT CAN_ID_EX #define CAN_ID_STD_EXT 2 #define CAN_ID_EXT_STD 3 static int __genc_ids(int format,uint32_t *ids,uint32_t *pout) { switch (format) { case CAN_ID_STD_STD: pout[0] = (ids[0] << 21) | CAN_Id_Standard; pout[1] = (ids[1] << 21) | CAN_Id_Standard; break; case CAN_ID_STD_EXT: pout[0] = (ids[0] << 21) | CAN_Id_Standard; pout[1] = (ids[1] << 3) | CAN_Id_Extended; break; case CAN_ID_EXT_STD: pout[0] = (ids[0] << 3) | CAN_Id_Extended; pout[1] = (ids[1] << 21) | CAN_Id_Standard; break; case CAN_ID_EXT_EXT: pout[0] = (ids[0] << 3) | CAN_Id_Extended; pout[1] = (ids[1] << 3) | CAN_Id_Extended; break; default: { return -1; } } return 0; } static int __p_can_set_filter_list(int filter_id, int fifo_no, int format, uint32_t id1, uint32_t id2) { CAN_FilterInitTypeDef CAN_FilterInitStructure = { 0 }; uint32_t in_ids[2] = {id1,id2}; uint32_t out_ids[2] = {0}; if(__genc_ids(format,in_ids,out_ids)){ _debug(SYS_INFO, "CAN geting id is failed \n"); return -1; } _debug(SYS_INFO, "filter_Id = 0x%x 0x%x, filter_number = %d, CAN_Filter_FIFO = %d\n",\ out_ids[0], out_ids[1], filter_id, fifo_no); CAN_FilterInitStructure.CAN_FilterNumber = filter_id; CAN_FilterInitStructure.CAN_FilterMode = CAN_FilterMode_IdList; CAN_FilterInitStructure.CAN_FilterScale = CAN_FilterScale_32bit; CAN_FilterInitStructure.CAN_FilterIdHigh = (out_ids[0] >> 16) & 0xffff; CAN_FilterInitStructure.CAN_FilterIdLow = out_ids[0] & 0xffff; CAN_FilterInitStructure.CAN_FilterMaskIdHigh = (out_ids[1] >> 16) & 0xffff; CAN_FilterInitStructure.CAN_FilterMaskIdLow = out_ids[1] & 0xffff; CAN_FilterInitStructure.CAN_FilterFIFOAssignment = fifo_no; CAN_FilterInitStructure.CAN_FilterActivation = ENABLE; CAN_FilterInit(&CAN_FilterInitStructure); return 0; } static int __p_can_set_filter_mask(int filter_id, int fifo_no, int format, uint32_t id, uint32_t mask) { CAN_FilterInitTypeDef CAN_FilterInitStructure = { 0 }; uint32_t in_ids[2] = {id,mask}; uint32_t out_ids[2] = {0}; if(__genc_ids(format,in_ids,out_ids)){ _debug(SYS_INFO, "CAN geting id is successed ...\n"); return -1; } _debug(SYS_INFO, "------ filter_Id = 0x%x 0x%x, filter_number = %d, CAN_Filter_FIFO = %d ----------\n",\ out_ids[0], out_ids[1], filter_id, fifo_no); CAN_FilterInitStructure.CAN_FilterNumber = filter_id; CAN_FilterInitStructure.CAN_FilterMode = CAN_FilterMode_IdMask; CAN_FilterInitStructure.CAN_FilterScale = CAN_FilterScale_32bit; CAN_FilterInitStructure.CAN_FilterIdHigh = (out_ids[0] >> 16) & 0xffff; CAN_FilterInitStructure.CAN_FilterIdLow = out_ids[0] & 0xffff; CAN_FilterInitStructure.CAN_FilterMaskIdHigh = (out_ids[1] >> 16) & 0xffff; CAN_FilterInitStructure.CAN_FilterMaskIdLow = out_ids[1] & 0xffff; CAN_FilterInitStructure.CAN_FilterFIFOAssignment = fifo_no; // CAN_Filter_FIFO0 CAN_FilterInitStructure.CAN_FilterActivation = ENABLE; CAN_FilterInit(&CAN_FilterInitStructure); return 0; } /* @filter_mode FILTER_LIST FILTER_MASK @format CAN_ID_ST CAN_ID_EX */ int p_can_set_filter(int can_dev, int filter_mode, int format, uint32_t* ids, int id_cnt) { int i; can_cfg_t* pparam = &can_cfg[can_dev]; uint32_t r_ids[28] = {0}; CAN_SlaveStartBank(CAN2_FILTER_S); if (id_cnt & 1) { //奇数 for(i = 0; i < id_cnt; i++){ r_ids[i] = ids[i]; } if(filter_mode == FILTER_LIST){ r_ids[i] = r_ids[i-1]; }else{ r_ids[i] = 0xffffffff; } id_cnt++; }else{ for(i = 0; i < id_cnt; i++){ r_ids[i] = ids[i]; } } if (filter_mode == FILTER_LIST) { for (i = 0; i < id_cnt / 2; i++) { __p_can_set_filter_list(pparam->filter_start + i, pparam->fifo_no, format, r_ids[2*i], r_ids[2*i + 1]); } } else { for (i = 0; i < id_cnt / 2; i++) { __p_can_set_filter_mask(pparam->filter_start + i, pparam->fifo_no, format, r_ids[2*i], r_ids[2*i + 1]); } } return 0; }

    (2)can.h

    #ifndef __p_can_h__ #define __p_can_h__ #if 0 .word CAN2_TX_IRQHandler .word CAN2_RX0_IRQHandler .word CAN2_RX1_IRQHandler .word CAN2_SCE_IRQHandler #define CAN_Id_Standard ((uint32_t)0x00000000) /*!< Standard Id */ #define CAN_Id_Extended ((uint32_t)0x00000004) /*!< Extended Id */ #endif typedef enum { CAN_DEV1, CAN_DEV2, CAN_DEV_CNT } CAN_DEV_E; #define CAN_ID_ST 0 //标准帧 #define CAN_ID_EX 1 //扩展帧 #define CAN_FR_DATA 0 #define CAN_FR_REMOTE 1 #define FILTER_LIST 0 #define FILTER_MASK 1 typedef struct _can_msg_t { uint8_t id_type; //0:标准帧 1:扩展帧 uint8_t id_frame; //0:数据帧 1:远程帧 uint8_t len; uint8_t res; uint32_t id; uint8_t data[8]; } can_msg_t; int can_dev_init(int can_dev, int can_mode, int brp); int p_can_open(int can_dev,int bps); void p_can_close(int can_dev); int p_can_read(int can_dev,can_msg_t *msg); int p_can_send(int can_dev,can_msg_t *msg); /* @filter_mode FILTER_LIST FILTER_MASK @format CAN_ID_ST CAN_ID_EX */ int p_can_set_filter(int can_dev, int filter_mode, int format, uint32_t* ids, int id_cnt); void p_can_task_start(int can_dev); void p_can_task_stop(int can_dev); void p_can_task(void); #endif
    Processed: 0.014, SQL: 9