mraaf Ответов: 1

Как настроить CAN-коммуникацию с помощью softing canusb?


Здравствуйте Эксперты,
Мне трудно установить связь с микроконтроллером с помощью CAN-шины. Мой проект вошел в предел устройства, поэтому я должен использовать несколько устройств и управлять всеми из них через CAN-шину. Я ищу везде, но не могу помочь мне с API CAN Layer2, который я использую. Я действительно Новичок в программировании CAN.

Используемая библиотека DLL:
canL2.dll
Can_def.ч
CANL2.Ч

Ниже приведен пример c-кодов от Softing, но я не уверен, как использовать их с VC++.

Заранее спасибо.
мрааф

Что я уже пробовал:

#include "can_def.h"  // dll import and export definitions
#include "canL2.h"    // definition of the API functions an the structures


main()
{
  int ret;
  CANL2_CH_STRUCT ch1, ch2;
  CAN_HANDLE can1, can2;
  L2CONFIG L2Config[2];
  char custom, *pName[2] = {NULL,NULL};
  PCHDSNAPSHOT pBuffer = NULL;
  unsigned long u32NeededBufferSize, u32NumOfChannels, u32ProvidedBufferSize, channelIndex;
  int sw_version, fw_version, hw_version, license, chip_type, i;


printf ("Analyzing your system ...\n");

  u32ProvidedBufferSize = 0;

  // call the function without a valid buffer size first to get the needed buffersize in "u32NeededBufferSize"
  ret = CANL2_get_all_CAN_channels(0, &u32NeededBufferSize, &u32NumOfChannels, NULL);

  if(!u32NumOfChannels)
  {
    printf("you have no Softing CAN interface card plugged in your Computer!\n");
    printf("plug a interface card first and start this program again after this.\n");
    custom=getch();
    exit(0);
  }

  if(ret)
  {
    printf("The driver reported a problem: Error Code %x\n", ret);
    custom=getch();
    exit(0);
  }
  
  
  pBuffer = malloc(u32NeededBufferSize);

  if(!pBuffer)
  {
    printf("Out of memory\n");
    custom=getch();
    exit(0);
  }

  u32ProvidedBufferSize = u32NeededBufferSize;

    
  ret = CANL2_get_all_CAN_channels(u32ProvidedBufferSize, &u32NeededBufferSize, &u32NumOfChannels, pBuffer);

  if(ret)
  {
    printf("The driver reported a problem: Error Code %x\n", ret);
    custom=getch();
    free(pBuffer);
    exit(0);
  }

  printf("You have %u Softing CAN channels in your system\n\n", u32NumOfChannels);

  printf("\tname\t\t serialnumber\t type\t\t chan.\t    open\n");
  printf("------------------------------------------------------------------------\n");
  printf("\n");

  for(channelIndex=0; channelIndex<u32NumOfChannels; channelIndex++)
  {
    PCHDSNAPSHOT pCh = &pBuffer[channelIndex];
    

    printf("% 17s\t %09u  % 18s\t %2u\t % 5s\n",
      pCh->ChannelName,
      pCh->u32Serial,
      getDeviceType(pCh->u32DeviceType),
      pCh->u32PhysCh,
      (pCh->bIsOpen) ? "yes" : "no");

    if(!pCh->bIsOpen)
    {
      if(ch<2)
      {
        pName[ch] = pCh->ChannelName;
        ch++;
      }
    }

  }
  
  if(ch < 2)
  {
    if(ch == 0)
    {
      printf("\nAll CAN channels are used by other applications!\n");
      printf("Type <return> to exit program!\n");
      custom=getch();
      free(pBuffer);
      exit(0);
    }

    printf("\nYou have only 1 channel plugged, the commands for the second channel will not \n");
    printf("be available!\n");
    printf("Type <return> to proceed!\n");
    custom=getch();
  }


  
  
  L2Config[0].bEnableAck = GET_FROM_SCIM;
  L2Config[0].bEnableErrorframe = GET_FROM_SCIM;
  L2Config[0].s32AccCodeStd = GET_FROM_SCIM;
  L2Config[0].s32AccCodeXtd = GET_FROM_SCIM;
  L2Config[0].s32AccMaskStd = GET_FROM_SCIM;
  L2Config[0].s32AccMaskXtd = GET_FROM_SCIM;
  L2Config[0].s32OutputCtrl = GET_FROM_SCIM;
  L2Config[0].s32Prescaler = GET_FROM_SCIM;
  L2Config[0].s32Sam = GET_FROM_SCIM;
  L2Config[0].s32Sjw = GET_FROM_SCIM;
  L2Config[0].s32Tseg1 = GET_FROM_SCIM;
  L2Config[0].s32Tseg2 = GET_FROM_SCIM;

  memcpy(&L2Config[1], &L2Config[0], sizeof(L2CONFIG));

  strcpy(ch1.sChannelName,pName[0]);

  if(ch > 1)
  {
    strcpy(ch2.sChannelName,pName[1]);
  }
  
  
/*
  strcpy(ch1.sChannelName,"Softing1");
  strcpy(ch2.sChannelName,"Softing2");
  */
  
  if(ch > 1)
  {
    printf("\ninitializing %s and %s\n", ch1.sChannelName, ch2.sChannelName);
  }
  else
  {
    printf("\ninitializing %s\n", ch1.sChannelName);
  }

  printf("Initialization started...\n");
  
  

  free(pBuffer);


  ret = INIL2_initialize_channel(&ch1.ulChannelHandle, ch1.sChannelName);

  if(ret)
  {
    printf("Error %u in INIL2_initialize_channel()\n",ret);
    custom=getch();
    return ret;
  }

  can1 = ch1.ulChannelHandle;

  if(ch > 1)
  {
    
    ret = INIL2_initialize_channel(&ch2.ulChannelHandle, ch2.sChannelName);
    
    if(ret)
    {
      printf("Error %u in INIL2_initialize_channel()\n",ret);
      custom=getch();
      return ret;
    }
    
    can2 = ch2.ulChannelHandle;
  }
  else
  {
    can2 = (CAN_HANDLE)INVALID_HANDLE_VALUE;
  }


  ret = PrepareForIntEvents(&L2Config[0], &can1, &L2Config[1], &can2);
  if(ret)
  {
    printf("Error %u in PrepareForIntEvents()\n",ret);
    custom=getch();
    return ret;
  }

  ret = CANL2_initialize_fifo_mode(can1, &L2Config[0]);
  if(ret)
  {
    printf("Error %u in CANL2_initialize_fifo_mode()\n",ret);
    printf("please configure the channel by the SCIM first\n");
    custom=getch();
      // use start->control panel->can for configuration of the card settings!
    return ret;
  }

  if(ch > 1)
  {
    ret = CANL2_initialize_fifo_mode(can2, &L2Config[1]);
    if(ret)
    {
      printf("Error %u in CANL2_initialize_fifo_mode()\n",ret);
      printf("please configure the channel by the SCIM first\n");
      custom=getch();
      // use start->control panel->can for configuration of the card settings!
      return ret;
    }
  }


  ret = CANL2_get_version(can1, &sw_version, &fw_version, &hw_version, &license, &chip_type);
  if(ret)
  {
    printf("Error %u in CANL2_get_version(CAN1)\n",ret);
  }


  printf("\n VERSION INFO CAN1: \n\n");
  printf("    - Software version: %u.%02u\n", sw_version/100, sw_version%100);
  printf("    - Firmware version: %u.%02u\n", fw_version/100, fw_version%100);
  printf("    - Hardware version: %x.%02x\n", hw_version/0x100, hw_version%0x100);
  printf("    - CAN chip        : %s\n", (chip_type==1000)? "SJA1000": (chip_type==161) ? "Infineon XC161" : "Infineon XE164");


  if(ch > 1)
  {
    
    ret = CANL2_get_version(can2, &sw_version, &fw_version, &hw_version, &license, &chip_type);
    if(ret)
    {
      printf("Error %u in CANL2_get_version(CAN1)\n",ret);
    }
    
    printf("\n VERSION INFO CAN2: \n\n");
    printf("    - Software version: %u.%02u\n", sw_version/100, sw_version%100);
    printf("    - Firmware version: %u.%02u\n", fw_version/100, fw_version%100);
    printf("    - Hardware version: %x.%02x\n", hw_version/0x100, hw_version%0x100);
    printf("    - CAN chip        : %s\n", (chip_type==1000)? "SJA1000": (chip_type==161) ? "Infineon XC161" : "Infineon XE164");
    
    
    
    printf("The 2 channels are online now!\n\n");
  }
  else
  {
    printf("\n\nThe CAN channel is online now, a second channel is not available!\n\n");
  }

  custom = 'h';
  do	// loop
		{
      
      Sleep(0);

      // User request	
      ret=UserRequestFIFO(custom, can1, can2);	
      
      // Loop till user request
      while (!kbhit()) 
      {
      }// end while
      
      custom=getch();
      
      if (ret < 0)	
      {
        printf("-->User request failed \n");
        INIL2_close_channel(can1);

        if(ch > 1)
        {
          INIL2_close_channel(can2);
        }

        return(-1);
      }
    } 
    while (custom != 'q');	// End inner loop

    SetEvent(hThreadEvents[1]);
    WaitForSingleObject(hIntThread[0], 2000);

    if(ch > 1)
    {
      SetEvent(hThreadEvents[3]);
      WaitForSingleObject(hIntThread[1], 2000);
    }

    for(i=0; i<((ch>1)? 2 : 1); i++)
    {
      CloseHandle(hIntThread[i]);
    }

    for(i=0; i<((ch>1)? 4 : 2); i++)
    {
      CloseHandle(hThreadEvents[i]);
    }

    INIL2_close_channel(can1);

    if(ch > 1)
    {
      INIL2_close_channel(can2);
    }

    return ret;
    
}

1 Ответов

Рейтинг:
5

Jochen Arndt

Создание консольного приложения с помощью сторонней библиотеки DLL:
Создайте новое консольное приложение, скопируйте код в _tmain() функция и добавить библиотеку в настройках проекта (project-build options - linker settings - add library).

Вместо добавления библиотеки в настройках проекта вы также можете использовать

#pragma comment( lib, "canL2")
в одном из ваших исходных файлов (см. комментарий (C-C++)[^]).

Обратите внимание, что вам также нужен файл библиотеки canL2.Либ потому что это файл, на который ссылаются настройки проекта и pragma инструкция.

Вы можете указать полный путь к этому файлу LIB или убедиться, что он находится в пределах пути поиска библиотеки (например, добавив этот путь в настройки проекта).

DLL-файл должен быть помещен в тот же каталог, что и приложение. Во время разработки это выходные каталоги выпуска и отладки.


mraaf

Спасибо, теперь он выглядит намного лучше. Но некоторые функции до сих пор неузнаваемы.

Jochen Arndt

Вы должны предоставить больше информации о таких проблемах, как ошибки компилятора и коды ошибок, возвращаемые функциями во время выполнения программирования.

Без такой информации помочь невозможно.

Обратите внимание также, что, вероятно, никто здесь не использует эту библиотеку и harwdare, чтобы проверить код. Это делает более важным получение подробной информации о проблеме (и может сделать невозможным решение некоторых проблем).

mraaf

Отмеченный. Сожалеть об этом.
Я получу его, как только вернусь завтра в офис.

mraaf

Привет Йохен,
Ниже приведены ошибки компилятора:

Ошибка №1:
PCHDSNAPSHOT pBuffer = NULL;
беззнаковый Long u32NeededBufferSize;

pBuffer = malloc(u32NeededBufferSize)
...ошибка c2440: '=' : не удается конвертировать из 'Void*, который в CHDSNAPSHOT *'
... Преобразование из 'void*' в указатель на не - 'void' требует явного приведения


Ошибка №2:
CANL2_CH_STRUCT ch1, ch2;
char *pName[2] = {NULL,NULL};

и strcpy(ч1.sChannelName, изъятия[0]);
..ошибка C2664: 'strcpy': не удается преобразовать параметр 1 из 'unsigned char [80]' в 'char *'
..Типы, на которые указывают, не связаны; преобразование требует reinterpret_cast, приведения в стиле C или приведения в стиле функции


Ошибка №3:
int ret;
CANL2_CH_STRUCT ch1, ch2;
PRAEDEF int MIDDEF INIL2_initialize_channel(CAN_HANDLE *pu32ChannelHandle, char *pChannelName); / / CANL2. H

рэт = INIL2_initialize_channel(&ампер;ч1.ulChannelHandle, ч1.sChannelName);
..ошибка C2664: 'INIL2_initialize_channel': не удается преобразовать параметр 2 из 'unsigned char [80]' в 'char *'
..Типы, на которые указывают, не связаны; преобразование требует reinterpret_cast, приведения в стиле C или приведения в стиле функции

Jochen Arndt

Это происходит потому, что пример кода-это C, в то время как вы используете C++, который имеет более сильную проверку типов.

Просто сделайте то, что предлагают сообщения об ошибках: используйте кастинг.

pBuffer = (PCHDSNAPSHOT)malloc(u32NeededBufferSize);
strcpy((char*)ch1.sChannelName, pName[0]);
ret = INIL2_initialize_channel(&ch1.ulChannelHandle, (char*)ch1.sChannelName);

mraaf

Большое спасибо. Он работает как шарм.