|
Посылка по CAN в STM32F3 |
|
|
|
Aug 17 2018, 09:56
|
Профессионал
Группа: Участник
Сообщений: 1 778
Регистрация: 29-03-12
Пользователь №: 71 075
|
Настраиваю CAN CODE void CAN_Setup(void) { GPIO_InitTypeDef GPIO_InitStructure; NVIC_InitTypeDef NVIC_InitStructure; CAN_InitTypeDef CAN_InitStructure; CAN_FilterInitTypeDef CAN_FilterInitStructure; /* CAN GPIOs configuration **************************************************/
/* Enable GPIO clock */ RCC->AHBENR |= RCC_AHBPeriph_GPIOB;
/* Connect CAN pins to AF9 */ GPIO_PinAFConfig(GPIOB, GPIO_PinSource8, GPIO_AF_9); GPIO_PinAFConfig(GPIOB, GPIO_PinSource9, GPIO_AF_9); /* Configure CAN RX and TX pins */ GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8| GPIO_Pin_9; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP; GPIO_Init(CAN_GPIO_PORT, &GPIO_InitStructure);
/* NVIC configuration *******************************************************/ NVIC_InitStructure.NVIC_IRQChannel = USB_LP_CAN1_RX0_IRQn; NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x0; NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x0; NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; NVIC_Init(&NVIC_InitStructure); NVIC_InitStructure.NVIC_IRQChannel = CAN1_RX1_IRQn; NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x0; NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x0; NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; NVIC_Init(&NVIC_InitStructure); /* CAN configuration ********************************************************/ /* Enable CAN clock */ RCC_APB1PeriphClockCmd(RCC_APB1Periph_CAN1, ENABLE); /* CAN register init */ CAN_DeInit(CAN1); CAN_StructInit(&CAN_InitStructure);
// CAN cell init CAN_InitStructure.CAN_TTCM = DISABLE; CAN_InitStructure.CAN_ABOM = DISABLE; CAN_InitStructure.CAN_AWUM = DISABLE; CAN_InitStructure.CAN_NART = DISABLE; CAN_InitStructure.CAN_RFLM = DISABLE; CAN_InitStructure.CAN_TXFP = DISABLE; CAN_InitStructure.CAN_Mode = CAN_Mode_Normal;
/* CAN Baudrate = 1MBps (CAN clocked at 36 MHz) */ CAN_InitStructure.CAN_BS1 = CAN_BS1_9tq; CAN_InitStructure.CAN_BS2 = CAN_BS2_8tq; CAN_InitStructure.CAN_Prescaler = 2; CAN_InitStructure.CAN_SJW = CAN_SJW_1tq; //CAN_InitStructure.CAN_BS1 = CAN_BS1_3tq; //CAN_InitStructure.CAN_BS2 = CAN_BS2_5tq; //CAN_InitStructure.CAN_Prescaler = 39; //CAN_InitStructure.CAN_SJW = 2; CAN_Init(CANx, &CAN_InitStructure);
/* CAN filter init */ CAN_FilterInitStructure.CAN_FilterNumber = 0; CAN_FilterInitStructure.CAN_FilterMode = CAN_FilterMode_IdMask; CAN_FilterInitStructure.CAN_FilterScale = CAN_FilterScale_32bit; CAN_FilterInitStructure.CAN_FilterIdHigh = 0x0000; CAN_FilterInitStructure.CAN_FilterIdLow = 0x0000; CAN_FilterInitStructure.CAN_FilterMaskIdHigh = 0x0000; CAN_FilterInitStructure.CAN_FilterMaskIdLow = 0x0000; CAN_FilterInitStructure.CAN_FilterFIFOAssignment = 0; CAN_FilterInitStructure.CAN_FilterActivation = ENABLE; CAN_FilterInit(&CAN_FilterInitStructure); /* Enable FIFO 0 message pending Interrupt */ CAN_ITConfig(CANx, CAN_IT_FMP0, ENABLE); /* Enable FIFO 1 message pending Interrupt */ CAN_ITConfig(CANx, CAN_IT_FMP1, ENABLE); } Посылаю Код TxMessage.StdId = ( (0x100 *(i+1)) + CAN_COM_WHO_IS); TxMessage.DLC = 1; TxMessage.RTR = CAN_RTR_DATA; TxMessage.IDE = CAN_ID_STD; CAN_Transmit(CAN1, &TxMessage); В функции посылки - все мейлбоксы заняты - я попадаю в transmit_mailbox = CAN_TxStatus_NoMailBox; CODE uint8_t CAN_Transmit(CAN_TypeDef* CANx, CanTxMsg* TxMessage) { uint8_t transmit_mailbox = 0; /* Check the parameters */ assert_param(IS_CAN_ALL_PERIPH(CANx)); assert_param(IS_CAN_IDTYPE(TxMessage->IDE)); assert_param(IS_CAN_RTR(TxMessage->RTR)); assert_param(IS_CAN_DLC(TxMessage->DLC));
/* Select one empty transmit mailbox */ if ((CANx->TSR&CAN_TSR_TME0) == CAN_TSR_TME0) { transmit_mailbox = 0; } else if ((CANx->TSR&CAN_TSR_TME1) == CAN_TSR_TME1) { transmit_mailbox = 1; } else if ((CANx->TSR&CAN_TSR_TME2) == CAN_TSR_TME2) { transmit_mailbox = 2; } else { transmit_mailbox = CAN_TxStatus_NoMailBox; }
if (transmit_mailbox != CAN_TxStatus_NoMailBox) { /* Set up the Id */ CANx->sTxMailBox[transmit_mailbox].TIR &= TMIDxR_TXRQ; if (TxMessage->IDE == CAN_Id_Standard) { assert_param(IS_CAN_STDID(TxMessage->StdId)); CANx->sTxMailBox[transmit_mailbox].TIR |= ((TxMessage->StdId << 21) | \ TxMessage->RTR); } else { assert_param(IS_CAN_EXTID(TxMessage->ExtId)); CANx->sTxMailBox[transmit_mailbox].TIR |= ((TxMessage->ExtId << 3) | \ TxMessage->IDE | \ TxMessage->RTR); } /* Set up the DLC */ TxMessage->DLC &= (uint8_t)0x0000000F; CANx->sTxMailBox[transmit_mailbox].TDTR &= (uint32_t)0xFFFFFFF0; CANx->sTxMailBox[transmit_mailbox].TDTR |= TxMessage->DLC;
/* Set up the data field */ CANx->sTxMailBox[transmit_mailbox].TDLR = (((uint32_t)TxMessage->Data[3] << 24) | ((uint32_t)TxMessage->Data[2] << 16) | ((uint32_t)TxMessage->Data[1] << 8) | ((uint32_t)TxMessage->Data[0])); CANx->sTxMailBox[transmit_mailbox].TDHR = (((uint32_t)TxMessage->Data[7] << 24) | ((uint32_t)TxMessage->Data[6] << 16) | ((uint32_t)TxMessage->Data[5] << 8) | ((uint32_t)TxMessage->Data[4])); /* Request transmission */ CANx->sTxMailBox[transmit_mailbox].TIR |= TMIDxR_TXRQ; } return transmit_mailbox; } Если принимающая сторона не приняла мейлбокс он не освободился ?
Сообщение отредактировал IgorKossak - Aug 19 2018, 20:06
Причина редактирования: [codebox] для длинного кода, [code] - для короткого!
|
|
|
|
|
Aug 19 2018, 07:31
|
Профессионал
Группа: Участник
Сообщений: 1 778
Регистрация: 29-03-12
Пользователь №: 71 075
|
для отладки я изменил случай когда все мейлбоксы заняты Код else { transmit_mailbox = CAN_TxStatus_NoMailBox; //force pending messages to be sent anyway CANx->sTxMailBox[0].TIR |= TMIDxR_TXRQ; CANx->sTxMailBox[1].TIR |= TMIDxR_TXRQ; CANx->sTxMailBox[2].TIR |= TMIDxR_TXRQ; } я становлюсь скопом на ножку CAN_TX и не вижу никаких выходящих сигналов. что происходит? кто может объяснить?
|
|
|
|
|
Sep 17 2018, 05:27
|
Профессионал
Группа: Свой
Сообщений: 1 241
Регистрация: 15-11-05
Из: Челябинск
Пользователь №: 10 882
|
Цитата(Jenya7 @ Sep 17 2018, 09:59) Другая проблема. При приеме слейв через какое то время отсыхает. Я смотрю на ESR и вижу что TEC увеличивается при каждом принятии пакета, хотя данные пришли, иногда уменьшается но чаще увеличивается. Когда TEC = 0xFF прием отсыхает и LEC = 5. Ничего тут не напутано? На прием REC работает, на передачу TEC. Сдается мне, что физически что-то как-то не так подключено. Физический интерфейс имеется? Резистор в линии имеется?
|
|
|
|
|
Sep 17 2018, 10:11
|
Профессионал
Группа: Свой
Сообщений: 1 241
Регистрация: 15-11-05
Из: Челябинск
Пользователь №: 10 882
|
Цитата(Jenya7 @ Sep 17 2018, 11:04) CAN контроллер всегда слушает линию. Если вдруг в линии не то, что мы ожидали (коллизия), передатчик сообщает об ошибке. Доминатное состояние достигается за счет драйвера, рецессивное за счет нагрузки в линии. Для подтверждения приема служит бит ACK, его генерирует приемник, он контролируется передатчиком. Передатчик по-умолчанию будет посылать сообщение, пока его кто-нибудь не примет (или достигнется лимит TEC) Контроллер в STM32 можно настроить так, чтобы сообщение он принял, а АСК бит не выдал и даже не проконтролировал! Полагаю, где-то тут ваш случай. Передачу данных очень наглядно отображает даже дешевый логический анализатор.
|
|
|
|
|
Sep 17 2018, 10:35
|
Профессионал
Группа: Участник
Сообщений: 1 778
Регистрация: 29-03-12
Пользователь №: 71 075
|
Цитата(Alechek @ Sep 17 2018, 15:11) CAN контроллер всегда слушает линию. Если вдруг в линии не то, что мы ожидали (коллизия), передатчик сообщает об ошибке. Доминатное состояние достигается за счет драйвера, рецессивное за счет нагрузки в линии. Для подтверждения приема служит бит ACK, его генерирует приемник, он контролируется передатчиком. Передатчик по-умолчанию будет посылать сообщение, пока его кто-нибудь не примет (или достигнется лимит TEC)
Контроллер в STM32 можно настроить так, чтобы сообщение он принял, а АСК бит не выдал и даже не проконтролировал! Полагаю, где-то тут ваш случай.
Передачу данных очень наглядно отображает даже дешевый логический анализатор. с анализатором (USB-CAN Plus) мастер работает нормально. да и данными мастер-слейв вроде как обмениваются. бес его знает что там CANу не нравиться. я что то не нашел где там АСК отменить. я отменил бесперерывную посылку (NART =1). послал один раз и все, не фиг линию грузить.
Сообщение отредактировал Jenya7 - Sep 17 2018, 11:07
|
|
|
|
|
Sep 17 2018, 12:47
|
Местный
Группа: Участник
Сообщений: 356
Регистрация: 9-06-07
Пользователь №: 28 315
|
Цитата я что то не нашел где там АСК отменить Почитайте спецификацию на CAN?хотя бы в русском переводе.
--------------------
Хорошую систему делают из стандартных блоков нестандартно мыслящие инженеры.
|
|
|
|
|
Sep 17 2018, 18:48
|
Гуру
Группа: Свой
Сообщений: 2 724
Регистрация: 14-05-07
Из: Ярославль, Россия
Пользователь №: 27 702
|
Цитата(Jenya7 @ Sep 17 2018, 17:11) там регистров с гулькин нос. все биты просмотрел. Может, это Цитата Silent mode The bxCAN can be put in Silent mode by setting the SILM bit in the CAN_BTR register. In Silent mode, the bxCAN is able to receive valid data frames and valid remote frames, but it sends only recessive bits on the CAN bus and it cannot start a transmission. If the bxCAN has to send a dominant bit (ACK bit, overload flag, active error flag), the bit is rerouted internally so that the CAN Core monitors this dominant bit, although the CAN bus may remain in recessive state. Silent mode can be used to analyze the traffic on a CAN bus without affecting it by the transmission of dominant bits (Acknowledge Bits, Error Frames).
|
|
|
|
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|