В предыдущей статье мы рассмотрели преобразователь USB to SPI на базе MCP2210
Итак, давайте разберемся как же общаться с устройствами подключенными к модулю MCP2210 через SPI (на AliExpress м/с MCP2210 стоит около 2$). Для этого из моего ящика была вытащена микросхема MAX1240, которая представляет собой АЦП с передачей данных по SPI. Довольно интересная микросхема в DIP корпусе, что позволяет собрать всю тестовую схему на беспаечной макетной плате. Собранная схема приведена ниже.
MAX1240 подключена по типовой схеме, питание 3.3 В берется со стабилизатора, находящегося "на борту" модуля MCP2210. У АЦП имеется выход опорного напряжения 2.5 В, подаем его на вход для оцифровки через потенциометр по схеме обычного делителя напряжения, тем самым мы можем менять напряжение на входе от 0 до 2.5 В. На этом мы заканчиваем подготовительные работы.
Скачиваем библиотеку MCP2210 по следующему адресу:
http://ww1.microchip.com/downloads/en/DeviceDoc/MCP2210_DLLv2.zip
Я буду показывать работу с модулем на примере языка C#. На других языках работа с модулем аналогична, пожалуйста внимательно прочитайте документацию!
Создаем новый консольный проект C# в Visual Studio 2010 (далее VS2010). Для начала необходимо добавить скаченную библиотеку к нашему проекту. Открываем архив и извлекаем все файлы. Теперь во вкладке Обозреватель решений в проекте VS2010 кликаем правой кнопкой на пункте Ссылки, выбираем Добавить ссылку. Переходим на вкладку Обзор и указываем путь до файла mcp2210_dll_m_dotnetv4_x86.dll и вот тут важно, во-первых, если вы использует C# или VisualBasic, то нужно использовать файл с буквой m - managed. Данная библиотека использует .Net и не будет работать на других языках! Для других языков в папке unmanaged есть файлы для импорта в ваш проект. Работа на других языках очень похожа, отличия минимальны! Так же в зависимости от версии установленного в системе .Net фрэймворка нужно выбирать netv2 или netv4 соответственно. Ну и последний момент, это разрядность системы. Выбрали библиотеку и нажимаем OK.
С этого момента, библиотека добавлена в проект. Вверху проекта дописываем строчку:
using mcp2210_dll_m;
Следующим шагом станет проверка подключен ли модуль, и далее создаем объект, закидываем ему настройки и передаем! Приведу сразу весь текст программы:
int error = 0; ushort chislo = 0; double znachenie = 0; //проверяем подключен ли модуль error = MCP2210.M_Mcp2210_GetConnectedDevCount(0x4D8, 0xDE); //стандартные VID и PID у модуля MCP2210 if (error == 0) { Console.WriteLine("Error! Not connected module!"); Console.ReadKey(); } else { Console.WriteLine("Module connected! Let's open!"); // открываем модуль StringBuilder Path = null; IntPtr module = MCP2210.M_Mcp2210_OpenByIndex(0x4D8, 0xDE, 0, Path); //настраиваем параметры модуля //скорость передачи данных uint rate = 10000; //настройка выводов CS uint cs_idle = 0xFFFFFF; uint cs_activ = 0xFFFFEF; //задержки всякие uint cs_to_data_dly = 0; uint data_to_data_dly = 0; uint data_to_cs_dly = 0; //количество байт передачи/приема uint numberbyte = 2; //режим SPI byte spi_mode = (byte)MCP2210.M_MCP2210_SPI_MODE0; //создаем массивы, важно, чтобы массивы были не пустыми! byte [] Tx = new byte[2]; byte [] Rx = new byte[2]; while (true) { //данная команда сразу и настраивает модуль и запускает передачу/прием пакетов error = MCP2210.M_Mcp2210_xferSpiDataEx(module, Tx, Rx, ref rate, ref numberbyte, 0x10, ref cs_idle, ref cs_activ, ref cs_to_data_dly, ref data_to_cs_dly, ref data_to_data_dly, ref spi_mode); if (error != 0) { Console.WriteLine("Error! Not reseved data!"); } else { //на данном этапе, в массиве Rx хранятся принятые 2 байта данных с АЦП //дальнейшие "пляски" связанны с его обработкой и переводом в вольты //исправляем порядок битов, переворачивая их Array.Reverse(Rx); //сшиваем массив из двух байтов в одно число 2 байтное (важно!) chislo = BitConverter.ToChar(Rx, 0); //скидываем влево все число пропадает старшая единица, не несущая информации chislo = (ushort)(chislo << 1); //сдвигаем все байты вправо (данные 12 бит, а принятых 16) chislo = (ushort)(chislo >> 4); //по формуле из datasheet переводим в вольты znachenie = chislo * 0.00061; //выводим и радуемся Console.WriteLine(znachenie); } //повторяем это все пока не надоест с такой вот паузой System.Threading.Thread.Sleep(100); } }
На самом деле все очень просто. В видео к статье я продемонстрирую работу этого кода и расскажу как он работает! Но думаю, по комментариям в коде и так, не сложно разобраться.
В данном примере мы воспользовались функцией xferSpiDataEx, которая упрощает передачу, в ней одновременно задаются и параметры модуля и передача/прием. Но данная функция не совсем подходит, если нам необходимо расширить возможности модуля. И тут я имею ввиду, если мы хотим по полной использовать 9 выводов GPIO. Давайте разберем, что же они могут.
Все 9 выводов GPIO имеют 3 режима работы. В первом режиме GPIO, они используются как обычные цифровые входы/выходы, т.е. программно можно выставить или считать любой уровень на нужном выводе. Во-втором режиме CS, которые используются для передачи данных, выбранный вывод используется как выход разрешения. В этом режиме настраиваются задержки срабатывания CS, уровень CS (инверсный или нет). И наконец третий режим, в котором у каждого вывода есть своя собственная функция. Однако большая часть этих функций может и не пригодиться обычному обывателю, лично я, иногда, использую SPI Transfer Traffic LED. На вывод GPIO3 вешаю светодиод с резистором для наглядного контроля передачи данных. Но как видно, микросхема обладает и прерыванием, честно скажу не придумал когда это может пригодится, но если пригодится я буду знать, что оно есть! А вот в первом режиме выводов - GPIO, я придумал что можно сделать!
Видоизменим нашу схему на макетной плате.
Теперь давайте напишем тот же код что и раньше добавив использование кнопки в качестве старт/стоп измерений, а светодиод пусть загорается для индикации этой кнопки (стоп - не горит/ старт - горит).
Опять же, приведу сразу весь текст программы.
int error = 0; ushort chislo = 0; double znachenie = 0; uint work = 0; //проверяем подключен ли модуль error = MCP2210.M_Mcp2210_GetConnectedDevCount(0x4D8, 0xDE); //стандартные VID и PID у модуля MCP2210 if (error == 0) { Console.WriteLine("Error! Not connected module!"); Console.ReadKey(); } else { Console.WriteLine("Module connected! Let's open!"); // открываем модуль StringBuilder Path = null; IntPtr module = MCP2210.M_Mcp2210_OpenByIndex(0x4D8, 0xDE, 0, Path); //настраиваем параметры модуля //скорость передачи данных uint rate = 10000; //настройка выводов CS uint cs_idle = 0xFFFFFF; uint cs_activ = 0xFFFFEF; //задержки всякие uint cs_to_data_dly = 0; uint data_to_data_dly = 0; uint data_to_cs_dly = 0; //количество байт передачи/приема uint numberbyte = 2; //режим SPI byte spi_mode = (byte)MCP2210.M_MCP2210_SPI_MODE0; //создаем массивы, важно, чтобы массивы были не пустыми! byte[] Tx = new byte[2]; byte[] Rx = new byte[2]; //переменная светодиода uint svetik = 1; //создаем переменную, в которой хранится состояние GPIO uint resvet = 0; //настраиваем GIPO все выводы GPIO, кроме GPIO4, который CS byte [] gpio = {0x00,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x00}; //настраиваем GPIO MCP2210.M_Mcp2210_SetGpioConfig(module, (byte)MCP2210.M_MCP2210_VM_CONFIG, gpio, 0, 0, (byte)MCP2210.M_MCP2210_REMOTE_WAKEUP_DISABLED, (byte)MCP2210.M_MCP2210_INT_MD_CNT_NONE, (byte)MCP2210.M_MCP2210_SPI_BUS_RELEASE_DISABLED); MCP2210.M_Mcp2210_SetSpiConfig(module, (byte)MCP2210.M_MCP2210_VM_CONFIG, ref rate, ref cs_idle, ref cs_activ, ref cs_to_data_dly, ref data_to_cs_dly, ref data_to_data_dly, ref numberbyte, ref spi_mode); while (true) { //считываем значение кнопки MCP2210.M_Mcp2210_GetGpioPinVal(module, ref resvet); if ((resvet & 0x01) == 1) Сhange(ref work, ref svetik);//функция просто меняет 0 на 1 и наоборот if (work == 1) { error = MCP2210.M_Mcp2210_xferSpiData(module, Tx, Rx, ref rate, ref numberbyte, 0x10); if (error != 0) { Console.WriteLine("Error! Not reseved data!"); } else { //на данном этапе, в массиве Rx хранятся принятые 2 байта данных с АЦП //дальнейшие "пляски" связанны с его обработкой и переводом в вольты //исправляем порядок битов, переворачивая их Array.Reverse(Rx); //сшиваем массив из 2 байтов в одно число 2 байтное (важно!) chislo = BitConverter.ToChar(Rx, 0); //скидываем влево все число пропадает старшая единица, не несущая информации chislo = (ushort)(chislo << 1); //сдвигаем все байты вправо (данные 12 бит, а принятых 16) chislo = (ushort)(chislo >> 4); //по формуле из datasheet переводим в вольты znachenie = chislo * 0.00061; //выводим и радуемся Console.WriteLine(znachenie); } } //включаем или выключаем светодиод if (svetik == 0) { MCP2210.M_Mcp2210_SetGpioPinVal(module, 128, ref resvet); } else { MCP2210.M_Mcp2210_SetGpioPinVal(module, 0, ref resvet); } //повторяем это все пока не надоест с такой вот паузой System.Threading.Thread.Sleep(100); } }
Демонстрация работы данного кода в видео!
В коде видно, что появились функции SetGpioConfig и SetSpiConfig. Именно эти функции настраивают модуль, после чего простенькой функцией xferSpiData происходит обмен данными. Да, функция Change выглядит следующим образом:
static void Сhange(ref uint work, ref uint svetik) { if (work == 0) { work = 1; svetik = 0; } else { work = 0; svetik = 1; } }
Итак, вот собственно и все! Работать с модулем MCP2210 Breakout Module не так уж и сложно! Если у вас появились вопросы задавайте или читайте datasheet на MCP2210. Там все очень хорошо и подробно описано. Все необходимые файлы я аккуратно упаковал в архив и приложил к статье. Так что, дерзайте!
Прикрепленные файлы:
- MCP2210.rar (3457 Кб)
Комментарии (8) | Я собрал (0) | Подписаться
Для добавления Вашей сборки необходима регистрация
[Автор]
[Автор]
[Автор]