Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: Передача данных по CAN
Форум разработчиков электроники ELECTRONIX.ru > Сайт и форум > В помощь начинающему > Интерфейсы
Васька
Доброго времени суток! Т.к. я совсем новичек и много чего еще не понимаю, опишу суть проблемы. Имеется контроллер AT90CAN64. Необходимо организовать только передачу данных по CAN. По гуглив, почитав datasheet на русском и найдя кое - какие примеры, состряпал свою программу в CodeVision. После прошивки посмотрел осциллографом сигнал непосредственно на выходе CAN, а затем на ноге TX контроллера. Сигнал отсутсвует везде. Ниже привожу код моей программы с коментариями. Прошу гуру данного форума дать дельный совет и указать на мои косяки, ибо работа горит. sm.gif Заранее спасибо.
Код
unsigned char i;
unsigned char datatx_buf[8];

void ResetAllMailbox (void)  // сбрасываем регистры (вроде как рекомендуется)
{
  unsigned char num_channel, num_data;

  for (num_channel = 0; num_channel < 15; num_channel++)
  {
    CANPAGE  = (num_channel<<4);
    CANSTMOB = 0;
    CANCDMOB = 0;
    CANIDT4  = 0;
    CANIDT3  = 0;
    CANIDT2  = 0;
    CANIDT1  = 0;
    CANIDM4  = 0;
    CANIDM3  = 0;
    CANIDM2  = 0;
    CANIDM1  = 0;
    for (num_data = 0; num_data < 8; num_data++)
    {
      CANMSG = 0;
    }
  }

}

void CAN_Init()
{

    CANBT1=0x00;   // CAN System Clock: 8000,0 kHz
    CANBT2=0x0C;   // Propagation Time Segement: 0,875 us, Re-Sync Jump Width: 0,125 us
    CANBT3=0x37;   // Sample Point(s): 3, Phase Segment 1: 0,500 us, Phase Segment 2: 0,500 us
    CANTCON=0x7C;  // CAN Timer Clock Period: 125,000 us


  CANGCON |= (1<<SWRES);          //сброс общего регистра управления CAN
  ResetAllMailbox (); // вызов функции сброса регистров
  
  //Настройка MOb1=Tx на передачу
  CANPAGE  = 0x10;                //Выбор номера Mob, в данном случае Mob1
  CANSTMOB = 0x40;              //Установка бита удачного завершения передачи TXOK, для 1-й передачи, зачем то везде ставят
  CANCDMOB = 0x08;             // длина данных 8 байт
  
  CANIDT4  = 0x00;                                                              
  CANIDT3  = 0x00;                                                              
  CANIDT2  = 0x20;       //Идентификатор равен 1                                              
  CANIDT1  = 0x00;                                                                              
  CANIDM4  = 0x00;      //Принудительный положительный результат сравнения                                                                        
  CANIDM3  = 0x00;                                      
  CANIDM2  = 0x00;                                                                                                              
  CANIDM1  = 0x00;                                                                          
  
  CANEN2=0xff;                 //Разрешить все Mob
  CANEN1=0xff;
  CANIE2=0x00;                 //запретить прерывания по всем Mob
  CANIE1=0x00;
  
  CANHPMOB=0x10;               //Установка высшего приоритета для MOb1

  CANGCON |= 0x02;             //Разрешить контроллер CAN                                        
}

void can_send (unsigned char n)
{
  
    CANPAGE = (n<<4);                              //Выбрать n-й канал, автоинкремент, местоположение байта данных в FIFO 0
    if (CANSTMOB & (1<<TXOK))                  //Если бит TXOK регистра CANSTMOB установлен в 1
    {
        CANSTMOB &= 0;                             //Сбросить регистр состояния объектов сообщений
        
        for(i = 0; i < 8; i++)
        {
            CANMSG = datatx_buf[i];                //Запись данных в регистр данных CAN
        }
        CANCDMOB |= (1<<6);    //Разрешение передачи,длина данных 8 байт
        CANCDMOB |= (1<<3);
    }

}

void main(void)
{
CAN_Init();
datatx_buf[0]=0x0A;
datatx_buf[1]=0x0B;
datatx_buf[2]=0x0C;
datatx_buf[3]=0x0D;
datatx_buf[4]=0x0E;
datatx_buf[5]=0x0F;
datatx_buf[6]=0xAA;
datatx_buf[7]=0xBB;
can_send(1);
}
Палыч
Цитата(Васька @ Jun 9 2011, 09:38) *
дать дельный совет и указать на мои косяки
Посмотрел программу "по диагонали"... Бросилось в глаза, что нет настройки ног, типа такой:
Код
    //- Pull-up on TxCAN & RxCAN one by one to use bit-addressing
    CAN_PORT_DIR &= ~(1<<CAN_INPUT_PIN );
    CAN_PORT_DIR &= ~(1<<CAN_OUTPUT_PIN);
    CAN_PORT_OUT |=  (1<<CAN_INPUT_PIN );
    CAN_PORT_OUT |=  (1<<CAN_OUTPUT_PIN);
Первые две строчки, возможно, излишние, а вот - две последние...
Васька
Инициализацию портов я не стал здесь приводить. CodeVision сделал это сам. Не знаю, тоже самое это или нет, что вы предлагаете, но инициализация порта с CAN выглядит так
Код
PORTD=0x20; // нога TXCAN
DDRD=0x20;
Палыч
Цитата(Васька @ Jun 9 2011, 14:44) *
Не знаю, тоже самое это или нет, что вы предлагаете, но инициализация порта с CAN выглядит так

Приведенный выше код взят из примера от Atmel. В соответствии с ним в Вашем случае должно быть
Код
DDRD=0x00; // Впрочем этот регистр и по сбросу = 0; поэтому я и говорил, что две строчки - излишни
PORTD=0x60;
Васька
В общем проблема решилась комментированием строки

Код
CANGCON |= (1<<SWRES);          //сброс общего регистра управления CAN


З.Ы. спасибо Палычу за советы sm.gif
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.