Перейти к содержанию
    

Регистры CAN модуля в LPC1549

Здравствуйте

Разбираюсь с 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) Как настраивать фильтр и маску тоже не понятно.

Из примеров состряпал программу. Передача получилась, а вот с приемом ну никак.

Прошу помощи

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Бегло просмотрел документацию на 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)
 {
   //выполняем проверку принятого сообщения
   ......
 } 

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Спасибо, разбираюсь

Что нужно сделать чтобы установить INT в ноль? В User manual написано чтением Status Register (STAT) или очисткой INTPND.

 can_stat = LPC_CAN->STAT;
LPC_CAN->IF2_MCTRL &= 0xDFFF;//Clear INTPND

После этих действий INT не обнуляется

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Что нужно сделать чтобы установить 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.

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Может я не правильно инициализировал объект для приема?

Вот код:

     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.

Ошибки в регистре статуса не отображаются.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Может я не правильно инициализировал объект для приема?

А эту инициализацию нужно делать один раз или после каждого приема?

 

RX инициализируется один раз, а обслуживается уже в прерываниях.

Во вложении есть пример настройки всех RX MSG OBJECT - это функция CAN_InitRxMessages().

А вот TX MSG OBJECT в этом процессоре лично я настраиваю каждый раз перед отправкой сообщения - мне так проще работать с ними.

 

В LPC17 CAN устроен по другому - там передавать получалось используя FIFO сообщений.

А вот в LPC11 всё не так удобно .... :(

Но с другой стороны разобравшись с примерами удалось состряпать приведённый во вложении код, который успешно функционирует в 4х серийных проектах без каких-либо нареканий на работу CAN-шины.

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

RX инициализируется один раз, а обслуживается уже в прерываниях.

Во вложении есть пример настройки всех RX MSG OBJECT - это функция CAN_InitRxMessages().

А вот TX MSG OBJECT в этом процессоре лично я настраиваю каждый раз перед отправкой сообщения - мне так проще работать с ними.

 

В LPC17 CAN устроен по другому - там передавать получалось используя FIFO сообщений.

А вот в LPC11 всё не так удобно .... :(

Но с другой стороны разобравшись с примерами удалось состряпать приведённый во вложении код, который успешно функционирует в 4х серийных проектах без каких-либо нареканий на работу CAN-шины.

Получается что нужно инициировать объект для приема в Message RAM и сделать его копию в программе, что бы потом по средству IF регистров получить к ним доступ и обрабатывать уже копию?

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Почему не выходит с прерывания после приема?

Вроде и очистка бита 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?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.

Гость
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...