ViKo 1 4 ноября, 2018 Опубликовано 4 ноября, 2018 · Жалоба Может, ack не стирается где-то когда-то после обработки принятого? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Сергей Борщ 119 4 ноября, 2018 Опубликовано 4 ноября, 2018 · Жалоба 36 минут назад, jenya7 сказал: но от компайлера за 5 кусков зеленых ждешь чего то большего. Похоже, вы ожидаете от него телепатии? Как и от нас, выкладывая по капельке кусочки кода, а то и вовсе описывая его на словах. Увы, это не сработает ни в первом, ни во втором случае. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
jenya7 0 4 ноября, 2018 Опубликовано 4 ноября, 2018 · Жалоба 6 minutes ago, Сергей Борщ said: Похоже, вы ожидаете от него телепатии? Как и от нас, выкладывая по капельке кусочки кода, а то и вовсе описывая его на словах. Увы, это не сработает ни в первом, ни во втором случае. Все просто. Через мастера пишу читаю параметры слейвов. uint32_t COM_MotParam(uint32_t argc, char** args) { uint8_t data[8]; uint32_t mot_num = 0, size = 0, ack = 0, i; uint32_t timeout; int32_t value; uint8_t opcode; mot_num = atoi(args[1]); if ((mot_num > 0) && (mot_num < MAX_MOTORS)) mot_num--; else return MSG_INV_ARG; opcode = command.var_offset; if (argc > 1) //param mot_num val { size = 2; value = atoi(args[2]); data[0] = value; data[1] = value>>8; } //send parameter to slave CAN_TX(motor_rt_params[mot_num].mot_id, opcode, data, size); timeout = TIM_GetTimeStamp_ms(TIM6) + 1000; //wait for response while (1) { ack = CAN_RX_Master(); if (ack == 1) { for (i = 0; i < 10000; i++) ; //to fix the problem value = (RxMessage.Data[1] << 8) | RxMessage.Data[0]; Parser_SendInt(COM_USART, value, 1, 0); break; } else { if (TIM_GetTimeStamp_ms(TIM6) > timeout) { Parser_SendString(COM_USART, "No response\n", 0); break; } } } return MSG_OK; } если ack = CAN_RX_Master(); вернул мне 1 - значит призошел ивент can_message_received = 1 uint32_t CAN_RX_Master(void) { uint32_t mot_num; uint32_t opcode; uint32_t pos; uint32_t ack = 0; if (can_message_received) { can_message_received = 0; //тут много кейсов - зашел в кейс - ack = 1 } return ack; } и значит данные пришли. так с какого перепугу value = (RxMessage.Data[1] << 8) | RxMessage.Data[0]; дает мне 0? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Arlleex 131 4 ноября, 2018 Опубликовано 4 ноября, 2018 (изменено) · Жалоба В раздел "Предлагаю работу" лучше напишите. Хотя, в общем-то, 5 тысяч зеленых, которые Вы выложили за среду, лучше мне заплатите. Я IAR крякну, и избавлю Вас от этих злополучных проблем со средой программирования =D P.S. can_message_received как объявлен? Изменено 4 ноября, 2018 пользователем Arlleex Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Integro 0 4 ноября, 2018 Опубликовано 4 ноября, 2018 · Жалоба 43 minutes ago, jenya7 said: Все просто Это не всё! Что делаем CAN_Receive, чья это функция? Где заполняется RxMessage, где еще испольуется и как обьявен? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
jenya7 0 4 ноября, 2018 Опубликовано 4 ноября, 2018 · Жалоба 16 minutes ago, Integro said: Это не всё! Что делаем CAN_Receive, чья это функция? Где заполняется RxMessage, где еще испольуется и как обьявен? я приводил уже выше void USB_LP_CAN1_RX0_IRQHandler(void) { can_message_received = 1; CAN_Receive(CAN1, CAN_FIFO0, &RxMessage); } Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Integro 0 4 ноября, 2018 Опубликовано 4 ноября, 2018 · Жалоба Это я видел, по этому и спрашиваю: Что делаем в CAN_Receive, чья это функция? Как кстати настроен CAN? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
jenya7 0 4 ноября, 2018 Опубликовано 4 ноября, 2018 · Жалоба 3 minutes ago, Integro said: Это я видел, по этому и спрашиваю: Что делаем в CAN_Receive, чья это функция? Как кстати настроен CAN? это стандартная библиотечная функция. с КАНом проблем нет. данные приходят. если я остановлюсь дебагером в CAN_Receive я их вижу. проблема что по флагу переменная не обновляется. if (ack == 1) { value = (RxMessage.Data[1] << 8) | RxMessage.Data[0]; } Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Integro 0 4 ноября, 2018 Опубликовано 4 ноября, 2018 · Жалоба 4 hours ago, jenya7 said: for (i = 0; i < 10000; i++) ; Вот эта вот задержка, по факту, необходима для того, чтобы "магическим" образом в RxMessage.Data появилось сообщение. Учитывая то что данные туда ложатся одним махом (а не по байтно, как я предполагал ранее), остается только три варианта: Вариант того что приходит прерывание без данных, как пример прерывание с ошибкой или о том то фифо пусто, нужно проверять статусные флаги в обработчике Вариант того что реально приходят два сообщения, но благодаря этой задержке, первое сообщение "теряется". Вариант того что ack = CAN_RX_Master(); возвращает ack неверно и по совпадению каких-то обстоятельств, рашьне на пару us чем нужно :) IAR тут точно ни при чем!)) Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Arlleex 131 4 ноября, 2018 Опубликовано 4 ноября, 2018 · Жалоба Повторюсь. Флаг can_message_received как объявлен? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
jenya7 0 5 ноября, 2018 Опубликовано 5 ноября, 2018 · Жалоба 14 hours ago, Arlleex said: Повторюсь. Флаг can_message_received как объявлен? глобальная переменная volatile uint32_t can_message_received Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Arlleex 131 5 ноября, 2018 Опубликовано 5 ноября, 2018 (изменено) · Жалоба 2 hours ago, jenya7 said: глобальная переменная volatile uint32_t can_message_received Ну тогда обрабатывайте все исключения и смотрите. Я не помню зачем, но у меня в исходниках в обработчике прерывания по заполнению FIFO следующий код: CAN_Receive(CAN1, CAN_FIFO0, &CANRxMessage); CAN_FIFORelease(CAN1, CAN_FIFO0); Не совсем помню, для чего нужен Release, вроде как для того, чтобы уведомить приемный автомат о том, что сообщение было обработано и нужно следующие протолкнуть по FIFO. Изменено 5 ноября, 2018 пользователем Arlleex Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
jenya7 0 5 ноября, 2018 Опубликовано 5 ноября, 2018 (изменено) · Жалоба 41 minutes ago, Arlleex said: Ну тогда обрабатывайте все исключения и смотрите. Я не помню зачем, но у меня в исходниках в обработчике прерывания по заполнению FIFO следующий код: CAN_Receive(CAN1, CAN_FIFO0, &CANRxMessage); CAN_FIFORelease(CAN1, CAN_FIFO0); Не совсем помню, для чего нужен Release, вроде как для того, чтобы уведомить приемный автомат о том, что сообщение было обработано и нужно следующие протолкнуть по FIFO. Release да нужен но он есть внутри void CAN_Receive(CAN_TypeDef* CANx, uint8_t FIFONumber, CanRxMsg* RxMessage) { /* Check the parameters */ assert_param(IS_CAN_ALL_PERIPH(CANx)); assert_param(IS_CAN_FIFO(FIFONumber)); /* Get the Id */ RxMessage->IDE = (uint8_t)0x04 & CANx->sFIFOMailBox[FIFONumber].RIR; if (RxMessage->IDE == CAN_Id_Standard) { RxMessage->StdId = (uint32_t)0x000007FF & (CANx->sFIFOMailBox[FIFONumber].RIR >> 21); } else { RxMessage->ExtId = (uint32_t)0x1FFFFFFF & (CANx->sFIFOMailBox[FIFONumber].RIR >> 3); } RxMessage->RTR = (uint8_t)0x02 & CANx->sFIFOMailBox[FIFONumber].RIR; /* Get the DLC */ RxMessage->DLC = (uint8_t)0x0F & CANx->sFIFOMailBox[FIFONumber].RDTR; /* Get the FMI */ RxMessage->FMI = (uint8_t)0xFF & (CANx->sFIFOMailBox[FIFONumber].RDTR >> 8); /* Get the data field */ RxMessage->Data[0] = (uint8_t)0xFF & CANx->sFIFOMailBox[FIFONumber].RDLR; RxMessage->Data[1] = (uint8_t)0xFF & (CANx->sFIFOMailBox[FIFONumber].RDLR >> 8); RxMessage->Data[2] = (uint8_t)0xFF & (CANx->sFIFOMailBox[FIFONumber].RDLR >> 16); RxMessage->Data[3] = (uint8_t)0xFF & (CANx->sFIFOMailBox[FIFONumber].RDLR >> 24); RxMessage->Data[4] = (uint8_t)0xFF & CANx->sFIFOMailBox[FIFONumber].RDHR; RxMessage->Data[5] = (uint8_t)0xFF & (CANx->sFIFOMailBox[FIFONumber].RDHR >> 8); RxMessage->Data[6] = (uint8_t)0xFF & (CANx->sFIFOMailBox[FIFONumber].RDHR >> 16); RxMessage->Data[7] = (uint8_t)0xFF & (CANx->sFIFOMailBox[FIFONumber].RDHR >> 24); /* Release the FIFO */ /* Release FIFO0 */ if (FIFONumber == CAN_FIFO0) { CANx->RF0R |= CAN_RF0R_RFOM0; } /* Release FIFO1 */ else /* FIFONumber == CAN_FIFO1 */ { CANx->RF1R |= CAN_RF1R_RFOM1; } } у меня разрешено только одно прерывание - FIFO message pending Interrupt Изменено 5 ноября, 2018 пользователем jenya7 Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Integro 0 5 ноября, 2018 Опубликовано 5 ноября, 2018 · Жалоба 1 hour ago, jenya7 said: у меня разрешено только одно прерывание - FIFO message pending Interrupt Не видел, не верю!) Гипотезу с лишним прерыванием легко проверить вставкой счетчика в обработчик. А вообще, мне кажется, должно быть так: void CAN1_RX0_IRQHandler(void) { if (CAN_GetITStatus(CAN1,CAN_IT_FMP0)!= RESET) { CAN_ClearITPendingBit(CAN1, CAN_IT_FF0); CAN_ClearFlag(CAN1, CAN_FLAG_FF0); CAN_Receive(CAN1, CAN_FIFO0, &RxMessage); can_message_received = 1; } } Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
jenya7 0 5 ноября, 2018 Опубликовано 5 ноября, 2018 (изменено) · Жалоба 1 hour ago, Integro said: Не видел, не верю!) Гипотезу с лишним прерыванием легко проверить вставкой счетчика в обработчик. А вообще, мне кажется, должно быть так: void CAN1_RX0_IRQHandler(void) { if (CAN_GetITStatus(CAN1,CAN_IT_FMP0)!= RESET) { CAN_ClearITPendingBit(CAN1, CAN_IT_FF0); CAN_ClearFlag(CAN1, CAN_FLAG_FF0); CAN_Receive(CAN1, CAN_FIFO0, &RxMessage); can_message_received = 1; } } спасибо. проверю. Изменено 5 ноября, 2018 пользователем jenya7 Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться