URC220_QNX (Раздаточные материалы), страница 2
Описание файла
Файл "URC220_QNX" внутри архива находится в следующих папках: Раздаточные материалы, Документация. PDF-файл из архива "Раздаточные материалы", который расположен в категории "". Всё это находится в предмете "программное обеспечение управляющих комплексов (поук)" из 9 семестр (1 семестр магистратуры), которые можно найти в файловом архиве МГТУ им. Н.Э.Баумана. Не смотря на прямую связь этого архива с МГТУ им. Н.Э.Баумана, его также можно найти и в других разделах. Архив можно найти в разделе "остальное", в предмете "поук" в общих файлах.
Просмотр PDF-файла онлайн
Текст 2 страницы из PDF
ВследующемокневыберетеРис.4.1 Настройки нового проектавкладку “Build Variants”, гдеустановите пункты “X86 (Little Endian)” (см. рис.4.1).Новый проект создастся после нажатия на “Finish” в папке “/User_name/de4workspace/test_simple”.В проекте появится файл исходного кода “test_simple.cc” с минимальным кодомдля компиляции.4.2 Пример использованияРассмотрим простой пример, который продемонстрирует запись данных вустройство. Для начала нужно переписать в папку с проектом файлы библиотеки:“stdtypes.h”, “urc220.h” и “urc220.cpp”. Все файлы в каталоге с проектомавтоматически добавляются в проект. Чтобы увидеть их в списке, нажмите наназвание проекта правой кнопкой мыши и выберете пункт меню “Refresh”.9Изменим исходный код. Добавим необходимые заголовочные файлы (в том числефайл библиотеки).
Также прототип функции select_device(), которая понадобитсяв дальнейшем, а также создадим объект класса CURC220, с помощью которого ибудем работать с устройством.//-----------------------------------------------------------#include <stdio.h>#include <stdlib.h>#include "urc220.h"uint32 select_device();CURC220 urc;//------------------------------------------------------------Далее напишем функцию main()://-----------------------------------------------------------int main(int argc, char *argv[]){printf("URC test\n");uint32 index = select_device();if(index == URC_MAXDEV) return EXIT_FAILURE;printf("Opening device %d\n", index);if(!urc.Open(index)){printf("ER: can't open device\n");return EXIT_FAILURE;}printf("Changingurc.SetOutput(0,urc.SetOutput(1,urc.SetOutput(2,urc.SetOutput(3,urc.SetOutput(4,urc.SetOutput(5,urc.SetOutput(6,urc.SetOutput(7,LEDs state\n");1);0);1);0);1);0);1);0);printf("Writing data to the device\n");if(!urc.Write()){printf("ER: can't write data\n");return EXIT_FAILURE;}urc.Close();printf("Done\n");return EXIT_SUCCESS;}//------------------------------------------------------------Здесь сначала вызывается функция select_device(), которая вернёт номер тогоустройства, с которым необходимо работать.
Так как всего может быть10подключено не более URC_MAXDEV устройств, то индекс устройства можетпринимать значения от 0 до (URC_MAXDEV - 1), поэтому если функция возвращаетURC_MAXDEV, значит произошла ошибка, поэтому идёт проверка значенияпеременной index на равенство URC_MAXDEV.Далее, если был возвращён корректный индекс, открываем это устройство, вызвавфункцию Open(). В случае ошибки все функции класса возвращают 0, поэтому вслучае возврата нуля программа выдаёт сообщение об ошибке и завершает работу(return EXIT_FAILURE).После того, как устройство было открыто, можно начать вызывать функции дляработы.
В данном случае вызывается метод SetOutput(), который в качествепервого параметра принимает номер цифрового выхода (от 0 до 7), а вторымпараметром является значение на выходе (0 – низкий уровень, !0 – высокий). Таккак цифровые выходы продублированы светодиодами, то после установкилогической единицы на выходы 0, 2, 4 и 6, загорятся соответствующиесветодиоды. Однако все внесенные изменения записываются не непосредственнов устройство, а в буфер в оперативной памяти (это нужно для увеличенияскорости обмена между компьютером и устройством), поэтому окончательнозаписать все изменения можно вызвав функцию Write(). Здесь также происходитпроверка корректности выполнения функции.Далее программа закрывает устройство и завершает работу.Теперь рассмотрим исходный код функции select_device().
Эта функция нужна длявыбора устройства среди устройств, подключённых к компьютеру. Получитьсписок устройств можно с помощью функции GetDevStates() того же класса. Вкачестве параметра функция принимает массив из URC_MAXDEV чисел, кудазапишет состояние каждого слота для подключения устройства. Так, еслизначение ячейки массива равно URCSTATE_OPENED, значит устройство,соответствующее номеру этой ячейки, подключено.Необходимость нумерации возникает из-за того, что требуется избежать путаницыномеров при подключении и отключении устройств. Например, если подключитьпервое устройство, а затем второе, то у них будут индексы 0 и 1 соответственно.Однако, если отключить первое подключенное устройство, то ячейка номер 0примет значение URCSTATE_CLOSED, а ячейка номер 1 останется равнаURCSTATE_OPENED.
Таким образом, номер подключённой платы остаётсянеизменнымнавсёвремяподключения,внезависимостиотподключения/отключения других плат.//-----------------------------------------------------------uint32 select_device(){uint32 states[URC_MAXDEV];if(!urc.GetDevStates(states)){printf("ER: can not receive devices state\n");return URC_MAXDEV;}11printf("Active device index(s): ");uint32 count = 0;for(uint32 i = 0; i < URC_MAXDEV; i++){if(states[i] == URCSTATE_OPENED){printf("%d ", i);count++;}}if(!count) printf("<no>");printf("\nTotal devices found: %d\n", count);if(!count) return URC_MAXDEV;printf("Input device index: ");char buf[100];fgets(buf, sizeof(buf) - 1, stdin);int index = atoi(buf);if(index >= URC_MAXDEV || index < 0){printf("Wrong device index\n");return URC_MAXDEV;}if(states[index] != URCSTATE_OPENED){printf("Wrong device index\n");return URC_MAXDEV;}return index;}//------------------------------------------------------------Далее в цикле просматриваются значения всех ячеек массива, и на экранвыводятся номера подключённых устройств и их количество.
Затем пользователюпредлагается ввести номер устройства. После этого, введённая строкапреобразуется в число и происходит проверка введённого числа (входит ли оно вдиапазон [0, (URC_MAXDEV - 1)], а также подключено ли данное устройство).Если в процессе выполнения функции не возникло никаких ошибок, то она вернётиндекс выбранного устройства. В противном случае функция вернёт URC_MAXDEVв качестве ошибки.Теперь компилируем проект. Для этого выберем меню “Project” – “Build All”. Послевыполнения этой команды будут созданы объектные (“*.o”) и исполняемые файлывсехпроектовиконфигураций, в том числе идля проекта simple_test.Принастройкахпоумолчаниюимяисполняемогофайла“/user_name/ide4workspace/test_simple/x86/o/test_simple”.Рис.4.2 Выполнение программы test_simple12Запустим файл в консоли (“Launch” – “Utilities” – “Console”).
Для вставки пути избуфера обмена нажмите на Ctrl+Alt+V. Ход выполнения программы показан нарисунке 4.2. При этом на плате должны загореться светодиоды LED0, LED2, LED4 иLED6.4.3 Универсальный примерНиже приведён универсальный пример, который демонстрирует все функции дляработы с устройством. Данное консольное приложение выводит на экран вседанные с платы, которые можно считать, в виде таблицы, а также устанавливаетзначения ШИМ на всех каналах и мигает светодиодами.Здесь, как и в предыдущем примере, сначала происходит выбор устройства спомощью функции select_device(), а затем подключение к выбранному устройству.ШИМ меняется линейно от 0 до +700 и обратно, а данные на экран выводятся 4раза в секунду.Подключение заголовочных файлов, прототипы функция и функция main()://-----------------------------------------------------------#include#include#include#include#include<stdio.h><stdlib.h><pthread.h><errno.h>"urc220.h"//-----------------------------------------------------------uint32 select_device();void *test_complex(void *);CURC220 urc;//-----------------------------------------------------------int main(int argc, char *argv[]){printf("URC test\n");uint32 index = select_device();if(index == URC_MAXDEV) return EXIT_FAILURE;printf("Opening device %d\n", index);if(!urc.Open(index)){printf("ER: can't open device\n");return EXIT_FAILURE;}printf("Creating thread\n");pthread_t thread;int ret = pthread_create(&thread, NULL, &test_complex, NULL);if(thread == 0 || ret != EOK){printf("ER: can't create thread (%d)\n", ret);return EXIT_FAILURE;}13getchar();pthread_detach(thread);pthread_abort(thread);urc.Close();printf("Done\n");return EXIT_SUCCESS;}//------------------------------------------------------------Здесь, после подключения к устройству, создаётся дополнительный поток, вкотором будет выполняться функция test_complex().
Также есть проверка науспешность создания потока. Далее вызывается функция getchar(), котораязаблокирует основной поток до нажатия на Enter, после чего программа закроетобращение к устройству и завершит свою работу.В функции test_complex() реализован бесконечный цикл, в котором происходитсчитывание данных из устройства с помощью метода Read() с проверкойуспешности выполнения, далее заполняются значения локальных переменных спомощью функций GetInput(), GetOutput(), GetADC() и GetEnc(). Далее всезначения выводятся на экран. Затем идёт подсчёт нового значения ШИМ и записьданных обратно в устройство.Исходный код функции test_complex() приведён ниже.//-----------------------------------------------------------void *test_complex(void *){printf("Complex test\n");int sign = +1;int led_num = 0;while(1){if(!urc.Read()){printf("ER: can't read data\n");delay(1000);}uint8 in[4];uint8 out[8];uint16 adc[4];int16 pwm[4];int32 enc[2];for(int i = 0; i < 4; i++)urc.GetInput(i, &in[i]);for(int i = 0; i < 8; i++)urc.GetOutput(i, &out[i]);for(int i = 0; i < 4; i++)urc.GetADC(i, &adc[i]);for(int i = 0; i < 4; i++)urc.GetPWM(i, &pwm[i]);for(int i = 0; i < 2; i++)14urc.GetEnc(i, &enc[i]);printf("%d %d %d %d - %d %d %d %d %d %d %d %d - %04d %04d %04d%04d - %03d %03d %03d %03d - %d,%d\n",in[0], in[1], in[2], in[3],out[0], out[1], out[2], out[3],out[4], out[5], out[6], out[7],adc[0], adc[1], adc[2], adc[3],pwm[0], pwm[1], pwm[2], pwm[3],enc[0], enc[1]);int16 cur_pwm = pwm[0];cur_pwm += sign * 50;urc.SetPWM(0, cur_pwm);urc.SetPWM(1, cur_pwm);urc.SetPWM(2, cur_pwm);urc.SetPWM(3, cur_pwm);if(cur_pwm == 700) sign = -1;if(cur_pwm == 0) sign = +1;for(int i = 0; i < 8; i++)urc.SetOutput(i, 0);urc.SetOutput(led_num, 1);led_num++;if(led_num == 8) led_num = 0;if(!urc.Write()){printf("ER: can't write data\n");delay(1000);}delay(250);}return NULL;}//------------------------------------------------------------Функцияselect_device()в этомпримере взятаизпредыдущего.Ходвыполненияпрограммыпоказан нарисунке 4.3.Рис.4.3 Выполнение программы test_complex155.
Устройство шины USB5.1 Общие сведенияUSB (Universal Serial Bus) – это спецификация, разрабатывавшаяся компаниямиCompaq, Intel, Microsoft и NEC, а затем и Hewlett-Packard, Lucent и Philips. Стандартбыл разработан для упрощения подключения устройств к компьютеру, дляреализации технологии PnP (Plug & Play), а также не требует использованиепрерываний или DMA (Direct Memory Access), что позволяет упростить разработкудрайверов для новых устройств, подключаемых к компьютеру через USB.5.2 Версии спецификаций и скорость передачи данныхНаиболее распространённым стандартом был USB 1.1. Впоследствии его заменилUSB 2.0 с сохранением совместимости с устройствами, поддерживающимистандарт версии 1.1.В таблице 5.1 приведены значения максимальной скорости передачи данных дляUSB 1.1 и USB 2.0.Таблица 5.1USB 1.0 и 1.1НазваниеLow SpeedFull SpeedСкорость1.5 МБит/с12 МБит/сUSB 2.0НазваниеLow SpeedFull SpeedHigh SpeedСкорость1.5 МБит/с12 МБит/с480 МБит/сТаким образом, “USB 2.0” не означает High Speed, т.е.
мышь, подключаемая ккомпьютеру через USB, может поддерживать стандарт версии 2.0, но работать наскорости 1.5 Мбит/с. Процессор в устройстве URC220 – AT91SAM7S64 поддерживает USB 2.0 Full Speed.5.3 АрхитектураUSB основан на топологии типа “звезда”, гдеприсутствует только один ведущий концентратор(Root Hub) и может быть до 127 подключаемыхустройств (см. рис. 5.1). При этом в качествеустройствмогутвыступатьидругиеконцентраторы, то есть нельзя подключать более127 устройств, включая концентраторы.Рис.5.1 Топология шины USBЧисло 127 возникает из-за того, что каждомуустройству присваивается его адрес (номер), накоторый в USB отводится 7 бит (всего различныхадресов 27=128, нулевой адрес присваиваетсявновь подключаемым устройствам, которые ещёне были инициализированы).