реклама на сайте
подробности

 
 
13 страниц V   1 2 3 > »   
Reply to this topicStart new topic
> ARM. Энкодеры и акселерометры, Помогите решить задачу
Zliva
сообщение Jul 29 2009, 20:01
Сообщение #1


Частый гость
**

Группа: Участник
Сообщений: 137
Регистрация: 14-11-06
Из: Луцка
Пользователь №: 22 318



Всем привет!
Нужна помощь.
Есть виброплощадка с двумя дебалансными валами, с одной стороны которой через эластические муфты приделаны двигатели, а с другой – инкрементные энкодеры. Площадка крепится через пружины к станине. Двигатели прикручены к станине жестко. Валы площадки не синхронизированы. К площадке крепится датчик ускорения ADXL210 с выходным сигналом ШИМ. Двигатель вращается с частотой 1500 об/мин, следовательно это равно 25об/сек. Энкодер имеет разрешение 1024им/об, это равно 1024*25=25600Гц. Начальное положение определяться перед пуском. Поскольку дебалансный вал имеет эксцентриситет, то соответственно он направлен в низ. Это и есть его начальное положение. Контролер и комп НЕ УПРАВЛЯЕТ ДВИГАТЕЛЯМИ, а они запускаются отдельно через рубильник.
Точность измерения:
  • угловое положение +/-0,4градуса;
  • угловую скорость(+/-1.0град/сек);
  • угловое ускорение (после интерполяции графика скорости. Зависит от метода);
  • линейное ускорение(+/-0,1g);

Нужно периодично опрашивать датчики, чтобы знать его положение, ускорение в каждый момент времени. Данные через USB от датчиков должны заливаться на комп.

Нужно измерять положения дебалансных валов и их скорость, ускорение, а также ускорение, скорость, положение площадки. Ловить сдвиг фаз между положениями валов.

Здесь нимного обсуждалось и здесь
Что уже есть: изготовлена площадка, на ней стоят энкодеры. Уже запускал, работает.
Прикупил ARM отладочную плату AT91SAM7S64_DBoard для ARM микроконтроллеров фирмы ATMEL и программатор J-Link - USB JTAG adapter. Хочу на базе этого дивайса решить эту задачу. Опит программирования только AVR. Знаю немного Си и Delphi. Очень нужно. Помогите пожалуйста.


--------------------
If the person is successful, he is successful in any sphere.
Go to the top of the page
 
+Quote Post
_Pasha
сообщение Jul 30 2009, 08:17
Сообщение #2


;
******

Группа: Участник
Сообщений: 5 646
Регистрация: 1-08-07
Пользователь №: 29 509



Я бы все-таки энкодеры обрабатывал простеньким AVR Tiny2313, результаты отдавал по SPI, с согласованием питания.
Go to the top of the page
 
+Quote Post
Zliva
сообщение Jul 30 2009, 08:44
Сообщение #3


Частый гость
**

Группа: Участник
Сообщений: 137
Регистрация: 14-11-06
Из: Луцка
Пользователь №: 22 318



Цитата(_Pasha @ Jul 30 2009, 11:17) *
Я бы все-таки энкодеры обрабатывал простеньким AVR Tiny2313, результаты отдавал по SPI, с согласованием питания.

Зачем городить схему. В принципе ARM может работать с напряжением 5В, но только на вход. Так написано в даташите. Я думаю все равно ставить оптронную развязку. Хочу задействовать прерывания для обработки сигналов. Для начала помогите сконфигурировать IAR с JTAG-м. Хочу залить первую программу, какую не будь мигалку. Нажал кнопку и светится, отпустил - погасло.


--------------------
If the person is successful, he is successful in any sphere.
Go to the top of the page
 
+Quote Post
Zliva
сообщение Aug 15 2009, 20:01
Сообщение #4


Частый гость
**

Группа: Участник
Сообщений: 137
Регистрация: 14-11-06
Из: Луцка
Пользователь №: 22 318



С программированием ARM разобрался. Программируется AT91SAM7S128 и через J-LINK и через SAM-BA. Перешел с IAR на KEIL. Мне нравится. Отличный там симулятор.
Возникло несколько вопросов.
1. Объясните пожалуйста на пальцах разницу между CDC, HID,MSD и USB SER.SYS?
2. Где можно про это почитать?
3. Какой вариант в моем случае лучше?

Хочу для сначала измерить положение вала. Думаю делать так (набросайте помидорами сразу):
Задействую первое прерывание на линию А энкодера, а второе - В на обычный вход(используется для определения направления вращения). Сохраняю значение текущего положения постоянно. В момент возникновения прерывания сохраняю текущее значение времени. Время отсчитывается с момента старта. Затем формирую пакет «Время» - «Текущая позиция» «количество оборотов» (пакет буде побольше включая скорость для двух энкодеров и ускорение для двух координат) и по запросу с ПК считываю значение. На ПК интерполирую данные, а затем дифференцирую или интегрирую и получаю остальные характеристики. Вот коротко что хочу. Может у кого-то будут какие-то другие идеи по решению этой задачи, буду рад. Поскольку начинаю юзать АРМ, могут возникнуть вопросы. Надеюсь на вашу помощь.

4. Может у кого-то есть рабочий пример по работе с USB?


--------------------
If the person is successful, he is successful in any sphere.
Go to the top of the page
 
+Quote Post
aaarrr
сообщение Aug 15 2009, 20:36
Сообщение #5


Гуру
******

Группа: Свой
Сообщений: 10 713
Регистрация: 11-12-04
Пользователь №: 1 448



1. Первые три - классы устройств USB; usbser.sys - драйвер винды, обслуживающий CDC ACM.
2. usb.org
3. Зависит от Вашей задачи - какой поток, требуется ли гарантированная доставка данных и т.д. и т.п. Стандартными классами пользоваться вовсе не обязательно.
Go to the top of the page
 
+Quote Post
Zliva
сообщение Aug 15 2009, 20:47
Сообщение #6


Частый гость
**

Группа: Участник
Сообщений: 137
Регистрация: 14-11-06
Из: Луцка
Пользователь №: 22 318



Цитата(aaarrr @ Aug 15 2009, 23:36) *
3. Зависит от Вашей задачи - какой поток, требуется ли гарантированная доставка данных и т.д. и т.п. Стандартными классами пользоваться вовсе не обязательно.

Гарантия доставки обязательна. Со стороны компа буду периодично считывать данные.
Тогда какой класс выбрать?


--------------------
If the person is successful, he is successful in any sphere.
Go to the top of the page
 
+Quote Post
aaarrr
сообщение Aug 15 2009, 20:52
Сообщение #7


Гуру
******

Группа: Свой
Сообщений: 10 713
Регистрация: 11-12-04
Пользователь №: 1 448



Если гарантия доставки обязательна, то в качестве типа передачи нужно выбирать bulk. Так какой поток нужен?
И лучше почитайте с начала об USB вообще.
Go to the top of the page
 
+Quote Post
Zliva
сообщение Aug 15 2009, 20:57
Сообщение #8


Частый гость
**

Группа: Участник
Сообщений: 137
Регистрация: 14-11-06
Из: Луцка
Пользователь №: 22 318



Цитата(aaarrr @ Aug 15 2009, 23:52) *
Если гарантия доставки обязательна, то в качестве типа передачи нужно выбирать bulk. Так какой поток нужен?
И лучше почитайте с начала об USB вообще.

Спасибо. Разберусь обязательно. Если была бы еще русскоязычная документация, было бы попроще. Ну нечего. Прорвусь. А скорость опроса примерно 1кГц(если вы это имели в виду).


--------------------
If the person is successful, he is successful in any sphere.
Go to the top of the page
 
+Quote Post
aaarrr
сообщение Aug 15 2009, 21:01
Сообщение #9


Гуру
******

Группа: Свой
Сообщений: 10 713
Регистрация: 11-12-04
Пользователь №: 1 448



Цитата(Zliva @ Aug 16 2009, 00:57) *
А скорость опроса примерно 1кГц(если вы это имели в виду).

Нет, я имел в виду именно поток. Тот же CDC со стандартным виндовым драйвером имеет ограничения - не получится отправить хосту более одного пакета за миллисекунду (т.е. предельная скорость составит 64000 байт/с), в обратном направлении таких ограничений нет.
Go to the top of the page
 
+Quote Post
Zliva
сообщение Aug 15 2009, 21:30
Сообщение #10


Частый гость
**

Группа: Участник
Сообщений: 137
Регистрация: 14-11-06
Из: Луцка
Пользователь №: 22 318



Цитата(aaarrr @ Aug 16 2009, 00:01) *
Нет, я имел в виду именно поток. Тот же CDC со стандартным виндовым драйвером имеет ограничения - не получится отправить хосту более одного пакета за миллисекунду (т.е. предельная скорость составит 64000 байт/с), в обратном направлении таких ограничений нет.

Что-то я запутался. Нужно немного почитать чтобы говорить на вашем языке. Правильно ли я понял:
У меня есть пакет.
«Время»___«Текущая позиция»___«к-во обо-в»___«Текущая позиция»___«к-во обо-в»___Ускорение Х___Ускорение Y
__________Энкодер 1___________Энкодер 1______Энкодер 2__________Энкодер 2
_8байт_____2байта______________12 байт________2байта______________12 байт________2байта________2 байта

Его размер будет 40байта. Если я хочу опрашивать устройство с частотой 1кГц, то получается 40кБайт/с.
Так какой класс выбрать?


--------------------
If the person is successful, he is successful in any sphere.
Go to the top of the page
 
+Quote Post
aaarrr
сообщение Aug 15 2009, 21:39
Сообщение #11


Гуру
******

Группа: Свой
Сообщений: 10 713
Регистрация: 11-12-04
Пользователь №: 1 448



Цитата(Zliva @ Aug 16 2009, 01:30) *
Так какой класс выбрать?

Оставьте пока классы и почитайте об организации передачи данных в USB на более низком уровне.

P.S. В вашем случае с одинаковым успехом можно использовать CDC или вообще не пользоваться стандартными классами.
Go to the top of the page
 
+Quote Post
Zliva
сообщение Aug 15 2009, 22:02
Сообщение #12


Частый гость
**

Группа: Участник
Сообщений: 137
Регистрация: 14-11-06
Из: Луцка
Пользователь №: 22 318



Цитата(aaarrr @ Aug 16 2009, 00:39) *
Оставьте пока классы и почитайте об организации передачи данных в USB на более низком уровне.

P.S. В вашем случае с одинаковым успехом можно использовать CDC или вообще не пользоваться стандартными классами.

Спасибо. Но а если я с хочу считывать данные со скоростью не 1кГц, а скажем 5кГц – это возможно?


--------------------
If the person is successful, he is successful in any sphere.
Go to the top of the page
 
+Quote Post
aaarrr
сообщение Aug 15 2009, 22:08
Сообщение #13


Гуру
******

Группа: Свой
Сообщений: 10 713
Регистрация: 11-12-04
Пользователь №: 1 448



Возможно. Другое дело, что фрейм USB равен 1 мс, поэтому на низкую латентность при работе рассчитывать не приходится.
Go to the top of the page
 
+Quote Post
Zliva
сообщение Aug 23 2009, 15:35
Сообщение #14


Частый гость
**

Группа: Участник
Сообщений: 137
Регистрация: 14-11-06
Из: Луцка
Пользователь №: 22 318



Вот код обработки по прерыванию положения первого энкодера.
CODE
#include <AT91SAM7S128.H> /* AT91SAM7S64 definitions */
#include "..\Board.h"

volatile unsigned int ENCODER1_Position = 0; /* Текуща позиция энкодера 1*/
volatile unsigned long int ENCODER1_Count = 0; /* Текуща позиция энкодера 1*/
#define ENCODER1_A_MASK (1<<20) /* PA19 */
#define ENCODER1_B_MASK (1<<19) /* PA20 */
#define ENCODER2_A_MASK (1<<15) /* PA15 */
#define ENCODER2_B_MASK (1<<14) /* PA14 */
#define ENCODER_A_MASK (ENCODER1_A_MASK|ENCODER1_B_MASK|ENCODER2_A_MASK|ENCODER2_B_MASK)

#define ENCODER1_A (1<<20) // PA19
#define ENCODER1_B (1<<19) // PA20
#define ENCODER2_A (1<<15) // PA15
#define ENCODER2_B (1<<14) // PA14


#define ENCODER1_resolution 1024
#define ENCODER2_resolution 1024


extern AT91S_PIO * pPIO; /* Global Pointer to PIO */

extern __irq void irq0_int (void); /* IRQ0 Function */


void irq0_nint (void) { /* Nested IRQ0 (Push button SW2) */

if ((pPIO->PIO_PDSR & ENCODER1_A) == 0) { /* Проверяем активный уровень на входе А энкодера 1*/
if ((pPIO->PIO_PDSR & ENCODER1_B) == 0) { /* Определяем направление вращения энкодера 1*/
if (ENCODER1_Position == (ENCODER1_resolution-1)) {/*Проверяем не прывисл ли
ENCODER1_Position значения полосок на энкодере*/
ENCODER1_Position = 0;/*Если превысил то отсчитываем с 0*/
// ENCODER1_Count++; /*Увеличиваем на 1 значения оборотов */
}
ENCODER1_Position++;} /* Если за часовой стрелкой то увеличиваем на 1*/
else {
if (ENCODER1_Position == 0) { /* Проверяем не прывисл ли ENCODER1_Position значения 0*/
ENCODER1_Position = (ENCODER1_resolution-1);/*Если 0 то отсчитываем с ENCODER1_resolution-1*/
ENCODER1_Count++; /*Уменьшаем на 1 значения оборотов */
}
ENCODER1_Position--; } /* Если против часовой стрелкой то уменьшаем на 1*/
}

*AT91C_AIC_EOICR = 0; /* End of Interrupt*/
}


void init_extint (void) { /* Setup IRQ 0 Interrupt */
AT91S_AIC * pAIC = AT91C_BASE_AIC; /* Setup IRQ0 Interrupt Mode and Vector with Priority 0 and Enable it */
/*
AIC_SMR - Регистр источника прерывания 0
AT91C_ID_IRQ0 - ID Прерывание для IRQ0
AT91C_AIC_SRCTYPE_INT_POSITIVE_EDGE - Internal Sources Code Label Positive
Edge triggered - Положительный фронт */
pAIC->AIC_SMR[AT91C_ID_IRQ0] = AT91C_AIC_SRCTYPE_INT_POSITIVE_EDGE | 0;// AT91C_AIC_SRCTYPE_INT_POSITIVE_EDGE
/* Вектор прерывания. AIC_SVR0..AIC_SVR31 - В эти регистры записываются
адреса соответствующих процедур обработки прерывания для каждого источника.*/
pAIC->AIC_SVR[AT91C_ID_IRQ0] = (unsigned long) irq0_int; /*Регистр разрешения прерываний*/
pAIC->AIC_IECR = (1 << AT91C_ID_IRQ0);
}

Вроде все правильно, но почему дважды вызывается прерывание? Все значения пересылаю через USART.
CODE
#include <AT91SAM7S128.H> /* AT91SAM7S64 definitions */
#include "..\Board.h"

#define BR 115200 /* Baud Rate */

#define BRD (MCK/16/BR) /* Baud Rate Divisor */


AT91S_USART * pUSART = AT91C_BASE_US0; /* Global Pointer to USART0 */


void init_serial (void) { /* Initialize Serial Interface */

*AT91C_PIOA_PDR = AT91C_PA5_RXD0 | /* Enable RxD0 Pin */
AT91C_PA6_TXD0; /* Enalbe TxD0 Pin */

pUSART->US_CR = AT91C_US_RSTRX | /* Reset Receiver */
AT91C_US_RSTTX | /* Reset Transmitter */
AT91C_US_RXDIS | /* Receiver Disable */
AT91C_US_TXDIS; /* Transmitter Disable */

pUSART->US_MR = AT91C_US_USMODE_NORMAL | /* Normal Mode */
AT91C_US_CLKS_CLOCK | /* Clock = MCK */
AT91C_US_CHRL_8_BITS | /* 8-bit Data */
AT91C_US_PAR_NONE | /* No Parity */
AT91C_US_NBSTOP_1_BIT; /* 1 Stop Bit */

pUSART->US_BRGR = BRD; /* Baud Rate Divisor */

pUSART->US_CR = AT91C_US_RXEN | /* Receiver Enable */
AT91C_US_TXEN; /* Transmitter Enable */
}


int sendchar (int ch) { /* Write character to Serial Port */

if (ch == '\n') { /* Check for CR */
while (!(pUSART->US_CSR & AT91C_US_TXRDY)); /* Wait for Empty Tx Buffer */
pUSART->US_THR = '\r'; /* Output CR */
}
while (!(pUSART->US_CSR & AT91C_US_TXRDY)); /* Wait for Empty Tx Buffer */
return (pUSART->US_THR = ch); /* Transmit Character */
}


int getkey (void) { /* Read character from Serial Port */

while (!(pUSART->US_CSR & AT91C_US_RXRDY)); /* Wait for Full Rx Buffer */
return (pUSART->US_RHR); /* Read Character */
}

Вот шапка.
CODE
AREA IRQ0, CODE, READONLY
ARM

PRESERVE8
ALIGN
IMPORT irq0_nint
EXPORT irq0_int
irq0_int FUNCTION

SUB LR, LR, #4 ; Update Link Register
STMFD SP!, {R0-R12, LR} ; Save Workspace & LR to Stack
MRS R0, SPSR ; Copy SPSR to R0
STMFD SP!, {R0, R1} ; Save SPSR to Stack (8-byte)
MSR CPSR_c, #0x1F ; Enable IRQ (Sys Mode)
STMFD SP!, {R0, LR} ; Save LR_sys to Stack (8-byte)
LDR R0, =irq0_nint ; Get IRQ Function Address
MOV LR, PC ; Return Address
BX R0 ; Call IRQ Function
LDMFD SP!, {R0, LR} ; Restore LR_sys
MSR CPSR_c, #0x92 ; Disable IRQ (IRQ Mode)
LDMFD SP!, {R0, R1} ; Restore SPSR to R0
MSR SPSR_cxsf, R0 ; Copy R0 to SPSR
LDMFD SP!, {R0-R12, PC}^ ; Return to program

ENDFUNC

END


Модератор. Zliva, в следующий раз буду просто удалять такие цитаты из сообщения. Либо форматируйте их сами, оформляя тэгами [ codebox ] и урезая по ширине, либо прилагайте к сообщению в виде текстовых файлов, как это рекомендуют Правила форума.
С уважением, rezident.
Причина редактирования: Нарушение п.3.4 Правил форума.


--------------------
If the person is successful, he is successful in any sphere.
Go to the top of the page
 
+Quote Post
aaarrr
сообщение Aug 23 2009, 16:11
Сообщение #15


Гуру
******

Группа: Свой
Сообщений: 10 713
Регистрация: 11-12-04
Пользователь №: 1 448



Цитата(Zliva @ Aug 23 2009, 19:35) *
Код
        /* Setup IRQ0 Interrupt Mode and Vector with Priority 0 and Enable it */
          /*
          AIC_SMR        -    Регистр источника прерывания 0
          AT91C_ID_IRQ0 -    ID Прерывание для IRQ0
          AT91C_AIC_SRCTYPE_INT_POSITIVE_EDGE    -     Internal Sources Code Label Positive
                                                  Edge triggered - Положительный фронт
          */
  pAIC->AIC_SMR[AT91C_ID_IRQ0] = AT91C_AIC_SRCTYPE_INT_POSITIVE_EDGE | 0;            //     AT91C_AIC_SRCTYPE_INT_POSITIVE_EDGE

Прерывание от IRQ0 является внешним источником, поэтому обратите внимание на такие строки в хидере:
Цитата
#define AT91C_AIC_SRCTYPE_INT_POSITIVE_EDGE ((unsigned int) 0x1 << 5) // (AIC) Internal Sources Code Label Positive Edge triggered
#define AT91C_AIC_SRCTYPE_EXT_NEGATIVE_EDGE ((unsigned int) 0x1 << 5) // (AIC) External Sources Code Label Negative Edge triggered


Цитата(Zliva @ Aug 23 2009, 19:35) *
Вроде все правильно, но почему дважды вызывается прерывание? Все значения пересылаю через USART.

А откуда это видно?

Цитата(Zliva @ Aug 23 2009, 19:35) *
Вот шапка.

Шапка с безобразным оверхедом. Нет никакой необходимости пихать все регистры на стек: R4-R11 и так никто не тронет.
Go to the top of the page
 
+Quote Post

13 страниц V   1 2 3 > » 
Reply to this topicStart new topic
4 чел. читают эту тему (гостей: 4, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 18th July 2025 - 20:46
Рейтинг@Mail.ru


Страница сгенерированна за 0.01498 секунд с 7
ELECTRONIX ©2004-2016