Доска разработки quark d2000: переход за пределы «привет мир»

Доска разработки quark d2000: переход за пределы «привет мир»
Доска разработки quark d2000: переход за пределы «привет мир»
Anonim

Совет развития Quark D2000: Перемещение за пределы «Hello World»

В первой части этой серии мы представили новый совет по разработке микроконтроллеров Quark D2000 и рассмотрели некоторые из его многочисленных функций. В этой части мы перейдем к программированию некоторых из этих функций.

Image
Image

Процессор Quark

Предпосылки

Пожалуйста, прочитайте часть первой этой серии для получения дополнительной информации о Quark D2000.

Предполагается, что вы установили программное обеспечение платы D2000, включая Intel System Studio, и успешно выполнили обновление целевого ПЗУ. Кроме того, предполагается, что вы настроили терминал с помощью USB / последовательной платы и кабеля и что вам достаточно знакомы с программным обеспечением Eclipse для компиляции и запуска примера «Hello World», который включен в комплект программного обеспечения.

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

Обязательно ознакомьтесь с такими ресурсами и ресурсами поддержки, которые вы можете собрать. Чтобы начать работу, ознакомьтесь с этими ссылками:

  • Ссылка на главную документацию
  • Форум поддержки микрокомпьютеров Quark

Включенное программное обеспечение

Весь код примера включен для загрузки в конце статьи. Каждый пример отображается как текстовый файл ASCII и предназначен для вырезания и вставки в существующий шаблон, например, для «Hello World», который входит в комплект программного обеспечения.

GPIO

D2000 имеет в общей сложности 25 GPIO, и каждый из них может быть независимо настроен. Все цифровые IO имеют толерантность 3, 3 В; применение напряжений выше 3, 3 В на вывод IO может повредить чип.

Многие из этих GPIO выполняют множество задач, как описано в документации по подключению контактов (PDF). То есть, 25 GPIO могут быть настроены для обслуживания различных функций, установив контакт в один из четырех пользовательских режимов (3: 0). По умолчанию, после сброса питания или холодного сброса все GPIO находятся в пользовательском режиме 0, а пример программ GPIO предполагает, что плата находится в этом режиме.

Чтобы работать с GPIO, нам нужно ознакомиться с структурой qm_gpio_port_config_t, которая определена в qm_gpio.h.

Рассмотрение структуры показывает семь членов ниже. Первый элемент используется для установки регистра направления данных. Остальные шесть членов используются в сочетании с прерываниями, которые могут быть сгенерированы через GPIO:

  • uint32_t направление
  • uint32_t int_en
  • uint32_t int_type
  • uint32_t int_polarity
  • uint32_t int_debounce
  • uint32_t int_bothedge
  • void (* callback) (uint32_t int_status)

Чтобы настроить GPIO, мы сначала устанавливаем экземпляр структуры в нашем коде. Затем мы настраиваем регистр направления данных для конкретного интересующего бита («0» для ввода и «1» для вывода). Впоследствии мы можем читать или записывать бит через определенные функции.

входные

Плата содержит пользовательскую кнопку, изображенную ниже, которая может использоваться в примерной программе для демонстрации чтения входного бита.

Image
Image

Встроенная кнопка пользователя

Ссылаясь на схему платы (PDF), вы можете увидеть (перейти к расчетному листу 7), что имеется нагрузочный резистор (562K) от Vdd к цифровому порту ввода I 5 и к одной стороне коммутатора. Другая сторона переключателя подключена к земле.

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

Сложно определить взаимосвязь между битными выводами порта Quark, схематическими метками, заголовками платы и ссылкой на программный код. Вы можете найти полезные таблицы в руководстве по аппаратным средствам (PDF), руководстве по подключению контактов и, конечно же, полезно использовать схему платы. Например, из схемы вы можете видеть, что цифровой IO5 также называется F2. В таблицах руководства по аппаратным средствам вы можете увидеть, что цифровой IO 5 (DIO_5) помечен как GPIO_2 в пользовательском режиме 0. Наш код будет нуждаться в этой информации.

Простая примерная программа (D2000_Button.txt) предполагает, что вы находитесь в пользовательском режиме по умолчанию 0 и будете считывать состояние коммутатора и распечатывать результат на терминал.

Вот основные моменты программы:

  • «Кнопка» определяется как имеющая значение 2, поскольку мы знаем, что кнопка подключается к GPIO2.
  • Структура типа qm_gpio_port_config_t объявляется как DDRcfg.
  • Бит, связанный с GPIO_2 (т. Е. Бит 2), очищается в переменной направления структуры с помощью инструкции «DDRcfg.direction = 0 << 2;» для настройки бита в качестве входа.
  • С набором структуры мы вызываем qm_gpio_set_config (QM_GPIO_0, & DDRcfg) и передаем два аргумента: QM_GPIO_0, который определяется как значение 0 (плата имеет только один набор GPIO) и адрес нашей структуры «& DDRcfg».
  • Когда GPIO_2 настроен так, как мы хотим, мы можем теперь прочитать состояние бит, используя «qm_gpio_read_pin (QM_GPIO_0, BUTTON)»; который вернет логическое значение для входного бита.

Остальная часть программы просто прочитает и распечатает состояние кнопки и изменит состояние.

Image
Image

Захват экрана выхода программы кнопки

Выходы

Конфигурирование GPIO для вывода следует аналогичным шагам. В следующем примере мы будем мигать светодиодом в качестве демонстрации.

Плата содержит светодиодный индикатор пользователя, и, рассматривая схему, мы видим, что этот светодиод имеет резистор, ограничивающий ток, и переключается с помощью MOSFET, ворота которого подключены либо к DIO 09 (F24), либо к DIO 13 (F16) в зависимости от положение перемычки.

Эта перемычка обозначена как J5, а в позиции «USR» DIO 09 будет управлять светодиодом, и это позиция, которую мы будем использовать для примера программы (D2000_Blink.txt), которая просто мигает светодиодом на 0, 05 Гц.

Image
Image

Перемычка 5 в правильном положении для маршрутизации DIO 09 на бортовой светодиод

Шаги в этом коде аналогичны примеру D2000_Button, за исключением того, что мы определяем светодиод как 24 (GPIO 24), а затем мы устанавливаем соответствующий бит в DDR на «1», используя инструкцию: «cfg.direction = 1 << 24;». После этого мы можем использовать «qm_gpio_set_pin (QM_GPIO_0, LED)»; для включения светодиода и «qm_gpio_clear_pin (QM_GPIO_0, LED)»; чтобы выключить светодиод.

Мы используем функцию «clk_sys_udelay (1000000UL)»; который определен в qm_scss.h, для задержки одной секунды. Аргумент в функции определяет количество микросекунд для задержки (не включая накладные расходы) и зависит от тактовой частоты системы, которая обычно составляет 32 МГц для платы.

Сделать немного звука

В следующем примере (D2000_Beep.txt) мы будем использовать выходной порт для цикла 5v зуммера. То есть, мы включим его на одну секунду и прочь на одну секунду, пять раз.

Зуммер, который я использовал, был старым muRata PKB9-3A0, и он, вероятно, устарел, но большинство любых 5-пьезо-зуммера, которое содержит внутреннюю схему, будут работать.

Мы можем использовать внешний источник питания 5 В для питания зуммера, но помните, что GPIO на D2000 составляет только 3, 3 В.

Один из способов добиться этого - использовать GPIO 5 (DIO4) для управления светодиодной частью оптоизолятора 4N25 через 330-омный резистор. Не уменьшайте значение резистора, так как бит порта может обеспечить только 12 мА (16 мА в режиме высокого напряжения). В моем тестировании также работал резистор 1K.

Транзистор NPN с другой стороны оптоизолятора будет переключать ток через зуммер, как показано на схеме, обозначенной схемой:

Image
Image

Схема интерфейса оптоизолятора / зуммера

Преимущество оптоизолятора заключается в том, что у нас есть изоляция между стороной 5v со стороны D2000 3.3v. Фактически, в этом примере вам не нужно подключать GND D2000 и внешний источник питания GND.

Зуммер, который я использовал, потребляет менее 20 мА, но вы должны проверить характеристики вашего устройства и убедиться, что ток транзисторного транзистора 4N25 оценивается выше нити зуммера.

Сделать тон

Зуммер 5v, используемый выше, имеет внутреннюю схему управления, которая обеспечивает генератор для пьезоэлемента. Эта схема упрощает работу, но ограничивает звук установленной частотой. В следующем примере мы будем использовать магнитный преобразователь (DBX05) для создания тона на программируемой частоте.

Спецификации для используемого преобразователя доступны здесь (PDF) и включают частотную характеристику (переход на стр. 13). Это типичный и недорогой шумоподавитель, который принимает рабочие напряжения от 3 до 8 В.

Однако мы не можем просить выходной порт, чтобы источник 40mA, что устройство может тянуть, поэтому мы заручиться помощью транзистора 2N4401 NPN. Простая схема показана ниже (с идентификацией нескольких использованных частей), и соответствующая программа D2000_Tone будет «воспроизводить» звук 2400 Гц с переменной продолжительностью.

Image
Image

Схема для интерфейса магнитного преобразователя

Мы хотим использовать преобразователь на частоте 2400 Гц, что означает, что период составляет ~ 416, 7 микросекунды.

Для нашей прямоугольной волны выход будет высоким в течение половины периода, а низкий для другой половины. Мы можем реализовать это, просто установив бит и затянув на ~ 208 микросекунд, а затем снизив его на ~ 208 микросекунд. Пока мы повторяем последовательность, мы будем генерировать тон.

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

Обратите внимание, что функция вызывает другую функцию _rdtsc (), которая возвращает unsigned long long (предположительно 64 бита - см. Здесь), содержащую значение таймера. Это функция, которую мы будем использовать для создания моментального снимка внутреннего таймера, который использует 32 тика за микросекунду при нормальной тактовой частоте 32 МГц. Если мы добавим нашу продолжительность к этому значению, мы можем выполнить тест цикла while, чтобы определить, прошла ли продолжительность. Внутри цикла while мы будем переключать выходной бит для достижения желаемой частоты.

Если вы посмотрите на включенную программу D2000_Tone, вы увидите функцию (продолжительность) функции, которая будет воспроизводить тон 2400 Гц в течение продолжительности, указанной в аргументе (в виде 1/32 микросекунды). Основная программа просто выводит некоторый текст на терминал и воспроизводит пять таких тонов продолжительностью в одну секунду, разделенных на 0, 5 секунды, а затем пять тоновых всплесков продолжительностью 0, 25 секунды, также разделенных на 0, 5 секунды.

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

Широтно-импульсная модуляция (PWM)

D2000 имеет два выхода, способных к PWM, и это хорошие новости. Плохая новость заключается в том, что вы можете использовать только один из них, PWM1. На момент написания этой статьи использование PWM0 может вызвать проблемы для некоторых контактов JTAG и предотвратить мигание и отладку платы. Это известная проблема, и, надеюсь, в конечном итоге будет обходной путь.

Поэтому конечный пример (D2000_PWM) будет использовать PWM1.

Выходной бит для PWM1 - F24, DIO 09. Этот бит подключен к встроенному светодиоду (в зависимости от положения J5) - мы использовали этот светодиод в примере D2000_Blink ранее. Поскольку это так удобно, мы будем использовать тот же светодиод для примера PWM.

Чтобы продемонстрировать ШИМ, мы будем увеличивать и уменьшать интенсивность светодиода, изменяя рабочий цикл. Эффект следует рассматривать как своего рода смягченное мигание и его следует легко отличить от программы D2000_Blink.

В этом примере мы сначала объявляем два массива: один для периодов «on» и один для «off» периодов. Эти значения будут определять количество циклов, при которых штифт управляется высоким и низким, соответственно. При добавлении этих значений к одному и тому же числу мы можем легко настроить рабочий цикл в процентах. Затем мы объявляем экземпляр структуры конфигурации qm_pwm_config_t. Если вы посмотрите в файл заголовка qm_pwm.h, вы можете увидеть определения этой структуры, и мы используем следующие элементы:

  • lo_count - Первоначально он установлен в первый элемент нашего «off» периода.
  • hi_count - Первоначально он установлен на первый элемент нашего «on» периода.
  • mask_interrupt - это значение «true», поскольку мы не используем возможности прерывания.
  • mode-set to QM_PWM_MODE_PWM - Это определяется как 10. Это определяет режим PWM в отличие от одного из двух доступных режимов таймера.
  • (* callback). Мы не используем это, так как мы не используем прерывание, но мы будем ссылаться на нашу процедуру обслуживания прерываний, если бы мы это сделали.

Затем мы включаем синхронизацию для периферийного устройства с инструкцией: «clk_periph_enable (CLK_PERIPH_PWM_REGISTER | CLK_PERIPH_CLK);». Значения бит в аргументе определяются в файле заголовка qm_scss.h. Затем мы настраиваем PWM, вызывая функцию qm_pwm_set_config (), используя аргументы, определяющие, что PWM и указывая на нашу конфигурационную структуру.

Прежде чем начать, мы должны настроить вывод для функции 2 с помощью инструкции «qm_pmux_select (QM_PWM_CH_1_PIN, QM_PWM_CH_1_FN_PWM); Помните, что используемый вами штырь мультиплексирован, и мы хотим установить функцию в пользовательский режим 2, который является PWM. Аргументы определены в программе, и они просто являются битами порта (24) и пользовательским режимом (2), соответственно.

Наконец, мы можем запустить PWM с выражением «qm_pwm_start (QM_PWM_0, QM_PWM_ID_1);». Аргументы здесь также использовались при настройке конфигурации, и они могут быть немного запутанными. Я думаю о первом аргументе, поскольку «банк» PWM и плата D2000 имеют только один, поэтому аргумент «0». Второй аргумент определяет, какая PWM внутри банка, а это PWM1. Таким образом, значения аргумента равны 0 и 1 соответственно.

На этом этапе на выводе отображается рабочий цикл, который мы установили, но мы хотим динамически изменять этот рабочий цикл, чтобы увеличить и уменьшить яркость светодиода. Это достигается в циклах for-next, которые циклически проходят через массивы «on» и «off», сначала увеличивая, а затем уменьшая рабочий цикл. Мы делаем это каждые 45 миллисекунд.

Я выбрал девять различных рабочих циклов, и ценности, на мой взгляд, создают приятное увеличение и уменьшение. После цикла 30 циклов заполнения программа заканчивается.

Заключительные мысли

В этой статье рассматривается программирование функций GPIO и PWM платы Quark D2000 Development и предназначено для удобного ознакомления с этими функциями.

Однако включенные примеры только поцарапают поверхность многих возможностей платы, в которую также входят АЦП, I2C, SPI, компараторы и т. Д.

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

Код

Загрузите примеры кода здесь:

Пример кода D2000

Попробуйте этот проект сами! Получить спецификацию.