Главная arrow Программирование arrow AVR arrow AVR-USB-MEGA16: быстрая разработка USB приложений на C# при помощи класса-обертки ATMega16 Monday, May 22 2017  
ГлавнаяКонтактыАдминистрированиеПрограммированиеСсылки
UK-flag-ico.png English Version
GERMAN-flag-ico.png Die deutsche Version
map.gif карта сайта
нашли опечатку?

Пожалуйста, сообщите об этом - просто выделите ошибочное слово или фразу и нажмите Shift Enter.

Поделиться:

AVR-USB-MEGA16: быстрая разработка USB приложений на C# при помощи класса-обертки ATMega16 Версия для печати
Написал Сергей Кухтецкий   
18.06.2009

При разработке систем на базе микроконтроллеров (МК), подключенных каналом связи к персональному компьютеру (ПК), разработчик сталкивается с проблемой одновременной (параллельной) разработки как ПО хоста, так и firmware для микроконтроллера. Это утомительный, итерационный процесс, связанный с переключением внимания на различные среды разработки.

Поскольку при работе с реальными сигналами и устройствами средства эмуляции не всегда годятся, возникает еще одно звено в этом процессе – запись firmware в память МК (т. е. «прошивка»). Таким образом, разработчик постоянно находится в процессе переключения между различными видами деятельности и приложениями. Например, внес изменения в программу firmware в текстовом редакторе типа блокнот. Затем скомпилировал, набрав «make hex» в командной строке. Поправил, если что не так. Далее - перешел к программатору и «прошил» МК новоиспеченным hex-файлом. Потом подключил МК к каналу связи (USB в нашем случае) и пошел в средство разработки хоста (например, Visual Studio). Внес изменения в программу хоста, откомпилировал, запустил и понял, что в программе firmware все еще что-то не так. И опять пошел в блокнот, редактировать firmware, попутно испытав стресс, перейдя из Visual Studio в блокнот с командной строкой. В общем, что-то с этим нужно было делать…

Одна из идей, которая помогла существенно облегчить этот процесс, заключается в следующем. Нужно сделать одну универсальную прошивку и класс-обертку для функций этой прошивки на C#, которые позволили бы решать все задачи, связанные со сбором данных, управления внешними устройствами и ресурсами микроконтроллера непосредственно из программы на C# (не выходя из Visual Studio). Т. е. один раз «прошил» МК, и все действия далее - только из хоста. Потом, если, конечно это нужно, часть отлаженного программного обеспечения хоста можно будет перенести в firmware для ускорения процессов или «разгрузки» канала связи или ПК.

Идея заманчивая, но, конечно, в общем случае такая задача вряд ли разрешима. Главная проблема такого тотального «интерпретатора» - катастрофическая потеря производительности и перегруженность канала связи. Кроме этого, часть процессов МК в принципе нельзя (или очень трудно) «перенести» на хост. Например, - обработка прерываний, высокоприоритетные, критические по времени выполнения операции и т.п.

Тем не менее оказалось, что для достаточно широкого круга задач такую прошивку и соответствующий класс-обертку можно сделать. Описанию этого решения и посвящена данная статья.

Для работы нам понадобятся следующие программы и «железо»:

1. Средства разработки хоста - свободно доступная Visual Studio 2008 Express Edition, которую можно скачать с сайта Microsoft.

2. Для работы с USB на стороне хоста используется свободная библиотека libusb-win32.

3. Макетная плата AVR-USB-MEGA16.

Если не хотите разрабатывать firmware и сами прошивать микроконтроллер этой платы, Вы можете при покупке платы попросить записать её нужной прошивкой. В противном случае понадобится средство разработки (если хотите сами прошивку скомпилировать). Чтобы записать прошивку-firmware в плату, программатор не нужен, так как макетка имеет встроенный USB-загрузчик (bootloader USBasp).

4. Для самостоятельной компиляции прошивок (если это Вам понадобится) нужен свободно доступный пакет WinAVR. См. также [1].

Исходники и скомпилированные бинарники firmare и ПО хоста, описанные в статье, можно скачать по ссылке [2].

[Firmware]

Круг задач, для которых разработана прошивка и класс-обертка, так или иначе связан с управлением измерительным или исполнительным оборудованием в системах автоматизации, вводом и обработкой полученной информации. Анализ большого количества примеров на эту тему показывает, что если процессы не очень быстрые (т. е. не требуется немедленной реакции микроконтроллера по аппаратным или программным прерываниям), то всю работу с внешними устройствами можно свести к установке или чтению значений портов и регистров ввода/вывода, управляющих периферией микроконтроллера. Если просмотреть файл iom16.h (например, в WinAVR\avr\include\avr), то становится ясно - все эти операции реализованы через макросы _SFR_IO8(адрес) для байтов или _SFR_IO16(адрес) для слов, причем последний макрос обычно дублируется парой байтовых. Например, регистр данных АЦП:

#define ADCW _SFR_IO16(0x04)
#define ADCL _SFR_IO8(0x04)
#define ADCH _SFR_IO8(0x05)

или порт D (для вывода данных):

#define PORTD _SFR_IO8(0x12)

Поэтому при разработке firmware для микроконтроллера ATMega16 в методе usbFunctionSetup() мы можем реализовать всего два (!) запроса, чтобы получить возможность работать с любым портом или регистром ввода/вывода. Наше firmware должно уметь по команде, пришедшей по USB, записать байт по указанному адресу регистров ввода/вывода микроконтроллера и уметь считать байт по указанному адресу.

Давайте так и поступим. Возьмем самый первый и простой пример из пакета AVR-USB – «custom class» и модернизируем его следующим образом (см. файл Main.c).

1. Определим две константы в начале программы в качестве команд:

typedef unsigned char byte; 
#define RQ_IO_READ 0x11 
#define RQ_IO_WRITE 0x12 

2. Выкинем из метода usbFunctionSetup() все «потроха» и напишем туда следующее:

usbMsgLen_t usbFunctionSetup(uchar data[8]) 
{
   usbRequest_t *rq = (void *)data;
   byte addr = rq->wIndex.bytes[0]; // Адрес порта или регистра
   byte val = rq->wValue.bytes[0];  // Значение для записи 
   switch(rq->bRequest)
   {//---------------------------------------------------------- 
    // Работа с портами и регистрами ввода/вывода. 
    //---------------------------------------------------------- 
   case RQ_IO_READ:                 // Чтение байта с порта ввода/вывода
      dataBuffer[0] = _SFR_IO8(addr);
      usbMsgPtr = dataBuffer; 
      return 1; 
   case RQ_IO_WRITE:                // Запись байта в порт ввода/вывода
      _SFR_IO8(addr) = val; 
      return 0; 
   }
   /* default для не реализованных запросов:
      на хост обратно данные не возвращаются */ 
   return 0;
}

3. И это – все. Скомпилируйте и прошейте микроконтроллер полученной прошивкой. Ни компилятор C для AVR, ни программатор нам больше не понадобятся.

Действительно, теперь мы можем прямо из хоста делать много полезного. В частности:
• «Дергать» любой доступный пин любого порта (PORTX), управлять направлением потока данных (DDRX) или читать с портов (PINX).
• Работать с любыми регистрами ввода/вывода. Например, проинициализировать, запустить и считать данные с АЦП или настроить и запустить аппаратный ШИМ на таймере TIMER1 и так далее (можно пойти почти по всей периферии микроконтроллера, там где не является обязательным условием использование прерываний).

Для этого в приложении хоста нам нужно всего лишь вызывать функцию usb_control_msg() библиотеки libusb с нужными параметрами. В параметрах этой функции мы должны указать тип запроса (собственно, направление передачи данных - RQ_IO_READ или RQ_IO_WRITE), адрес регистра или порта (addr) и еще значение (val), если мы пишем в порт или регистр. При чтении данные передаются в хост через первый байт буфера (тоже параметр функции usb_control_msg()), поскольку в данной реализации мы работаем с 16-разрядными регистрами только побайтно.

Другие элементы firmware (циклы, ветвления, вычисления и т. п.) вполне можно делать и на стороне ПО хоста, тем более что вычислительные ресурсы хоста существенно превышают ресурсы микроконтроллера.

Однако у такого подхода есть и серьезные ограничения. Он не будет работать, если нам нужна точная синхронизация процессов или их жесткая временнАя привязка к каким-нибудь внешним или внутренним событиям микроконтроллера. Если, например, нам необходимо немедленно реагировать по прерываниям или просто выполнять команды очень быстро (в этом случае будет сильно тормозить реализация USB в AVR-USB-MEGA16), то придется расширять firmware соответствующими модулями и обработчиками. Но, как показал опыт, для многих задач этого может и не потребоваться.

Прошивку вместе с исходниками вы можете взять из архива "firmware simple.zip", который находится в общем архиве [2].

Итак, половина дела (firmware) сделано. Мы превратили микроконтроллер платы AVR-USB-MEGA16 в интеллектуальное устройство ввода/вывода с богатой периферией, которое настраивается и управляется хостом по USB. Перейдем теперь к программному обеспечению хоста.

[ПО хоста - класс-обертка ATMega16]

При наличии достаточных вычислительных ресурсов объектно-ориентированный подход существенно «просветляет» мозги разработчика, освобождая его от рутины и давая возможность оперировать более крупными сущностями на более высоком уровне абстрагирования. Вычислительных ресурсов у нас в хосте достаточно. Поэтому для работы с микроконтроллером на языках .NET, будем использовать класс-обертку на C# - ATMega16. Этот класс я сконструировал так, что в программе хоста микроконтроллер выглядит как некое логическое устройство (объект класса ATMega16). Свойства этого устройства - порты и регистры ввода/вывода микроконтроллера. Кроме того, в этом классе инкапсулированы вспомогательные переменные, константы и вызовы, необходимые для работы с USB при помощи библиотеки libusb. Т. е. про USB пользователь (точнее - разработчик) ничего не знает (канал абсолютно прозрачен). Таким образом, в программе хоста на C# или Visual Basic мы можем создать объект класса ATMega16, передав конструктору параметры VID и PID. После создания объекта (пусть его зовут - dev), мы можем изменять его свойства (например, dev.PORTB |= 0x01) или читать значения этих свойств (например, bool flag = (dev.PORTC & 0x08) != 0). В реальности при этих присваиваниях будет производиться передача команды по USB, дешифрация её микроконтроллером, запись в порт или чтение из него и передача данных по USB обратно в ПО хоста, но в программе это выглядит просто как работа со свойствами объекта dev.

Исходный текст базового варианта класса-обертки можно взять в архиве «ATMega16 simple.zip» (находится в общем пакете [2]). Рассмотрим структуру класса чуть подробнее.

Пространство имен, в котором существует класс – AvrUsbDevice. Сам класс объявлен с ключевым словом unsafe, потому что в нем используются структуры и методы библиотеки libusb-win32, содержащей небезопасный код. В связи с этим при компиляции приложений, содержащих класс-обертку ATMega16, необходимо разрешить компилятору использовать небезопасный код. Для этого в свойствах проекта на закладке Build нужно включить флажок Allow unsafe code.

Класс ATMega16 состоит из двух больших блоков. В первом – все что связано с библиотекой libusb-win32 и USB. Он состоит из трех разделов – определения констант, определения на C# структур данных библиотеки libusb, импорт и объявление нужных функций этой библиотеки.

Второй блок содержит все необходимое для работы с микроконтроллером. В первом разделе – адреса портов, регистров ввода/вывода, имена пинов портов и битов регистров ATMega16. В конструктор класса передаются два параметра. Это - VID и PID USB-устройства. Далее в конструкторе происходит инициализация USB и поиск устройства. Успешность инициализации USB можно проверить вызовом метода IsOpen().

Следующие разделы содержат определения свойств класса, связанных с портами и регистрами периферии микроконтроллера (в данной версии класса-обертки - только АЦП и 16-разрядный таймер). Вы можете самостоятельно дополнить класс своими необходимыми свойствами (например – работой с памятью EEPROM, FLASH и RAM, firware при этом нужно соответственно доработать – добавить команды по аналогии с RQ_IO_READ и RQ_IO_WRITE). В методах set/get этих свойств как раз используются вызовы функции usb_control_msg() с соответствующими параметрами.

При разработке приложения необходимо включить класс-обертку ATMega16 в разрабатываемый проект и сделать доступным пространство имен AvrUsbDevice. Кроме этого, должна быть установлена библиотека libusb-win32 (файл libusb0.dll должен быть в папке исполняемого файла приложения или в другой папке, указанной в переменной окружения PATH).

Ниже представлена пошаговая инструкция по созданию простого приложения с использованием класса ATMega16.

[Разработка простейшего приложения – мигаем светодиодом по USB]

1. Запускаем Visual C# 2008 Express Edition.

2. Создаем новый проект, подключаем класс-обертку ATMega16 и настраиваем его свойства. Для этого проделаем следующие манипуляции.

2.1. Щелкаем меню File/New Project

2.2. На панели шаблонов New Project выбираем «Windows Forms Application» и снизу панели вводим имя проекта «LedTest» и нажимаем «Ok».

2.3. Через некоторое время на экране появится пустая форма.

2.4. Сохраним весь проект, выбрав пункт меню File/Save All. На панели диалога сохранения файла указываем папку, в которой мы хотим сохранить проект. Жмем Ok и в этой папке у нас появится новая папка с названием LedTest, в которой будут сохранены все файлы нашего проекта. Файл LedTest.sln это, собственно, файл проекта, а все наши программистские действия в данной простой программе будут находиться в файле Form1.cs.

2.5. Скопируем в эту папку файл с классом-оберткой ATMega16.cs и подключим этот объект к нашему проекту. Для этого щелкнем пункт меню Project/Add Existing Item… В открывшемся диалоге выберем файл ATMega16.cs и нажмем кнопку Add. Можно видеть, что в окне Solution Explorer появился новый объект ATMega16.cs.

2.6. Выполним настройку проекта – разрешим использование небезопасного кода. Это необходимо, поскольку класс ATMega использует небезопасный код, что и указано ключевым словом unsafe в объявлении класса (см. файл ATMega16.cs). Для этого откроем панель свойств проекта (меню Project/LedTest Properties), перейдем на закладку Build и поставим флажок в свойстве «Allow unsafe code».

3. Теперь приступим к содержательной части задачи. В окне Solution Explorer щелкните правой кнопкой мыши на объекте Form1.cs. В контекстном меню выберите пункт View Code. В главном окне вы увидите текст кода нашей главной формы.

3.1. Добавим пространство имен AvrUsbDevice, в котором находится класс-обертка ATMega16. Для этого после строки

using System.Windows.Forms;

добавьте строку

using AvrUsbDevice;

3.2. Сразу же после заголовка класса Form1 объявим переменные:

bool ledOn = false;  // Если ledOn равен true, то светодиодик 
                     // на плате включен 
ushort vid = 0x16C0, pid = 0x05DC; // VID и PID 
ATMega16 dev;        // Объявляем объект типа ATMega16

3.3. Создание объекта dev лучше всего выполнить при загрузке главной формы приложения. При этом генерируется событие Load. В обработчик этого события (метод Form1_Load()) мы и вставим создание объекта dev. Для этого перейдем на закладку дизайнера формы в главном окне (Form1.cs [Design]) и сделаем двойной щелчок по форме нашего будущего приложения. В коде главной формы появится шаблон:

private void Form1_Load(object sender, EventArgs e) 
{
}

Внутрь этого шаблона (в фигурные скобки функции Form1_Load) мы вставим следующий код:

dev = new ATMega16(vid, pid); // Создаем объект dev класса ATMega16
if (!dev.IsOpen())
{
   // Если есть проблемы с USB – сообщим и выйдем
   MessageBox.Show(
      String.Format(
         "Невозможно найти устройство vid = 0x{0:X}, pid = 0x{1:X}", vid, pid),
      "Ошибка USB",
      MessageBoxButtons.OK, MessageBoxIcon.Error); 
   Close(); 
} 
else 
{
   // Если все хорошо, настроим микроконтроллер по USB 
   dev.DDRB |= 0x01;  // Пин 0 порта B - на вывод – там светодиодик 
   dev.PORTB &= 0xFE; // Выключим светодиодик на плате 
}

3.4. Теперь разместим на форме кнопку, при помощи которой мы будем включать и выключать светодиодик на плате. Для этого опять перейдем в дизайнер формы и из Toolbox-а перетащим на форму кнопку.

3.5. Создадим обработчик события нажатия кнопки. Для этого сделаем двойной щелчок по изображению кнопки на форме. В коде формы появится шаблон

private void button1_Click(object sender, EventArgs e) 
{
}

3.6. Внутрь этого шаблона вставим код:

ledOn = !ledOn;
if (ledOn) 
   dev.PORTB |= 0x01; // Включим светодиодик на плате, PB0 = 1 
else 
   dev.PORTB &= 0xFE; // Выключим светодиодик на плате, PB0 = 0

4. Теперь проверим работу нашей программы и прошивки.

4.1. Подключим прошитую плату AVR-USB-MEGA16 к разъему USB персонального компьютера. На хосте-компьютере должна быть предварительно установлена библиотека libusb.

4.2. Компилируем и запускаем на выполнение наше приложение (ну просто нажимаем F5). Если все правильно воткнуто, прошито, собрано и написано, то на экране появится главное окно приложения с одной кнопкой. Нажимая на эту кнопку, мы сможем включать и выключать светодиодик, расположенный на плате AVR-USB-MEGA16 (см. Рис.1).
classCsharp-mega16-01.jpg
Рис.1. Вид работающего приложения и горящего светодиодика

Полностью готовый проект можно найти в архиве «host simple.zip» [2]. Более сложные примеры использования расширенного класса-обертки ATMega16 и расширенного firmware смотрите в ссылках статей AVR-USB-MEGA16: измеряем и контролируем температуру и AVR-USB-MEGA16: новая жизнь старого «Милихрома».

Байты перемычек (fuse bits) ATmega16 должны быть 0xFF (low) и 0x09 (high). 

S.V.Kukhtetskiy, 2009
Кухтецкий Сергей Владимирович,
лаборатория проблем материаловедения,
Институт химии и химической технологии СО РАН, Красноярск
E-mail: ku@icct.ru

[UPD120530]

Устройство USB, работающее с классом-оберткой, на самом деле USB HID, которому драйвера не должны быть нужны. Однако Windows спрашивает драйвер из-за какой-то ошибки в реализации прошивки микроконтроллера, поэтому драйвер все-таки нужен. Драйвер для устройства USB можете найти в архивах [2, 3], см. driver-vanoid.ru.

[Ссылки]

1. Разработка устройства USB - как начать работу с библиотеками AVR USB и libusb.
2. Исходники и скомпилированные бинарники firmare и ПО хоста, описанные в статье - 090617atmega16-Csharp-class.zip.
3. 101022V-USB-Csharp-libusb.zip - здесь я собрал в одном архиве все исходники программ, описанные в статье (ПО хоста и firmware), а также скомпилировал прошивки на все варианты частот кварцев для микроконтроллеров ATmega16 и ATmega32.

Последнее обновление ( 23.08.2012 )
 

Комментарии  

  1. #42 Никита
    2015-02-0220:22:30 Там используется Hidlibrary.h. Все так просто и, главное, работает! Но возникает вопрос, можно ли эту библиотеку прикрутить, например, к .net приложению? Если да, то сегодня же бросаю книжку по CBuilde и принимаюсь раскуривать c#))) Цель - быстро и просто реализовать связь ПО хоста - микроконтроллер на основе V-USB. Связка из вышеуказанной статьи не подходит только из-за невозможности создания х64 приложений))). И еще вопрос по HIDLibrary, вдогонку, возможно ли с ее помощью реализовать обмен не в функциях read и write. а в usbFunctionSetu p (как я понял, при такой реализации firmware получается несколько меньше)?

    microsin: со многим готов не согласиться. Библиотека x64 есть и 64-битной версии. Наверное даже есть её исходные коды, так что пользуйтесь на здоровье. По крайней мере на моем ноуте с Windows 8.1 x64 все замечательно работает: софт ПО хоста от Сергея Кухтецкого на основе LibUSB и макетная плата AVR-USB-MEGA16. Проблемы есть, конечно - с установкой драйвера фильтра, с установкой библиотеки, с отсутствием подписи (сертификата) драйвера, но они технические, и вполне себе решаемы. По крайней мере пусть геморрой, но жить можно. Не нравится - пользуйтесь в программировани и (на любом языке, не обязательно на C++, пишите хоть на Java, хоть на Бейсике) другими библиотеками (ключевые слова для поиска Библиотеки USB HID). Или обращайтесь к первоисточнику - к интерфейсу базовой HID.dll. Именно её и используют все библиотеки, они по сути обертки над функционалом HID.dll.

    По поводу раскуривания C# - это Вам в любом случае не повредит. По HIDLibrary ничего не подскажу - не использовал её. Но в принципе Вы могли бы сделать на её основе в том же CBuilder (или в MS Visual Studio) обычную DLL, и использовать в ЛЮБОМ ЯЗЫКЕ, который позволяет загружать DLL и использовать её функции. Сейчас подобным образом многие используют LibUSB - с её помощью программируют работу с устройствами USB на любом языке программировани я.

    Напрямую шаблоны классов из Hidlibrary.h использовать в приложении C# нельзя. Но через импорт функций из DLL - можно. Можно также портировать код из шаблонов C++ в код C#, если Вы хорошо разбираетесь в синтаксисе шаблонов C++ и вообще в языках C++ и C#. Подозреваю, что пока не очень, раз задаете такие вопросы, но у Вас действительно все впереди - много интересных свершений и открытий!
  2. #41 Никита
    2015-02-0220:19:09 К счастью я еще плохо разбираюсь во всем этом и все у меня еще впереди. http://microsin.ru/components/com_jcomments/images/smiles/lol.gif Как следствие - я плохо ориентируюсь даже в большом разнообразии ГОТОВЫХ решений (связок firmware-host). Мне понравилась реализация XANDER из статьи "USB для AVR. Часть 2. HID Class на V-USB". Собрал, все само определилось, программка тестовая работает отлично. Но там хост собран на основе с++builder 6, и, возможно, несколько лет назад это было еще актуально, но сейчас на множестве устройств рулит х64 и, естественно, хочется универсальности в пределах windows.

    microsin: если мне не изменяет память, то упомянутый Вами код от XANDER (заголовочный файл hidlibrary.h) - всего лишь набор шаблонных классов C++, поэтому Вам вовсе не обязательно его компилировать вместе с устаревшим CBuilder 6. Т. е. Вы можете с успехом этот код использовать в системе программировани я Visual Studio или любой другой среде, позволяющей программировать на C++ и писать приложения на любой Windows-платформе (в том числе и на x64). Кто запрещает?
  3. #40 Никита
    2015-02-0215:51:46 Объясните, пожалуйста, можно ли так скомпоновать приложение хоста, используя эту "обертку", чтобы не приходилось на каждый компьютер устанавливать libusb, фильтры, а, например, просто положить DLL в папку с программой? Будет ли работать такая программа на windows x64?

    microsin: к сожалению, чтобы все было именно так, как Вы хотите, нужно написать специальный инсталлятор, который будет поддерживать все версии имеющихся операционных систем. Пока что такого инсталлятора нет. Если Вы хорошо разбираетесь в программировани и, то можете заменить библиотеку LibUSB на библиотеку HID.dll, тогда не потребуется специальная установка для DLL (потому что HID.dll уже встроена в систему Windows), и не понадобится устанавливать драйвер фильтра.

    Кстати говоря, на LibUSB свет клином не сошелся. Есть много других библиотек для ПО хоста.
  4. #39 Никита
    2015-01-1402:26:50 3 часа ночи. Я после работы решил почитать гугл на тему разработки USB устройств дома… Я просто в шоке!!! Я в первый раз вижу такую работу!!! Еще не пробовал, естественно, но ОГРОМНОЕ ЧЕЛОВЕЧЕСКОЕ СПАСИБО Сергею!!! Вот так, от и до… Прошивки под все кварцы и частоты чуть не выбили слезу. Я думал, что такого не бывает. Еще раз, спасибо ОГРОМНОЕ!!!
  5. #38 Алексей
    2014-02-2013:53:02 В коде есть строка "if (!dev.IsOpen())", т. е. если указатель на устройство есть и оно открыто, то работаем. А как проверить в процессе работы наличие устройства? Если как по коду то оно открыто и его не закрывали, и проверка на открыто не проходит.

    microsin: если устройство открыто, то нет смысла его проверять на "открытость". Если хотите все-таки проверить, то закройте его и проверяйте на здоровье.
  6. #37 Виктор
    2013-08-2903:41:15 При запуске LedTest.exe пишет:
    "Ошибка USB
    —————————————-
    Невозможно найти устройство vid = 0×16C0, pid = 0×5DF"

    microsin: либо неправильно прошит микроконтроллер , либо неисправна схема, либо Вы не установили драйвер фильтра библиотеки LibUSB.
  7. #36 Туен
    2013-07-2101:31:06 Можно управлять периферийным устройством, имеющее интерфейса SPI, например, АЦП, ЦАП, датчиком с этим классом?

    microsin: можно. Класс специально для этого и предназначен.
  8. #35 Вова Третьяков
    2013-05-2015:46:28 А можно узнать, насколько медленно данные могут передаваться между хостом и устройством, и главное какая реакция на них? Я занимаюсь проблемой умного дома, и хотел бы через USB собирать данные с датчиков, управлять устройствами, в том числе и с помощью ШИМ, и общаться с другими устройствами через UART. А в Вашей статье предлагается вариант всех вычислений на хосте, а железо только для общения. Если я возьму ATmega16 или ATmega32, и задействую 3 порта со всеми функциями, оно у меня не зависнет с концами?

    microsin: зависнет или нет - зависит исключительно от Вас.
  9. #34 harik
    2013-01-3014:42:25 Проблему решил методом научного тыка. В проекте WinFormsApp все-таки ничего не работает: раньше я проверял, открывая проекты Сергея Кухтецкого из архива (оно работает, как часы). Потом решил написать что-нибудь самостоятельно. Код, буква в букву идентичный коду Сергея, вызывает ту же ошибку.
    Меня посетила мысль: может, где-то в настройках проекта что-нибудь различается? Облазил все, что смог придумать: каждая галочка и каждый символ совпадает.
    В конце концов решил сменить назначение проекта: и у меня, и у автора класса там стоит "Net Framework 4". Я же выбрал "Net Framework 3.5 Client" - и все компилируется без проблем. Почему так - понять не могу, но, может, кому-то и окажется полезным.
  10. #33 harik
    2013-01-3012:32:54
    Цитирую harik:
    Возникла необходимость использовать этот класс-обертку в WPF-приложении (VS2010 C#). При попытке вызвать open_device(dev ) возникает ошибка разбалансировки стека. Моих познаний в программировани и не хватает, чтобы разобрать ошибку самостоятельно или даже с помощью поиска в Google. Если же использовать WinFormsApp, то проблемы не возникает - все работает, как положено.

    microsin: попробуйте сделать DLL на основе класса-обертки, и в Вашем проекте WPF используйте функции из этой DLL.

    В том-то и проблема, что при объявлении функции unsafe из внешней DLL возникает рассогласование сигнатур (причем только в том случае, когда функция возвращает значение). Из найденных в сети материалов я усвоил, что функция кладет в стек не то число байт, которое ожидает компилятор. Там же указывается, что чаще всего это случается из-за рассогласования типов и рекомендуется заменить некоторые 64-bit типы на 32. Какие именно - понять не смог. Равно как и задать нужный атрибут.

    microsin: вообще-то я не настолько разбираюсь в C#, чтобы давать Вам советы. Во-первых, Вы можете сделать не функцию, а процедуру, которая модифицирует глобальные переменные класса, или переменные по переданному в процедуру указателю. Во-вторых, Вам нужно попробовать скомпилировать Ваш проект в режиме unsafe. Обратитесь пожалуйста к соответствующей документации в MSDN.

Добавить комментарий

:D:lol::-);-)8):-|:-*:oops::sad::cry::o:-?:-x:eek::zzz:P:roll::sigh:

Защитный код
Обновить

< Пред.   След. >

Top of Page
 
microsin © 2017