rsln 0 2 декабря, 2015 Опубликовано 2 декабря, 2015 · Жалоба Здравствуйте Разбираюсь с CAN модулем в LPC1549. Все с ноля: МК, архитектура МК, CAN. Перед этим имел дело с 8 битными МК и не сложные проекты. Собственно вопросы: 1) В МК (CAN модуль) есть по 2 одинаковых регистра с разными номерами 1 и 2. Это означает 1 - передача, 2 - прием? 2) Как организовано передачу из объекта сообщения (message object - правильно ли я перевел) в регистры CAN? 3) На счет номера объекта сообщения (message number), написано, что можно создать 32 таких объекта, в регистрах IF1/2_CMDREQ их по 32. Это 32 на прием и 32 на передачу? Как определять какие на прием, какие на передачу? 4) Как настраивать фильтр и маску тоже не понятно. Из примеров состряпал программу. Передача получилась, а вот с приемом ну никак. Прошу помощи Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
mempfis_ 0 2 декабря, 2015 Опубликовано 2 декабря, 2015 · Жалоба Бегло просмотрел документацию на lpc11 и lpc15 - CAN в них похоже одинаковый. На lpc11 у меня несколько серийных проектов. Просмотрите в приложенных файлах инициализацию и работу с CAN. Для работы я выбираю какие MSG OBJECT будут приёмные (RX), а какие передающие (TX) //msg object для приёма сообщений #define S6_BAM_CM_RX_MSG_OBJ 1 #define S6_BAM_DT_RX_MSG_OBJ 2 //msg object для отправки сообщений #define S6_PASSPORT_TX_MSG_OBJ 10 #define S6_COUNTERS_TX_MSG_OBJ 11 #define S6_STATUS0_TX_MSG_OBJ 12 #define S6_STATUS1_TX_MSG_OBJ 13 #define S6_STATUS2_TX_MSG_OBJ 14 #define S6_STATUS3_TX_MSG_OBJ 15 #define S6_BAM_TX_MSG_OBJ 16 Настройка RX есть в приложенных файлах. При настройке определяется также маска фильтрации ACF-фильтра. С TX работаем так: //Передача сообщения 01 02 03 04 05 06 07 08 (01 -младший байт в сообщении, 08 - старший) на id 21 bit 0xabcd (extended frame) stCANMSGObject msg; msg.id = EXT_FRAME_TYPE | 0xabcd; msg.dlc = 8; //длина данных (от 1 до 8) msg.data[0] = 0x0201; msg.data[1] = 0x0403; msg.data[2] = 0x0605; msg.data[3] = 0x0807; CAN_Send(S6_PASSPORT_TX_MSG_OBJ, &msg); Приём данных осуществляется в прерывании. Любое принятое сообщение извлекается из RX MSG OBJECT и закидывается в FIFO. Далее уже в основной программе FIFO опрашивается в цикле до опустошения. //проверяем rx fifo stCANMSGObject can_rx_msg; while(getMsgCAN(&can_rx_msg) != 0) { //выполняем проверку принятого сообщения ...... } Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
rsln 0 2 декабря, 2015 Опубликовано 2 декабря, 2015 · Жалоба Спасибо, разбираюсь Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
rsln 0 2 декабря, 2015 Опубликовано 2 декабря, 2015 · Жалоба Спасибо, разбираюсь Что нужно сделать чтобы установить INT в ноль? В User manual написано чтением Status Register (STAT) или очисткой INTPND. can_stat = LPC_CAN->STAT; LPC_CAN->IF2_MCTRL &= 0xDFFF;//Clear INTPND После этих действий INT не обнуляется Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
mempfis_ 0 2 декабря, 2015 Опубликовано 2 декабря, 2015 · Жалоба Что нужно сделать чтобы установить INT в ноль? В User manual написано чтением Status Register (STAT) или очисткой INTPND. can_stat = LPC_CAN->STAT; LPC_CAN->IF2_MCTRL &= 0xDFFF;//Clear INTPND После этих действий INT не обнуляется А какое значение он имеет? В обработчике прерываний происходит чтение LPC_CAN->STAT, после чего определяется наличие или отсутствие ошибок. При отсутствии ошибок выполняется обработка MSG OBJECT сгенерировавшего прерывание. При обработке MSG OBJECT выполняется его чтение. Возможно при чтениее LPC_CAN->STAT или после чтения содержимого MSG OBJECT обнуляются флаги NEWDATA и INTPND. В документации написано: When the CPU transfers the contents of Message Object to the IFx Message Buffer registers by writing its number to the IFx Command Request Register, bits NEWDAT and INTPND in the corresponding Command Mask Register should be reset to zero (TXRQST/NEWDAT = ‘1’ and ClrINTPND = ‘1’). что я понимаю как Когда цпу перемещает содержимое MSG OBJECT в IFx buff путём записи его номера в IFx Command Request Register биты NEWDAT and INTPND в соответствующем Command Mask Register должны обнулиться. В привёдённом во вложении обработчике прерываний никаких дополнительных сбросов битов нет, но при этом нет и лишних прерываний, что наверняка было бы, еслибы бит INTPND не сбрасывался. Возможно у Вас есть ошибки на шине или Вы не корретно обрабатываете RX/TX MSG OBJECT. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
rsln 0 2 декабря, 2015 Опубликовано 2 декабря, 2015 · Жалоба Может я не правильно инициализировал объект для приема? Вот код: rec_obj.msgobj = 3; rec_obj.mode_id = 0; rec_obj.mask = 0; rec_obj.dlc = 8; for(i=0;i<8;i++){rec_obj.data[i]=0;} LPC_CAND_API->hwCAN_ConfigRxmsgobj(pCanHandle, (CAN_MSG_OBJ*)&rec_obj); А эту инициализацию нужно делать один раз или после каждого приема? В отладчике после такой инициализации изменились биты MN регистра IF1_CMDREQ а в обработчике прерываний работаю с IF2_CMDREQ. Не понятно как привязать объект rec_obj к IF2_CMDREQ. Ошибки в регистре статуса не отображаются. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
mempfis_ 0 2 декабря, 2015 Опубликовано 2 декабря, 2015 · Жалоба Может я не правильно инициализировал объект для приема? А эту инициализацию нужно делать один раз или после каждого приема? RX инициализируется один раз, а обслуживается уже в прерываниях. Во вложении есть пример настройки всех RX MSG OBJECT - это функция CAN_InitRxMessages(). А вот TX MSG OBJECT в этом процессоре лично я настраиваю каждый раз перед отправкой сообщения - мне так проще работать с ними. В LPC17 CAN устроен по другому - там передавать получалось используя FIFO сообщений. А вот в LPC11 всё не так удобно .... :( Но с другой стороны разобравшись с примерами удалось состряпать приведённый во вложении код, который успешно функционирует в 4х серийных проектах без каких-либо нареканий на работу CAN-шины. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
rsln 0 2 декабря, 2015 Опубликовано 2 декабря, 2015 · Жалоба RX инициализируется один раз, а обслуживается уже в прерываниях. Во вложении есть пример настройки всех RX MSG OBJECT - это функция CAN_InitRxMessages(). А вот TX MSG OBJECT в этом процессоре лично я настраиваю каждый раз перед отправкой сообщения - мне так проще работать с ними. В LPC17 CAN устроен по другому - там передавать получалось используя FIFO сообщений. А вот в LPC11 всё не так удобно .... :( Но с другой стороны разобравшись с примерами удалось состряпать приведённый во вложении код, который успешно функционирует в 4х серийных проектах без каких-либо нареканий на работу CAN-шины. Получается что нужно инициировать объект для приема в Message RAM и сделать его копию в программе, что бы потом по средству IF регистров получить к ним доступ и обрабатывать уже копию? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
rsln 0 3 декабря, 2015 Опубликовано 3 декабря, 2015 · Жалоба Почему не выходит с прерывания после приема? Вроде и очистка бита STAT_TXOK в регистре STAT выполняется. void CAN_IRQHandler(void)//CAN0_IRQHandler(void)//CAN_IRQHandler(void) { uint32_t can_stat, can_int; mas[0]=can_int = LPC_CAN->INT; mas[1]=can_stat = LPC_CAN->STAT; if(can_stat & STAT_TXOK) { LPC_CAN->STAT &= ~STAT_TXOK; } //message received if(can_stat & STAT_RXOK) { LPC_CAN->STAT &= ~STAT_RXOK; //Board_LED_Toggle(3); while ( LPC_CAN->IF2_CMDREQ & IFCREQ_BUSY ); LPC_CAN->IF2_CMDMSK = RD|MASK|ARB|CTRL|INTPND|TREQ|DATAA|DATAB; LPC_CAN->IF2_CMDREQ = 3; /* Start message transfer */ while ( LPC_CAN->IF2_CMDREQ & IFCREQ_BUSY ); /* Check new data bit */ rec_obj.mode_id = (LPC_CAN->IF2_ARB2 &0x1FFF) >> 2; rec_obj.dlc = LPC_CAN->IF2_MCTRL & 0x000F; // Get Msg Obj Data length //LPC_CAN->IF2_MCTRL &= 0xDFFF;//b1101111111111111;//Clear INTPND rec_obj.DA1= LPC_CAN->IF2_DA1; rec_obj.DA2= LPC_CAN->IF2_DA2; rec_obj.DB1= LPC_CAN->IF2_DB1; rec_obj.DB2= LPC_CAN->IF2_DB2; LPC_CAN->IF2_MCTRL &=0xDFFF;//b1101111111111111;//Clear INTPND } LPC_CAN->IF1_MCTRL &=0xDFFF;//b1101111111111111;//Clear INTPND mas[10]=10; } Не обнуляются биты регистра INT. Я правильно думаю что при очистке STAT_TXOK в регистре STAT должны обнулится INT? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
rsln 0 3 декабря, 2015 Опубликовано 3 декабря, 2015 · Жалоба Как узнать инициирован ли объект в Message RAM? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться