|
Помогите разобраться с CANом в stm32 |
|
|
|
May 7 2012, 08:13
|
Частый гость
 
Группа: Участник
Сообщений: 89
Регистрация: 3-01-11
Пользователь №: 61 997

|
Помогите, опжалуйста, разобраться с CANом для stm32. Постановка задачи следующая. Есть отладочная плата sk-mstm32f107 и самодельная плата на основе stm32f103vet. Роль первой платы - мастер, второй- слэйв. Пробую на основе исходников библиотеки StdPeriphLib написать программку, которая просто передаст хоть что-то на вторую платку. Не получается. Согласно документации на отладочную плату на stm32f107: CAN_TX1=GPIOD_1; CAN_RX1=GPIOD_0; Плата слэйва на stm32f103vet: CAN_TX=GPIOA_12; CAN_RX=GPIOA_11; Прилагаю файлы 2 проектов с настройками CANов. Подскажите, что я не так делаю и почему не срабатывает прерывание у слэйва по получению данных. P.S.(edited) Внесла исправления. Добавила в функцию Init_GPIO_CAN проекта для мастера stm32f107 ремап: Код GPIO_PinRemapConfig(GPIO_Remap2_CAN1, ENABLE); Но все равно прерывания по получению не срабатывают.
Сообщение отредактировал batisto4ka - May 7 2012, 10:30
|
|
|
|
|
May 7 2012, 09:47
|
Участник

Группа: Участник
Сообщений: 22
Регистрация: 12-08-11
Пользователь №: 66 698

|
Стандартной библиотекой не пользовался, сказать про неё немогу. 1 - проверте акновледжит ли сообщения принимающая плата, осцилом посмотрите на ногу CAN TX, должен быть акновледж на любое сообщение. 2 - проверте настройки фильтров приёмника и ID отправляемого сообщения, может просто не пропускать фильтр
|
|
|
|
|
May 7 2012, 11:06
|
Частый гость
 
Группа: Участник
Сообщений: 89
Регистрация: 3-01-11
Пользователь №: 61 997

|
Цитата(aba @ May 7 2012, 13:47)  Стандартной библиотекой не пользовался, сказать про неё немогу. 1 - проверте акновледжит ли сообщения принимающая плата, осцилом посмотрите на ногу CAN TX, должен быть акновледж на любое сообщение. 2 - проверте настройки фильтров приёмника и ID отправляемого сообщения, может просто не пропускать фильтр Нога Tx передатчика дрыгается, у приемника оотвественно дрыгается Rx. Настройки фильтров для обоих проектов одинаковые: Код 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); Может, обработчик прерывания неправильно описан или сами прерывания настроены неправильно, или нет тот флаг проверяется. Там этих флагов черт ногу сломит. Объясните, кому не лень, пожалуйста, помогите разобраться.
Сообщение отредактировал batisto4ka - May 7 2012, 11:34
|
|
|
|
|
May 7 2012, 11:55
|
Участник

Группа: Участник
Сообщений: 53
Регистрация: 27-10-08
Пользователь №: 41 225

|
1. Неплохо было бы увидеть принципиальные схемы обоих схемы.
2. Скорости большие - проверьте дальность проводов, и наличие терминирующих резисторов (ну или просто уменьшите скорости)
3. Запустите отправку пакета и посмотрите состояние CAN. Вас должен интересовать регистр ESR, а в нем поле LEC - в нем содержится код последней ошибки. Узнаете на чем конкретно валится передача от Мастера.
4. Гляньте осцилографом (а лучше лог.анализатором, у того же USBee есть расшифровка CAN), чего вообще творится на шине.
5. Банальное. Посмотрите на полярность проводов (CAN полярен) и одинаковые ли у вас микросхемы физического уровня.
|
|
|
|
|
May 7 2012, 11:56
|
Участник

Группа: Участник
Сообщений: 22
Регистрация: 12-08-11
Пользователь №: 66 698

|
это моя инициализация CANа, правда для STM32F2xx CODE // enable clock to CANs RCC->APB1ENR |= RCC_APB1ENR_CAN1EN; RCC->APB1ENR |= RCC_APB1ENR_CAN2EN;
CAN1->MCR |= CAN_MCR_RESET; CAN2->MCR |= CAN_MCR_RESET;
// configure CANs CANEnterConfig();
CAN1->MCR |= CAN_MCR_NART;//CAN_MCR_TXFP; CAN2->MCR |= CAN_MCR_NART;//CAN_MCR_TXFP;
switch (baud_rate) { case CAN_BR_50KBPS: BrpVal = (FPBA1 / (TS1VAL + 1 + TS2VAL + 1 + 1)) / 50000UL; break; case CAN_BR_125KBPS: BrpVal = (FPBA1 / (TS1VAL + 1 + TS2VAL + 1 + 1)) / 125000UL; break; case CAN_BR_250KBPS: BrpVal = (FPBA1 / (TS1VAL + 1 + TS2VAL + 1 + 1)) / 250000UL; break; case CAN_BR_500KBPS: BrpVal = (FPBA1 / (TS1VAL + 1 + TS2VAL + 1 + 1)) / 500000UL; break; case CAN_BR_1000KBPS: BrpVal = (FPBA1 / (TS1VAL + 1 + TS2VAL + 1 + 1)) / 1000000UL; break; default: break; }
CAN1->BTR = (SJWVAL << 24) | (TS2VAL << 20) | (TS1VAL << 16) | (BrpVal - 1); CAN2->BTR = (SJWVAL << 24) | (TS2VAL << 20) | (TS1VAL << 16) | (BrpVal - 1);
CAN1->IER = CAN_IER_FMPIE0; CAN2->IER = CAN_IER_FMPIE0;
CAN1->MCR &= ~CAN_MCR_SLEEP; CAN2->MCR &= ~CAN_MCR_SLEEP;
CANExitConfig();
static void CANExitConfig(void) { CAN1->MCR &= ~CAN_MCR_INRQ; // wait while CAN entered to initialization mode while (CAN1->MSR & CAN_MSR_INAK) ; CAN2->MCR &= ~CAN_MCR_INRQ; // wait while CAN entered to initialization mode while (CAN2->MSR & CAN_MSR_INAK) ; }
static void CANEnterConfig(void) { // CAN to initialization mode CAN1->MCR |= CAN_MCR_INRQ;
// wait while CAN entered to initialization mode while (!(CAN1->MSR & CAN_MSR_INAK)) ; // CAN to initialization mode CAN2->MCR |= CAN_MCR_INRQ; // wait while CAN entered to initialization mode while (!(CAN2->MSR & CAN_MSR_INAK)) ; } вот так инициализирую фильтры Код // begin of configuring filters CANEnterConfig();
CAN1->FMR |= CAN_FMR_FINIT; // set Initialization mode for filter banks CAN1->FMR &= ~(0x3F << 8); CAN1->FMR |= (0x0E << 8); CAN1->FA1R &= ~(uint32_t) (1 << filterIndex); // deactivate filter
// initialize filter CAN1->FS1R |= (uint32_t) (1 << filterIndex);// set 32-bit scale configuration CAN1->FM1R &= ~(uint32_t) (1 << filterIndex);// set 2 32-bit identifier list mode
CAN1->sFilterRegister[filterIndex].FR1 = CAN_msgId; // 32-bit identifier CAN1->sFilterRegister[filterIndex].FR2 = CAN_msgMask; // 32-bit identifier CAN1->FFA1R &= ~(uint32_t) (1 << filterIndex); // assign filter to FIFO 0 CAN1->FA1R |= (uint32_t) (1 << filterIndex); // activate filter CAN1->FMR &= ~CAN_FMR_FINIT; // reset Initialization mode for filter banks
CANExitConfig(); прерывания, впринципе, написаны как и у Вас
Сообщение отредактировал IgorKossak - May 7 2012, 17:37
Причина редактирования: [codebox] для длинного кода
|
|
|
|
|
May 7 2012, 12:16
|
Участник

Группа: Участник
Сообщений: 53
Регистрация: 27-10-08
Пользователь №: 41 225

|
CODE void CAN_Initialization (uint16_t speed) { CAN_InitTypeDef CAN_InitStructure; CAN_FilterInitTypeDef CAN_FilterInitStructure;
CAN_DBGFreeze(CAN1,DISABLE); CAN_DBGFreeze(CAN2,DISABLE);
CAN_DeInit(CAN1); CAN_DeInit(CAN2); CAN_InitStructure.CAN_TTCM = DISABLE; CAN_InitStructure.CAN_ABOM = ENABLE; CAN_InitStructure.CAN_AWUM = DISABLE; CAN_InitStructure.CAN_NART = DISABLE; CAN_InitStructure.CAN_RFLM = DISABLE; CAN_InitStructure.CAN_TXFP = ENABLE; CAN_InitStructure.CAN_Mode = CAN_Mode_Normal; CAN_InitStructure.CAN_SJW = CAN_SJW_1tq; CAN_InitStructure.CAN_BS1 = CAN_BS1_16tq; CAN_InitStructure.CAN_BS2 = CAN_BS2_8tq; switch (speed) { case 1000: CAN_InitStructure.CAN_Prescaler =1; break; //1Mb case 500: CAN_InitStructure.CAN_Prescaler =1; break; //500 kB case 250: CAN_InitStructure.CAN_Prescaler =2; break; //250 kB case 125: CAN_InitStructure.CAN_Prescaler =4; break; //125 kB case 100: CAN_InitStructure.CAN_Prescaler =6; break; //100 kB case 50: CAN_InitStructure.CAN_Prescaler =12; break; //50 kB case 20: CAN_InitStructure.CAN_Prescaler =40; break; //20 kB case 10: CAN_InitStructure.CAN_Prescaler =62; break; //10 kB default: CAN_InitStructure.CAN_Prescaler =144; break; }
CAN_DBGFreeze(CAN1,DISABLE); CAN_DBGFreeze(CAN2,DISABLE);
CAN_Start(UP); CAN_Start(DOWN); CAN_Init(CAN1, &CAN_InitStructure); CAN_Init(CAN2, &CAN_InitStructure);
//Ôèëüòð âåðõíåãî CAN CAN_FilterInitStructure.CAN_FilterNumber = 1; 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);
//CAN_FilterInitStructure.CAN_FilterIdHigh =0x2460; CAN_FilterInitStructure.CAN_FilterNumber = 15; CAN_FilterInit(&CAN_FilterInitStructure);
}
Вот пример моей реализации настройки CAN для stm32f105. Естественно перед этим, модулю отданы соответствующие выводы, и сделаны необходимые ремапы
|
|
|
|
|
May 7 2012, 12:44
|
Частый гость
 
Группа: Участник
Сообщений: 89
Регистрация: 3-01-11
Пользователь №: 61 997

|
Вопрос решен. Связь между платами утановлена. Проблемма была в перемычке на бутлоадер на отладочной плате мастера. По-этому, когда отключала программатор, плата после перезагрузки уходила в бут, а не на загрузку основной программы. Но осталась проблемма с платой приемника. Что-то мне кажется, не правильно настроены либо описаны прерывания у меня для stm32f103.Перифэралс Кан ресивер в Кейле при отладке показывает, что принят тот пакет, который отпрвлен мастером, НО прерывания не срабатывают. Более того, прогрмма заходит на строчку 324 файла startup_stm32f10x_hd.s. CODE /*=========================================================================*/ void NVIC_CAN_Configuration(void) { NVIC_InitTypeDef NVIC_InitStructure; NVIC_PriorityGroupConfig(NVIC_PriorityGroup_0); NVIC_InitStructure.NVIC_IRQChannel=USB_LP_CAN1_RX0_IRQn;//|USB_HP_CAN1_TX_IRQn; NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x0; NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x0; NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; NVIC_Init(&NVIC_InitStructure); } /*==============================================================================*/ void USB_HP_CAN1_TX_IRQHandler (void) { if (CAN_GetITStatus(CAN1,CAN_IT_TME)) { // request completed mbx 0 CAN_ClearITPendingBit(CAN1,CAN_IT_TME); CAN_TxRdy++; } } /*========================================================================*/ void USB_LP_CAN1_RX_IRQHandler (void) { if (CAN_GetITStatus(CAN1,CAN_IT_FMP0)) { // message pending ? CAN_Receive(CAN1,0,&RxMessage); // read the message CAN_RxRdy++; // set receive flag } } /*===========================================================================*/ int main (void) { __disable_irq (); Init_CLK(); NVIC_CAN_Configuration(); Init_GPIO_CAN(); Init_CAN(); CAN_ITConfig(CAN1, CAN_IT_FMP0, ENABLE); CAN_ITConfig(CAN1, CAN_IT_FF0, ENABLE); CAN_ITConfig(CAN1, CAN_IT_FOV0, ENABLE); __enable_irq (); while (1) { } }
Сообщение отредактировал IgorKossak - May 10 2012, 07:03
Причина редактирования: [codebox]
|
|
|
|
|
May 11 2012, 09:18
|
Участник

Группа: Участник
Сообщений: 26
Регистрация: 15-11-07
Пользователь №: 32 363

|
Цитата(batisto4ka @ May 10 2012, 15:35)  Подскажите, пожалуйста кто знает по фильтрам в CAN.
Можно ли с помощью фильтров, отсечь определенный диапазон ID. 1.Допустим устройство поддерживает ID от 0 до 125. Можно ли как то настроить фильтры, чтобы устройство принимало только сообщения с идентификаторами от 0 до 125? Как это реализовать? 2.Можно ли настроить фильтры так, чтобы они принимали только определенные номера ID (не по порядку штук 1000 разных ID)?Если можно, то как это сделать? Для STM32F4xx включается режим Mask mode и настраивается mask register, в котором необходимо указать биты идентификатора сообщения, участвующие в сравнении при получении сообщения по CAN. Т.о. например, настраиваем в mask register младших пять бит как “don’t care” и в результате все сообщения у которых совпадут старшие биты, (младшие пять бит могут быть любыми) - будут приняты. Получаем 32 сообщения принимаемых через один фильтр.
|
|
|
|
|
May 19 2012, 20:01
|

Twilight Zone
  
Группа: Свой
Сообщений: 454
Регистрация: 17-02-09
Из: Челябинск
Пользователь №: 44 990

|
Здравствуйте, коллеги! На STM32F2 возникли затруднения с CAN. Для начала решил поработать в режиме Loop back mode. В этом режиме все корректно работает, прочитанное сообщение идентично исходящему. Меняю строчку CAN_InitStructure.CAN_Mode = CAN_Mode_LoopBack; На CAN_InitStructure.CAN_Mode = CAN_Mode_Normal; Соединяю пины CAN_Rx и CAN_Tx (ня всякий случай через 100 Ом) для получения внешней Loop back . Скорость выставляю 125kBps. Так не работает. Вообще по CAN для STM32F2 мало информации и примеров, искал Demo софт для отладочных плат STM32F2XX c примером для CAN, так все пока безрезультатно. В примера IAR для STM32F2XX порты инициализируются так: Код #define CAN_GPIO_PORT GPIOD #define CAN_RX_SOURCE GPIO_PinSource0 #define CAN_TX_SOURCE GPIO_PinSource1 #define CAN_AF_PORT GPIO_AF_CAN1 #define CAN_RX_PIN GPIO_Pin_5 #define CAN_TX_PIN GPIO_Pin_13
/* Connect CAN pins to AF9 */ GPIO_PinAFConfig(CAN_GPIO_PORT, CAN_RX_SOURCE, CAN_AF_PORT); GPIO_PinAFConfig(CAN_GPIO_PORT, CAN_TX_SOURCE, CAN_AF_PORT); /* Configure CAN RX and TX pins */ GPIO_InitStructure.GPIO_Pin = CAN_RX_PIN | CAN_TX_PIN; 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); Т.е. и Rx и Tx как GPIO_Mode_AF. В примерах выше CAN_TX идет как GPIO_Mode_AF, CAN_RX - вход(GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU; // ). Как правильно? Если не сложно, прошу выложить куски рабочего кода инициализации и т.п. Ну, еще у меня CAN2 используется, может в нем какая-нибудь особенность есть....
--------------------
Magic Friend
|
|
|
|
|
May 28 2012, 05:38
|
Частый гость
 
Группа: Свой
Сообщений: 112
Регистрация: 1-05-09
Из: Ростов-на-Дону
Пользователь №: 48 518

|
Цитата(Danis @ May 20 2012, 00:01)  Соединяю пины CAN_Rx и CAN_Tx (ня всякий случай через 100 Ом) для получения внешней Loop back . Скорость выставляю 125kBps. Так не работает. Вообще по CAN для STM32F2 мало информации и примеров, искал Demo софт для отладочных плат STM32F2XX c примером для CAN, так все пока безрезультатно. Для начала CAN это не UART и одновременный прием и передача здесь не пройдет. Необходимо еще одно устройство, плюс драйвера на каждом. Цитата(Danis @ May 20 2012, 00:01)  Т.е. и Rx и Tx как GPIO_Mode_AF. В примерах выше CAN_TX идет как GPIO_Mode_AF, CAN_RX - вход(GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU; // ). Как правильно? У меня RX -> GPIO_Mode_IPU
--------------------
«У современных мобильных телефонов такая же вычислительная мощь, что и у компьютеров NASA в 60-е годы. И в то время этого хватало, чтобы запустить человека в космос, а сегодня — только чтобы запускать птиц в свиней.»
|
|
|
|
|
May 28 2012, 06:21
|

Twilight Zone
  
Группа: Свой
Сообщений: 454
Регистрация: 17-02-09
Из: Челябинск
Пользователь №: 44 990

|
Цитата(PoReX @ May 28 2012, 08:38)  Для начала CAN это не UART и одновременный прием и передача здесь не пройдет. Необходимо еще одно устройство, плюс драйвера на каждом.
У меня RX -> GPIO_Mode_IPU т.е. Вы убеждены, что введение внешней Loop back не приемлемо? С внутренней Loop back все же работает….
--------------------
Magic Friend
|
|
|
|
|
May 28 2012, 07:08
|
Частый гость
 
Группа: Свой
Сообщений: 112
Регистрация: 1-05-09
Из: Ростов-на-Дону
Пользователь №: 48 518

|
Да, кстати, если используется CAN2, то эти дефайны не правильные. Да и вообще похоже они вырваны с разных мест. Цитата(Danis @ May 20 2012, 00:01)  [code]#define CAN_GPIO_PORT GPIOD #define CAN_RX_SOURCE GPIO_PinSource0 #define CAN_TX_SOURCE GPIO_PinSource1 #define CAN_AF_PORT GPIO_AF_CAN1 #define CAN_RX_PIN GPIO_Pin_5 #define CAN_TX_PIN GPIO_Pin_13 Цифра в PinSource должна соответствовать, цифре GPIO_Pin. На порту GPIOD нет CAN'a. GPIO_AF_CAN1 заменить на GPIO_AF_CAN2 Цитата(Danis @ May 28 2012, 10:21)  т.е. Вы убеждены, что введение внешней Loop back не приемлемо? С внутренней Loop back все же работает…. Для этого и сделан режим Loop back, чтобы смотреть что отправляешь и по идее там не просто RX на TX закорочен, а еще изменяется алгоритм работы контроллера. Да я убежден, что внешняя Loop Back роли не играет. Например, если обратиться к википедии и почитать описание CAN, в частности арбитраж и посмотреть на блок схему драйвера, то можно увидеть, что внутри RX и TX (грубо говоря) соединены. Значит, следуя Вашим рассуждениям в нормальном режиме мы должны получать, то что отослали на TX, но этого не происходит......почему???? Да потому что во время отправки происходит арбитраж, на TX пине бит выставляется, а RX пином контроллер следит какой уровень на линии получился, если отличный от TX, значит он проиграл арбитраж. Таким образом прием во время передачи не возможен!! А Loop Back режим вносит некоторые изменения в алгоритм работы контроллера, а не тупо закорачивает ножки. Почитайте описание CAN. Цитата(PoReX @ May 28 2012, 09:38)  У меня RX -> GPIO_Mode_IPU Ошибочка, это для F103, а для F2 у RX и TX GPIO_Mode_AF.
Сообщение отредактировал PoReX - May 28 2012, 07:01
--------------------
«У современных мобильных телефонов такая же вычислительная мощь, что и у компьютеров NASA в 60-е годы. И в то время этого хватало, чтобы запустить человека в космос, а сегодня — только чтобы запускать птиц в свиней.»
|
|
|
|
|
May 28 2012, 07:51
|

Twilight Zone
  
Группа: Свой
Сообщений: 454
Регистрация: 17-02-09
Из: Челябинск
Пользователь №: 44 990

|
Цитата(PoReX @ May 28 2012, 10:08)  Да, кстати, если используется CAN2, то эти дефайны не правильные. Да и вообще похоже они вырваны с разных мест. Так и есть, это примеры из IAR. У меня порты и №CAN нужные. Тут вообщемто вопрос про режим pin i/o интересовал. На счет изучения материальной части - согласен, без нее никуда, было немного свободного времени, хотел как говориться сделать «быстрый старт», потом рассмотреть/закрепить детали. По поводу описания CAN на STM32F2, есть референс, но толкового app note, что то не нашел. Примеров на сайте тоже не вижу. PoReX, спасибо за отзыв!
--------------------
Magic Friend
|
|
|
|
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|