реклама на сайте
подробности

 
 
 
Reply to this topicStart new topic
> Регистры CAN модуля в LPC1549, Нужна консультация
kolisnichenko_r
сообщение Dec 2 2015, 07:30
Сообщение #1


Местный
***

Группа: Свой
Сообщений: 435
Регистрация: 12-09-07
Пользователь №: 30 482



Здравствуйте
Разбираюсь с 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) Как настраивать фильтр и маску тоже не понятно.
Из примеров состряпал программу. Передача получилась, а вот с приемом ну никак.
Прошу помощи
Go to the top of the page
 
+Quote Post
mempfis_
сообщение Dec 2 2015, 09:19
Сообщение #2


Профессионал
*****

Группа: Свой
Сообщений: 1 001
Регистрация: 27-06-06
Пользователь №: 18 409



Бегло просмотрел документацию на lpc11 и lpc15 - CAN в них похоже одинаковый.
На lpc11 у меня несколько серийных проектов.
Просмотрите в приложенных файлах инициализацию и работу с CAN.

Для работы я выбираю какие MSG OBJECT будут приёмные (RX), а какие передающие (TX)
CODE

//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 работаем так:

CODE

//Передача сообщения 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 опрашивается в цикле до опустошения.

CODE
//проверяем rx fifo
stCANMSGObject can_rx_msg;
while(getMsgCAN(&can_rx_msg) != 0)
{
//выполняем проверку принятого сообщения
......
}

Go to the top of the page
 
+Quote Post
kolisnichenko_r
сообщение Dec 2 2015, 10:15
Сообщение #3


Местный
***

Группа: Свой
Сообщений: 435
Регистрация: 12-09-07
Пользователь №: 30 482



Спасибо, разбираюсь
Go to the top of the page
 
+Quote Post
kolisnichenko_r
сообщение Dec 2 2015, 12:24
Сообщение #4


Местный
***

Группа: Свой
Сообщений: 435
Регистрация: 12-09-07
Пользователь №: 30 482



Цитата(kolisnichenko_r @ Dec 2 2015, 13:15) *
Спасибо, разбираюсь

Что нужно сделать чтобы установить INT в ноль? В User manual написано чтением Status Register (STAT) или очисткой INTPND.
Код
can_stat = LPC_CAN->STAT;
LPC_CAN->IF2_MCTRL &= 0xDFFF;//Clear INTPND

После этих действий INT не обнуляется
Go to the top of the page
 
+Quote Post
mempfis_
сообщение Dec 2 2015, 13:09
Сообщение #5


Профессионал
*****

Группа: Свой
Сообщений: 1 001
Регистрация: 27-06-06
Пользователь №: 18 409



Цитата(kolisnichenko_r @ Dec 2 2015, 15:24) *
Что нужно сделать чтобы установить 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.
Go to the top of the page
 
+Quote Post
kolisnichenko_r
сообщение Dec 2 2015, 13:26
Сообщение #6


Местный
***

Группа: Свой
Сообщений: 435
Регистрация: 12-09-07
Пользователь №: 30 482



Может я не правильно инициализировал объект для приема?
Вот код:
Код
     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.
Ошибки в регистре статуса не отображаются.
Go to the top of the page
 
+Quote Post
mempfis_
сообщение Dec 2 2015, 13:34
Сообщение #7


Профессионал
*****

Группа: Свой
Сообщений: 1 001
Регистрация: 27-06-06
Пользователь №: 18 409



Цитата(kolisnichenko_r @ Dec 2 2015, 17:26) *
Может я не правильно инициализировал объект для приема?
А эту инициализацию нужно делать один раз или после каждого приема?


RX инициализируется один раз, а обслуживается уже в прерываниях.
Во вложении есть пример настройки всех RX MSG OBJECT - это функция CAN_InitRxMessages().
А вот TX MSG OBJECT в этом процессоре лично я настраиваю каждый раз перед отправкой сообщения - мне так проще работать с ними.

В LPC17 CAN устроен по другому - там передавать получалось используя FIFO сообщений.
А вот в LPC11 всё не так удобно .... sad.gif
Но с другой стороны разобравшись с примерами удалось состряпать приведённый во вложении код, который успешно функционирует в 4х серийных проектах без каких-либо нареканий на работу CAN-шины.
Go to the top of the page
 
+Quote Post
kolisnichenko_r
сообщение Dec 2 2015, 14:34
Сообщение #8


Местный
***

Группа: Свой
Сообщений: 435
Регистрация: 12-09-07
Пользователь №: 30 482



Цитата(mempfis_ @ Dec 2 2015, 16:34) *
RX инициализируется один раз, а обслуживается уже в прерываниях.
Во вложении есть пример настройки всех RX MSG OBJECT - это функция CAN_InitRxMessages().
А вот TX MSG OBJECT в этом процессоре лично я настраиваю каждый раз перед отправкой сообщения - мне так проще работать с ними.

В LPC17 CAN устроен по другому - там передавать получалось используя FIFO сообщений.
А вот в LPC11 всё не так удобно .... sad.gif
Но с другой стороны разобравшись с примерами удалось состряпать приведённый во вложении код, который успешно функционирует в 4х серийных проектах без каких-либо нареканий на работу CAN-шины.

Получается что нужно инициировать объект для приема в Message RAM и сделать его копию в программе, что бы потом по средству IF регистров получить к ним доступ и обрабатывать уже копию?
Go to the top of the page
 
+Quote Post
kolisnichenko_r
сообщение Dec 3 2015, 07:55
Сообщение #9


Местный
***

Группа: Свой
Сообщений: 435
Регистрация: 12-09-07
Пользователь №: 30 482



Почему не выходит с прерывания после приема?
Вроде и очистка бита 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?
Go to the top of the page
 
+Quote Post
kolisnichenko_r
сообщение Dec 3 2015, 13:14
Сообщение #10


Местный
***

Группа: Свой
Сообщений: 435
Регистрация: 12-09-07
Пользователь №: 30 482



Как узнать инициирован ли объект в Message RAM?
Go to the top of the page
 
+Quote Post

Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 19th July 2025 - 20:09
Рейтинг@Mail.ru


Страница сгенерированна за 0.0197 секунд с 7
ELECTRONIX ©2004-2016