
4.3 Универсальный пример
Ниже приведён универсальный пример, который демонстрирует все функции для работы с устройством. Данное консольное приложение выводит на экран все данные с платы, которые можно считать, в виде таблицы, а также устанавливает значения ШИМ на всех каналах и мигает светодиодами.
Здесь, как и в предыдущем примере, сначала происходит выбор устройства с помощью функции select_device(), а затем подключение к выбранному устройству. ШИМ меняется линейно от 0 до +700 и обратно, а данные на экран выводятся 4 раза в секунду.
Подключение заголовочных файлов, прототипы функция и функция main():
//------------------------------------------------------------
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <errno.h>
#include "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;
}
getchar();
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++)
urc.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;
}
//------------------------------------------------------------
Рис.4.3 Выполнение программы test_complex |
Ход выполнения программы показан на рисунке 4.3.