URC220 (Раздаточный материал по URC220), страница 5
Описание файла
Файл "URC220" внутри архива находится в следующих папках: Раздаточный материал по URC220, Documents, URC220 Documentation. Документ из архива "Раздаточный материал по URC220", который расположен в категории "". Всё это находится в предмете "программное обеспечение управляющих комплексов (поук)" из 6 семестр, которые можно найти в файловом архиве МГТУ им. Н.Э.Баумана. Не смотря на прямую связь этого архива с МГТУ им. Н.Э.Баумана, его также можно найти и в других разделах. Архив можно найти в разделе "остальное", в предмете "программное обеспечение управляющих комплексов (поук)" в общих файлах.
Онлайн просмотр документа "URC220"
Текст 5 страницы из документа "URC220"
// подключение необходимых библиотек
#include <stdio.h>
#include <conio.h>
void main ()
{
// Печатает строку
printf ("Hello world!\n");
// ждёт нажатия любой кнопки на клавиатуре
_getch ();
}
5.2 Пример простой программы
Для работы с контроллером URC220 требуется скопировать в папку с проектом 4 файла: «URC220.h», «URC220.lib», «URCPIPE.h» и «URCPIPE.lib». В этих файлах находятся прототипы функций необходимых для работы контроллером. Сами же функции находятся в файлах «URC220.dll» и «URCPIPE.dll». При установке драйвера эти два .dll файла автоматически копируются в системный каталог Window. Рассмотрим работу с платой на примере. Программа будет гасить на плате светодиод OUT1 и зажигать OUT2, при этом состояние остальных светодиодов не изменяется.
// Подключение стандартных библиотек
#include <windows.h>
#include <conio.h>
#include <stdio.h>
// Подключение библиотеки для работы с платой
#include "URC220.h"
// Начало выполнения программы
void main ()
{
// Создаю объект платы
// (CURC220 - тип; board - имя переменной);
CURC220 board;
// Узнаю, есть ли вообще платы
board.UpdateDeviceList ();
// в этой переменной будет храниться количество плат
// подключённых к компьютеру
unsigned long int deviceNum = 0;
// Узнаю чило плат
board.GetDeviceCount (&deviceNum);
if (deviceNum == 0) //если плат нет
{
printf ("Board not connected :(\n");
}
else // если платы есть
{
// соединяюсь с платой под номером 0
board.Open (0);
// Записываю новое значение в буфер
board.DeviceSetOutput (1, 0);
board.DeviceSetOutput (2, 1);
// Применяю изменения к плате
board.DeviceWrite ();
// отсоединяюсь от устройства
board.Close ();
}
}
5.2.1 Инициализация контроллера
Первое действие - это создание объекта класса CURC220. В примере объект называется «board». Далее необходимо вызвать функцию этого класса board.UpdateDeviceList (). Функция опрашивает драйвер USB порта и составляет список устройств, подключённых к USB на данном компьютере. Функция board.GetDeviceCount (&deviceNum) определяет сколько контроллеров URC220 подключено к ПК. Функция board.Open (i) соединяется с контроллером под номером i. Естественно, что если указать i >= deviceNum, то подключения к контроллеру не произойдёт, так как контроллер не подключен. После успешного завершения board.Open (i) можно переходить к работе с контроллером.
5.2.2 Обмен данными с контроллером
Для ускорения работы в «URC220.dll» реализована работа с контроллером через буфер. Это означает, что любое изменение состояния платы сначала записывается в программный буфер на ПК, и лишь при вызове функции board.DeviceWrite (); происходит реальная передача данных в контроллер и изменение его состояния. В данном примере board.DeviceSetOutput (1, 0); – записывает в буфер, при этом контроллер не изменяет своего состояния, а реальное изменение состояния происходит только после board.DeviceWrite ();
Аналогичная ситуация и со считыванием информации из контроллера. Функция board.DeviceRead (); – обновляет буфер на ПК, а считывание из буфера производится другими функциями, например, board.DeviceGetInput(ULONG Index, UCHAR *Value);
5.2.3 Завершение работы с контроллером
При завершении программы и, соответственно, работы с контроллером необходимо вызывать функцию board.Close ();
Для работы с контроллером написано 4 примера. В папке «!Самый простой тест» вы найдёте прокомментированный пример работы с контроллером. Используйте его как шаблон, при создании новых программ.
5.3 Универсальный пример
Ниже приведён универсальный пример, который демонстрирует все функции для работы с устройством. Данное консольное приложение выводит на экран все данные с платы, которые можно считать, в виде таблицы, а также устанавливает значения ШИМ на всех каналах и мигает светодиодами.
Сначала происходит выбор устройства (функция list_devices), а затем подключение к выбранному устройству. ШИМ меняется линейно от -500 до +500 и обратно, а данные на экран выводятся 4 раза в секунду. Также происходит подсчёт числа итераций цикла.
//------------------------------------------------------
// Подключение необходимых библиотек
#include <windows.h>
#include <stdio.h>
#include <conio.h>
#pragma comment(lib, "Winmm.lib")
// В т.ч. и библиотеки для работы с устройством
#include "urc220.h"
//------------------------------------------------------
// Объект для работы с устройством
CURC220 urc;
//------------------------------------------------------
// Функция выводит на экран список устройств и
// возвращает номер выбранного пользователем устройства
// (начиная с "0", "-1" - ошибка)
int list_devices()
{
// Обновляем список устройств
urc.UpdateDeviceList();
// Определяем количество устройств
ULONG device_count = 0;
urc.GetDeviceCount(&device_count);
// Если не подключено ни одного устройства, то
if(!device_count)
{
// Выводим сообщение и выходим
printf("Devices not found\n");
return -1;
}
// Максимальная длина имени устройства
ULONG max_name_size = 0;
// Проходимся по всем устройствам и определяем
// размер самого длинного имени
for(ULONG i = 0; i < device_count; i++)
{
ULONG current_name_size = 0;
urc.GetDeviceNameLen(i, ¤t_name_size);
if(max_name_size < current_name_size)
max_name_size = current_name_size;
}
// Создаём строку для хранения имени
char *name = new char[max_name_size + 1];
// Выводим список устройств на экран
printf("Device list:\n");
printf("--------------------------------------------------------------------------------");
// Проходимся по всем устройствам
for(ULONG i = 0; i < device_count; i++)
{
// Определяем имя устройства и записываем его
// в созданную строку
urc.GetDeviceName(i, name, max_name_size + 1);
// Выводим имя на экран
printf("Device %d name:\n", i);
printf("%s\n", name);
}
printf("--------------------------------------------------------------------------------");
// Удаляем ненужную теперь строку
delete name;
// Если подключено более одного устройства, то
if(device_count > 1)
{
// Предлагаем пользователю ввести номер устройства
printf("Select device number:");
// Считываем ответ пользователя
char buf[100];
gets_s(buf, sizeof(buf));
// Преобразуем введённую строку в число
int device_index = atoi(buf);
// Если введён неверный номер, то
if((device_index < 0) || (device_index > ((int)device_count - 1)))
{
// Сообщаем и выходим
printf("Wrong device number\n");
return -1;
}
// Возвращаем номер устройства
return device_index;
}
// Если подключено всего одно устройство, то
else
{
// Сразу возвращаем его номер
return 0;
}
}
//------------------------------------------------------
int main()
{
// Определяем номер устройства,
// которое нужно открыть
int device_index = list_devices();
// Если возникла ошибка, то выходим
if(device_index < 0)
{
_getch();
return 0;
}
// Открываем выбранное усройство
if(!urc.Open(device_index))
{
// Сообщаем и выходим, если не получилось
printf("Can not open device #%d...\n", device_index);
_getch();
return 0;
}
// Сообщаем об успешном соединении
printf("Device #%d opened\n", device_index);
printf("Press Esc to quit\n");
// Предыдущее время вывода информации - текущее
DWORD prev_time = timeGetTime();
// Счётчик числа итераций
DWORD it_count = 0;
// Значение ШИМ
SHORT pwm = 0;
// Направление изменения ШИМа (+1 или -1)
SHORT pwm_sign = +1;
// Номер светодиода
DWORD led_id = 0;
// Счётчик линий
DWORD line_count = 0;
// Выводим заголовок таблицы
printf("--------------------------------------------------------------------------------");
printf("Inputs\tADC0\tADC1\tADC2\tADC3\tEnc0\tEnc1\tTicks/sec\n");
printf("--------------------------------------------------------------------------------");
// Начинаем бесконечный цикл
while(1)
{
// 1 - Сначала считываем данные из устройства
if(!urc.DeviceRead())
{
// Сообщаем и выходим, если не получилось
printf("Error reading device...\n");
_getch();
return 0;
}
// 2 - Далее выполняем необходимые действия с устройством
// Увеличиваем счётчик итераций
it_count++;
// Если прошло 250 мс, то
if(timeGetTime() - prev_time >= 250)
{
// Определяем состояние всех портов ввода
UCHAR in0, in1, in2, in3;
urc.DeviceGetInput(0, &in0); if(in0) in0 = 1;
urc.DeviceGetInput(1, &in1); if(in1) in1 = 1;
urc.DeviceGetInput(2, &in2); if(in2) in2 = 1;
urc.DeviceGetInput(3, &in3); if(in3) in3 = 1;
// Определяем измерения всех АЦП
USHORT adc0, adc1, adc2, adc3;
urc.DeviceGetADC(0, &adc0);
urc.DeviceGetADC(1, &adc1);
urc.DeviceGetADC(2, &adc2);
urc.DeviceGetADC(3, &adc3);
// Определяем значения на всех энкодерах
LONG enc0, enc1;
urc.DeviceGetEnc(0, &enc0);
urc.DeviceGetEnc(1, &enc1);
// Выводим все эти данные в виде строки таблицы
printf("%d%d%d%d\t%d\t%d\t%d\t%d\t%d\t%d\t%d\t\n",
in0, in1, in2, in3, adc0, adc1, adc2, adc3,
enc0, enc1, it_count * 4);
// Увеличиваем счётчик выведенных строк
line_count++;
// Если вывели уже 15 строк, то ещё раз печатаем
// заголовок таблицы и обнуляем счётчик строк
if(line_count == 15)
{
printf("--------------------------------------------------------------------------------");
printf("Inputs\tADC0\tADC1\tADC2\tADC3\tEnc0\tEnc1\tTicks/sec (Esc to quit)\n");
printf("--------------------------------------------------------------------------------");
line_count = 0;
}
// Устанавливаем логический 0 в порт вывода с номером led_id
urc.DeviceSetOutput(led_id, 0);
// Увеличиваем счётчик номера порта
led_id++;
// Если дошли до максимума, то начинам сначала
if(led_id == 8) led_id = 0;
// Устанавливаем логическую 1 в этот порт вывода
urc.DeviceSetOutput(led_id, 1);
// Обнуляем счётчик числа итераций
it_count = 0;
// Предыдущее время вывода информации - текущее
prev_time = timeGetTime();
}
// Устанавливаем значения на каналах ШИМ
urc.DeviceSetPWM(0, pwm);
urc.DeviceSetPWM(1, pwm);
urc.DeviceSetPWM(2, pwm);
urc.DeviceSetPWM(3, pwm);
// Изменяем текущую величину ШИМ
pwm += pwm_sign;
// Если дошли до максимума, то устанавливаем
// отрицательное изменение значения ШИМ
if(pwm == 500) pwm_sign = -1;
// Если дошли до минимума, то устанавливаем
// положительное изменение значения ШИМ
if(pwm == -500) pwm_sign = +1;
// 3 - Записываем данные в устройство
if(!urc.DeviceWrite())
{
// Сообщаем и выходим, если не получилось
printf("Error writing device...\n");
_getch();
return 0;
}
// Если нажали на Esc, то прерываем цикл
if(GetAsyncKeyState(VK_ESCAPE)) break;
}
// Выходим из программы
return 0;
}
//------------------------------------------------------
6. Содержание
1. Общее описание платы 2
1.1 Технические характеристики 2
1.2 Процессор AT91SAM7S64 3
1.3 Драйверы двигателей A3949 6
2. Элементы на плате 8
2.1 Порты вывода и светодиоды 8
2.2 Порты ввода и кнопки 9
2.3 Аналого-цифровой преобразователь (АЦП) 10
2.4 Потенциометры 11
2.5 Широтно-импульсный модулятор (ШИМ). 12
2.6 Вход для энкодеров 14
2.7 Интерфейсы связи 15
2.8 Разъёмы питания 15
3. Программирование микроконтроллера 16
3.1 Создание нового проекта 17
3.2 Простейшая программа 20
3.3 Отладка программы 24
4. Библиотека для работы с платой на компьютере 25
4.1 Алгоритм работы 25
4.2 Описание функций класса 26
5. Применение библиотеки 29
5.1 Создание нового проекта в Microsoft Visual Studio 2003 29
5.2 Пример простой программы 33
5.3 Универсальный пример 35
6. Содержание 40
40