|
ARM. Энкодеры и акселерометры, Помогите решить задачу |
|
|
|
Jul 29 2009, 20:01
|
Частый гость
 
Группа: Участник
Сообщений: 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.
|
|
|
|
|
Jul 30 2009, 08:44
|
Частый гость
 
Группа: Участник
Сообщений: 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.
|
|
|
|
|
Aug 15 2009, 20:01
|
Частый гость
 
Группа: Участник
Сообщений: 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.
|
|
|
|
|
Aug 15 2009, 20:47
|
Частый гость
 
Группа: Участник
Сообщений: 137
Регистрация: 14-11-06
Из: Луцка
Пользователь №: 22 318

|
Цитата(aaarrr @ Aug 15 2009, 23:36)  3. Зависит от Вашей задачи - какой поток, требуется ли гарантированная доставка данных и т.д. и т.п. Стандартными классами пользоваться вовсе не обязательно. Гарантия доставки обязательна. Со стороны компа буду периодично считывать данные. Тогда какой класс выбрать?
--------------------
If the person is successful, he is successful in any sphere.
|
|
|
|
|
Aug 15 2009, 20:57
|
Частый гость
 
Группа: Участник
Сообщений: 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.
|
|
|
|
|
Aug 15 2009, 21:30
|
Частый гость
 
Группа: Участник
Сообщений: 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.
|
|
|
|
|
Aug 15 2009, 22:02
|
Частый гость
 
Группа: Участник
Сообщений: 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.
|
|
|
|
|
Aug 23 2009, 15:35
|
Частый гость
 
Группа: Участник
Сообщений: 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.
|
|
|
|
|
Aug 23 2009, 16:11
|
Гуру
     
Группа: Свой
Сообщений: 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 и так никто не тронет.
|
|
|
|
|
Aug 23 2009, 18:23
|
Частый гость
 
Группа: Участник
Сообщений: 137
Регистрация: 14-11-06
Из: Луцка
Пользователь №: 22 318

|
Цитата(aaarrr @ Aug 23 2009, 19:11)  Прерывание от IRQ0 является внешним источником, поэтому обратите внимание на такие строки в хидере: Вижу в 232analyzer (утилита для работы с ком-портом), что при однократном нажатии кнопки (энкодер лежит с боку, пока не подключал), данные получаю и оны непрерывно поступают, пока кнопка нажата, а я хочу, чтобы происходило прерывание на переходе 0-1. Чем можете помочь? Неужели дребезг? Манипулою так: Прерывания от irq0 заведено на кнопку (симулирую линию энкодера А), а РА20 на кнопку B2(симулирую линию энкодера В). При однократном нажатии на B1 значение убывает, но их приходит очень много. Например, один раз нажал получил значение 9 десть раз. При удерживании В2 нажимаю на B1. Значения идут по возрастающей. Количество резолюций поставил 10 только для тестирования. В реальности энкодер имеет 1024 имп/об. Цитата А откуда это видно? Утилита 232analyzer для работы с ком-портом Цитата Шапка с безобразным оверхедом. Нет никакой необходимости пихать все регистры на стек: R4-R11 и так никто не тронет. Тогда как правильно сделать?
--------------------
If the person is successful, he is successful in any sphere.
|
|
|
|
|
Aug 23 2009, 18:46
|
Гуру
     
Группа: Свой
Сообщений: 10 713
Регистрация: 11-12-04
Пользователь №: 1 448

|
Цитата(Zliva @ Aug 23 2009, 22:23)  Вижу в 232analyzer (утилита для работы с ком-портом), что при однократном нажатии кнопки (энкодер лежит с боку, пока не подключал), данные получаю и оны непрерывно поступают, пока кнопка нажата, а я хочу, чтобы происходило прерывание на переходе 0-1. Чем можете помочь? Неужели дребезг? А что Вас удивляет? Вполне естественно, что кнопка имеет дребезг. Цитата(Zliva @ Aug 23 2009, 22:23)  Утилита 232analyzer для работы с ком-портом Вы не выложили ту часть кода, которая заведует отравкой данных, поэтому судить о наблюдаемой картине никто не возьмется. Цитата(Zliva @ Aug 23 2009, 22:23)  Тогда как правильно сделать? Очевидно, не сохранять лишнее. Если обработчик написан на 'C' без всяких naked, то строки: Код STMFD SP!, {R0-R12, LR} ; Save Workspace & LR to Stack ... LDMFD SP!, {R0-R12, PC}^ ; Return to program можно спокойно заменить на: Код STMFD SP!, {R0-R3, R12, LR} ; Save Workspace & LR to Stack ... LDMFD SP!, {R0-R3, R12, PC}^ ; Return to program Но делать это стоит только при ясном понимании, почему так можно. В противном случае оставьте как есть - процедура все равно рабочая.
|
|
|
|
|
Aug 23 2009, 19:41
|
Частый гость
 
Группа: Участник
Сообщений: 137
Регистрация: 14-11-06
Из: Луцка
Пользователь №: 22 318

|
Не могу понять, почему когда я удерживаю кнопку (как бы дребезга недолжно быть), возникает прерывание? Может здесь pAIC->AIC_SMR[AT91C_ID_IRQ0] = AT91C_AIC_SRCTYPE_INT_POSITIVE_EDGE|0 что-то не так? Даже в симуляторе та же фича. Вот весь проект (на базе Hello.Uv2)
Прикрепленные файлы
Main.rar ( 56.24 килобайт )
Кол-во скачиваний: 19
--------------------
If the person is successful, he is successful in any sphere.
|
|
|
|
|
Aug 24 2009, 08:15
|
Частый гость
 
Группа: Участник
Сообщений: 137
Регистрация: 14-11-06
Из: Луцка
Пользователь №: 22 318

|
Цитата(aaarrr @ Aug 24 2009, 09:17)  Что там не так, я уже написал выше.
Работа с прерываниями по фронту вообще требует предельной внимательности - Вы уверены, что это действительно необходимо? В принципе – да. Уверен. Вы что-то можете предложить другое?
--------------------
If the person is successful, he is successful in any sphere.
|
|
|
|
|
Aug 24 2009, 11:32
|
Частый гость
 
Группа: Участник
Сообщений: 137
Регистрация: 14-11-06
Из: Луцка
Пользователь №: 22 318

|
Цитата(aaarrr @ Aug 24 2009, 13:37)  Для обработки энкодеров логично было бы использовать общее прерывание PIO. Выставляется по любому фронту на выводе (-ах), при этом является внутренним источником для AIC'а. Спасибо, Вам. Если можно, небольшой пример. Может есть смысл задействовать два прерывания на один энкодер? Кажись настроил прерывание по фронту. Но сейчас появилась следующая проблема. Пропуск шагов(или неверный алгоритм работы). Суть такая (на картинке видно устройство и энкодер), рычаг вала энкодера поворачиваю в какое-то крайнее положение до упора. Затем делаю RESET устройства. Проворачиваю до следующего крайнего положения(до упора). Получаю следующую последовательность: 0 - 637 1020-633 1015-627 1010-622 и т.д. Что не так?
Эскизы прикрепленных изображений
--------------------
If the person is successful, he is successful in any sphere.
|
|
|
|
|
Aug 24 2009, 11:48
|
Гуру
     
Группа: Свой
Сообщений: 10 713
Регистрация: 11-12-04
Пользователь №: 1 448

|
Цитата(Zliva @ Aug 24 2009, 15:32)  Если можно, небольшой пример. Может есть смысл задействовать два прерывания на один энкодер? Пример: CODE void pioa_irq_init(void) { AT91C_BASE_AIC->AIC_SVR[AT91C_ID_PIOA] = (unsigned int)irq_pioa; AT91C_BASE_AIC->AIC_SMR[AT91C_ID_PIOA] = AT91C_AIC_SRCTYPE_INT_HIGH_LEVEL | PIOA_IRQ_PRIORITY; AT91C_BASE_AIC->AIC_IECR = (1UL << AT91C_ID_PIOA); AT91C_BASE_SYS->PIOA_IER = PINX_MASK | PINY_MASK; }
__irq void irq_pioa(void) { unsigned int status = AT91C_BASE_SYS->PIOA_ISR; if(status & PINX_MASK) { ... } if(status & PINY_MASK) { ... } AT91C_BASE_AIC->AIC_EOICR = status; } Смысла использовать более одного прерывания не вижу - фронты ведь разнесены по времени. Цитата(Zliva @ Aug 24 2009, 15:32)  Что не так? Что-то не очень понятна последовательность. Что такое "1015-627"? Лучше напишите положение вала и насчитанное число для каждой точки.
Причина редактирования: Уменьшение видимого размера цитаты исходника.
|
|
|
|
|
Aug 24 2009, 12:09
|
Частый гость
 
Группа: Участник
Сообщений: 137
Регистрация: 14-11-06
Из: Луцка
Пользователь №: 22 318

|
Цитата(aaarrr @ Aug 24 2009, 14:48)  Что-то не очень понятна последовательность. Что такое "1015-627"? Лучше напишите положение вала и насчитанное число для каждой точки. Попробую объяснить получше. Суть такая (на картинке видно устройство и энкодер), рычаг вала энкодера поворачиваю в какое-то крайнее положение до упора(соприкосновение двух винтов). Затем делаю RESET устройства (для того, чтобы начать отсчет с нуля). Проворачиваю до следующего крайнего положения рычаг вала энкодера до упора (соприкосновение винта рычага и винта на корпусе энкодера). Затем кручу рычаг в обратную сторону до упора. И так несколько раз. Получаю следующую последовательность в крайних положениях (как изменилось значение положения крайних положениях): 0 - 637 1020-633 1015-627 1010-622 и т.д. Эта последовательность – им/обр. Так как винты размещены на одной оси с упорными винтами(грубо 180 градусов см.рис.), получается такая последовательность. Энкодер за 1 об. делает 1024 импульса. Надеюсь понятно. Но куда деваются значения, непонятно. По правильному(я так думаю), должно быть: 0 - 637 637-0 0 - 637 637-0
--------------------
If the person is successful, he is successful in any sphere.
|
|
|
|
|
Aug 24 2009, 12:30
|
Частый гость
 
Группа: Участник
Сообщений: 137
Регистрация: 14-11-06
Из: Луцка
Пользователь №: 22 318

|
Цитата(aaarrr @ Aug 24 2009, 15:15)  Ну, если даже направление теряется, то это похоже на косяк в алгоритме. Код приведите. <Здесь была цитата исходника>. Удалено модератором (rezident).
Причина редактирования: Нарушение п.3.4 Правил форума.
--------------------
If the person is successful, he is successful in any sphere.
|
|
|
|
|
Aug 24 2009, 12:56
|
Частый гость
 
Группа: Участник
Сообщений: 137
Регистрация: 14-11-06
Из: Луцка
Пользователь №: 22 318

|
Цитата(aaarrr @ Aug 24 2009, 15:49)  Получается, что Вы по заднему фронту сигнала B смотрите сигнал B. Естественно, код все время инкрементируется. Тыкните пальцем, слепой.
--------------------
If the person is successful, he is successful in any sphere.
|
|
|
|
|
Aug 24 2009, 13:12
|
Гуру
     
Группа: Свой
Сообщений: 10 713
Регистрация: 11-12-04
Пользователь №: 1 448

|
Цитата(Zliva @ Aug 24 2009, 16:56)  Тыкните пальцем, слепой.  Пардон, комментарий вместо кода прочитал: Код #define ENCODER1_A (1<<20) // PA19 #define ENCODER1_B (1<<19) // PA20 Но все равно проверьте. И еще: тактирование PIO включить не забыли? Прерывания так будут работать, а из PDSR будут постоянно читаться нули. Очень похоже. P.S. Пожалуйста, убирайте закомментированные куски из выкладываемого кода.
|
|
|
|
|
Aug 24 2009, 13:27
|
Частый гость
 
Группа: Участник
Сообщений: 137
Регистрация: 14-11-06
Из: Луцка
Пользователь №: 22 318

|
Цитата(aaarrr @ Aug 24 2009, 16:12)  Пардон, комментарий вместо кода прочитал: Код #define ENCODER1_A (1<<20) // PA19 #define ENCODER1_B (1<<19) // PA20 Но все равно проверьте. И еще: тактирование PIO включить не забыли? Прерывания так будут работать, а из PDSR будут постоянно читаться нули. Очень похоже. В main определил *AT91C_PMC_PCER = (1 << AT91C_ID_PIOA) | (1 << AT91C_ID_IRQ0) | (1 << AT91C_ID_US0); Пробувал и по AT91C_AIC_SRCTYPE_INT_POSITIVE_EDGE и по AT91C_AIC_SRCTYPE_EXT_NEGATIVE_EDGE ничего. Никаких изменений.
--------------------
If the person is successful, he is successful in any sphere.
|
|
|
|
|
Aug 24 2009, 14:09
|
Частый гость
 
Группа: Участник
Сообщений: 137
Регистрация: 14-11-06
Из: Луцка
Пользователь №: 22 318

|
Решил сделать просто: Код void irq0_nint (void) { if ((pPIO->PIO_PDSR & ENCODER1_B) == 0) { ENCODER1_Position++;} else { ENCODER1_Position--; } *AT91C_AIC_EOICR = 0; AT91C_BASE_PIOA->PIO_ISR;} и посмотреть, что получилось. Так вот. Цитата(Zliva @ Aug 24 2009, 15:09)  .....рычаг вала энкодера поворачиваю в какое-то крайнее положение до упора(соприкосновение двух винтов). Затем делаю RESET устройства (для того, чтобы начать отсчет с нуля). Проворачиваю до следующего крайнего положения рычаг вала энкодера до упора (соприкосновение винта рычага и винта на корпусе энкодера). Затем кручу рычаг в обратную сторону до упора. И так несколько раз. Получаю следующую последовательность в крайних положениях (как изменилось значение положения крайних положениях): 0-205->{Вращаю влево} 205-1->{Вращаю вправо} 1-206->{Вращаю влево} 206-2->{Вращаю вправо} 2-207 ->{Вращаю влево} 207-3->{Вращаю вправо} 3-208->{Вращаю влево} и т.д. Значение постоянно смещается на 205. Где грабли непойму.
--------------------
If the person is successful, he is successful in any sphere.
|
|
|
|
|
Aug 24 2009, 18:17
|
Частый гость
 
Группа: Участник
Сообщений: 137
Регистрация: 14-11-06
Из: Луцка
Пользователь №: 22 318

|
Цитата(aaarrr @ Aug 24 2009, 19:35)  Так и задействуйте общее прерывание PIO - так Вы будете получать прерывание на каждый фронт каждого сигнала. Это меня устраивает. Помогите пожалуйста сконфигурировать стартап irq_pioa.s для прерывания irq_pioa с использованием Ваших функций, которые Вы приводили немного выше. И кстати, переменную PIOA_IRQ_PRIORITY Вы как определили?
--------------------
If the person is successful, he is successful in any sphere.
|
|
|
|
|
Aug 24 2009, 19:23
|
Гуру
     
Группа: Свой
Сообщений: 10 713
Регистрация: 11-12-04
Пользователь №: 1 448

|
Цитата(Zliva @ Aug 24 2009, 22:17)  Это меня устраивает. Помогите пожалуйста сконфигурировать стартап irq_pioa.s для прерывания irq_pioa с использованием Ваших функций, которые Вы приводили немного выше. Не совсем понял, в чем состоит вопрос. Просто уберите модификатор __irq для использования с вложенными вызовами. Цитата(Zliva @ Aug 24 2009, 22:17)  И кстати, переменную PIOA_IRQ_PRIORITY Вы как определили? Это просто макрос. Код #define PIOA_IRQ_PRIORITY 7
|
|
|
|
|
Aug 24 2009, 19:34
|
Частый гость
 
Группа: Участник
Сообщений: 137
Регистрация: 14-11-06
Из: Луцка
Пользователь №: 22 318

|
Цитата(aaarrr @ Aug 24 2009, 22:23)  Это просто макрос. Код #define PIOA_IRQ_PRIORITY 7 Спасибо. Цитата Не совсем понял, в чем состоит вопрос. Просто уберите модификатор __irq для использования с вложенными вызовами. Есть у меня файл с названием IRQ0.s. Там прописано Код AREA IRQ0, CODE, READONLY ARM PRESERVE8 ALIGN IMPORT irq0_nint EXPORT irq0_int irq0_int FUNCTION SUB LR, LR, #4 STMFD SP!, {R0-R3, R12, LR} MRS R0, SPSR STMFD SP!, {R0, R1} MSR CPSR_c, #0x1F STMFD SP!, {R0, LR} LDR R0, =irq0_nint MOV LR, PC BX R0 LDMFD SP!, {R0, LR} MSR CPSR_c, #0x92 LDMFD SP!, {R0, R1} MSR SPSR_cxsf, R0 LDMFD SP!, {R0-R3, R12, PC}^ ; ENDFUNC END Как сюда влепить для PIOA прерывания. Или я с терминологией путаюсь?
--------------------
If the person is successful, he is successful in any sphere.
|
|
|
|
|
Aug 24 2009, 20:25
|
Частый гость
 
Группа: Участник
Сообщений: 137
Регистрация: 14-11-06
Из: Луцка
Пользователь №: 22 318

|
Цитата(aaarrr @ Aug 24 2009, 22:37)  Это же просто универсальная обертка. Переименуйте irq0_nint и irq0_int, если хотите, и все. Ничего не получается с прерыванием от PIOA. Все сделал как Вы говорили – НИЧЕГО. Что-то виснет микроконтроллер. Когда комментирую pioa_irq_init() все работает (прерывания не работают), лампочки дрыгаются. Вложу исподники. Посмотрите пожалуйста.
--------------------
If the person is successful, he is successful in any sphere.
|
|
|
|
|
Aug 24 2009, 20:35
|
Частый гость
 
Группа: Участник
Сообщений: 137
Регистрация: 14-11-06
Из: Луцка
Пользователь №: 22 318

|
Цитата(aaarrr @ Aug 24 2009, 23:29)  Дык __irq уберите. Убрал. Все равно висим. В симуляторе вроде ОК.
Сообщение отредактировал Zliva - Aug 24 2009, 20:39
--------------------
If the person is successful, he is successful in any sphere.
|
|
|
|
|
Aug 24 2009, 20:58
|
Частый гость
 
Группа: Участник
Сообщений: 137
Регистрация: 14-11-06
Из: Луцка
Пользователь №: 22 318

|
Цитата(aaarrr @ Aug 24 2009, 23:53)  AT91C_AIC_SRCTYPE_INT_POSITIVE_EDGE - здесь фронт уже не нужен, т.е. вреден. Фронты отловит контроллер PIO. Все равно висим. Может что-то здесь AREA IRQ0, CODE, READONLY?
--------------------
If the person is successful, he is successful in any sphere.
|
|
|
|
|
Aug 24 2009, 21:13
|
Гуру
     
Группа: Свой
Сообщений: 10 713
Регистрация: 11-12-04
Пользователь №: 1 448

|
Цитата(Zliva @ Aug 25 2009, 00:58)  Все равно висим. Может что-то здесь AREA IRQ0, CODE, READONLY? Ну, на зависании это и не должно было сказаться. Извините, если ввел в заблуждение. Что-то не вижу в упор никаких проблем  Убрать только __irq из void irq_pioa_nin(void) - и все должно работать. Цитата(Zliva @ Aug 25 2009, 00:58)  Может что-то здесь AREA IRQ0, CODE, READONLY? Нет, не может.
|
|
|
|
|
Aug 24 2009, 21:34
|
Частый гость
 
Группа: Участник
Сообщений: 137
Регистрация: 14-11-06
Из: Луцка
Пользователь №: 22 318

|
Убрал строчку printf ("E1=%d\n",ENCODER1_Position); с тела прерывания. ЗАРАБОТАЛО
--------------------
If the person is successful, he is successful in any sphere.
|
|
|
|
|
Aug 25 2009, 19:07
|
Частый гость
 
Группа: Участник
Сообщений: 137
Регистрация: 14-11-06
Из: Луцка
Пользователь №: 22 318

|
Попробовал несколько вариантов обработки сигналов энкодера от PIOA. Целый день промаялся. Что-то ничего не получается. Вот код: Код void irq_pioa_nin(void){ unsigned int status = AT91C_BASE_SYS->PIOA_ISR; if(status & ENCODER1_A) if ((pPIO->PIO_PDSR & ENCODER1_B) == 0) { ENCODER1_Position++;} else { ENCODER1_Position--;} if(status & ENCODER1_B) if ((pPIO->PIO_PDSR & ENCODER1_A) == 1) { ENCODER1_Position++;} else { ENCODER1_Position--;} AT91C_BASE_AIC->AIC_EOICR = status; } Хочу прутя в одну сторону получить возрастание значения ENCODER1_Position, в другую – убывания.
--------------------
If the person is successful, he is successful in any sphere.
|
|
|
|
|
Aug 25 2009, 19:53
|
Частый гость
 
Группа: Участник
Сообщений: 137
Регистрация: 14-11-06
Из: Луцка
Пользователь №: 22 318

|
Цитата(aaarrr @ Aug 25 2009, 22:45)  У Вас получается одинаковая обработка вне зависимости от полярности фронта, что неправильно. Тогда как лучше сделать?
--------------------
If the person is successful, he is successful in any sphere.
|
|
|
|
|
Aug 25 2009, 19:54
|
Гуру
     
Группа: Свой
Сообщений: 10 713
Регистрация: 11-12-04
Пользователь №: 1 448

|
Цитата(Zliva @ Aug 25 2009, 23:53)  Тогда как лучше сделать? Я бы сделал примерно так: CODE signed char enc_step[16] = { // Previous Current Increment // AB AB // 0, // 00 00 1, // 00 01 +1 -1, // 00 10 -1 0, // 00 11 -1, // 01 00 -1 0, // 01 01 0, // 01 10 1, // 01 11 +1 1, // 10 00 +1 0, // 10 01 0, // 10 10 -1, // 10 11 -1 0, // 11 00 -1, // 11 01 -1 1, // 11 10 +1 0 // 11 11 };
void irq_pioa_nin(void) { unsigned int status = AT91C_BASE_SYS->PIOA_ISR, a, b, pa, pb;
a = (AT91C_BASE_PIOA->PIO_PDSR & ENCODER1_A) ? 1 : 0; b = (AT91C_BASE_PIOA->PIO_PDSR & ENCODER1_B) ? 1 : 0; pa = (status & ENCODER_A) ? a ^ 1 : a; pb = (status & ENCODER_B) ? b ^ 1 : b;
ENCODER1_Position += enc_step[(pa << 3) | (pb << 2) | (a << 1) | b];
AT91C_BASE_AIC->AIC_EOICR = status; }
Но еще не грех добавить аппаратный или программный антидребезг. В последнем случае прерывания непосредственно от выводов не нужны, все обрабатывается по таймеру.
|
|
|
|
|
Aug 25 2009, 20:22
|
Частый гость
 
Группа: Участник
Сообщений: 137
Регистрация: 14-11-06
Из: Луцка
Пользователь №: 22 318

|
aaarrr СПАСИБО. ЗАРАБОТАЛО!!! Цитата(aaarrr @ Aug 25 2009, 22:54)  Я бы сделал примерно так: Но еще не грех добавить аппаратный или программный антидребезг. В последнем случае прерывания непосредственно от выводов не нужны, все обрабатывается по таймеру. Не пойму зачем. Я писал, что энкодер оптический, и имеет логику на выходе(0=0в,1 = +5в). Еще одно. Как сюда добавить переменную, которая несет в себе информацию о количестве штришков на энкодере, и связать ее с переменной ENCODER1_Position, то есть, когда ENCODER1_Position ==1023 (1024 импульса/об), то ENCODER1_Position =0, Но когда ENCODER1_Position ==-1 - ENCODER1_Position =1023? аaarrr, еще раз спасибо
--------------------
If the person is successful, he is successful in any sphere.
|
|
|
|
|
Aug 25 2009, 20:32
|
Гуру
     
Группа: Свой
Сообщений: 10 713
Регистрация: 11-12-04
Пользователь №: 1 448

|
Цитата(Zliva @ Aug 26 2009, 00:22)  Не пойму зачем. Я писал, что энкодер оптический, и имеет логику на выходе(0=0в,1 = +5в). Я просто всегда держу в голове худший вариант. Если энкодер приличный, то можно и обойтись. Цитата(Zliva @ Aug 26 2009, 00:22)  Еще одно. Как сюда добавить переменную, которая несет в себе информацию о количестве штришков на энкодере, и связать ее с переменной ENCODER1_Position, то есть, когда ENCODER1_Position ==1023 (1024 импульса/об), то ENCODER1_Position =0, Но когда ENCODER1_Position ==-1 - ENCODER1_Position =1023?  Ну а тут то какие могут быть проблемы? Только не 1023, а 1024 в первом случае. Код ENCODER1_Position += enc_step[(pa << 3) | (pb << 2) | (a << 1) | b]; if(ENCODER1_Position < 0) ENCODER1_Position = ENCODER1_Resolution - 1; else if(ENCODER1_Position == ENCODER1_Resolution) ENCODER1_Position = 0;
|
|
|
|
|
Aug 25 2009, 20:50
|
Частый гость
 
Группа: Участник
Сообщений: 137
Регистрация: 14-11-06
Из: Луцка
Пользователь №: 22 318

|
aaarrr СПАСИБО. Заменил volatile int ENCODER1_Position = 0; вместо volatile unsigned int ENCODER1_Position = 0;и вставил код: Код if (ENCODER1_Position == ENCODER1_resolution){ ENCODER1_Position = 0;} if (ENCODER1_Position == -1){ ENCODER1_Position = ENCODER1_resolution-1;} Думаю вопрос о определении положения можно считать РЕШЕННЫМ. Давайте обсудим вопрос о определении скорости вала энкодера. Какие будут мысли?
--------------------
If the person is successful, he is successful in any sphere.
|
|
|
|
|
Aug 26 2009, 05:52
|
Частый гость
 
Группа: Участник
Сообщений: 137
Регистрация: 14-11-06
Из: Луцка
Пользователь №: 22 318

|
Цитата(aaarrr @ Aug 26 2009, 00:07)  Давайте. Только изложите сначала свои, а мы их потом "подумаем", хорошо? Хорошо! Излагаю теорию. Скорость – первая производная по перемещению от времени Omega(t)=d phi/dt (еще говорят скорость изменения положения), или исходя из определения производной, прирост функции к приросту аргумента Omega(t)=delta phi/ delta t. Для того, что бы определить скорость нужно от Omega(t)= {ENCODER1_Positionn- ENCODER1_Position(n-1)}/{ttimen - ttime(n-1)}, если неверно формулирую – поправьте. Соответственно ускорение - первая производная по скорости от времени или вторая производная по перемещению от времени (еще говорят скорость изменения скорости). Тут возникает вопрос связан с переменой ttime, то есть, как ее лучше определить? Что бы она генерировалась таймером? примечание. Изложена теория относиться как и к линейному перемещению (скорости, ускорению) так и к угловому перемещению(скорости, ускорению), но разница между ними большая.
--------------------
If the person is successful, he is successful in any sphere.
|
|
|
|
|
Aug 26 2009, 12:08
|
Частый гость
 
Группа: Участник
Сообщений: 137
Регистрация: 14-11-06
Из: Луцка
Пользователь №: 22 318

|
Цитата(aaarrr @ Aug 26 2009, 13:55)  Ее даже не обязательно вводить - можно просто вычислять скорость, оценивая перемещение через равные промежутки времени (по таймеру). Я на копе хочу выводить зависимость phi(t), Omega(t), но пока не знаю, что выбрать таймер или интервальный таймер (PIT) для генерации временной характеристики ttime. В любом случаи ttime понадобится. Использование таймера мне понадобится для определения ускорения по захвату, так как выходи у акселерометра - сигнал ШИМ. Что насчет этого думаете?
--------------------
If the person is successful, he is successful in any sphere.
|
|
|
|
Guest_@Ark_*
|
Aug 26 2009, 13:44
|
Guests

|
Цитата Ее даже не обязательно вводить - можно просто вычислять скорость, оценивая перемещение через равные промежутки времени (по таймеру). Дык, автору неоднократно это уже советовали (в предыдущих двух темах).  Но он, почему-то, упорно идет своим путем, и никак не хочет упростить себе задачу... to Zliva: Зачем Вам фиксировать и передавать время на каждый "тик" энкодера? Не нужно этого делать! Все что необходимо в этой задаче - это 1 раз каждую миллисекунду (точно по таймеру) копировать счетчики обоих энкодеров, АЦП-ровать два канала акселерометра, формировать пакет для передачи и передавать его в компьютер. И все! В компьютере Вы принимаете пакеты последовательно и уже знаете, что время для них отличается на 1мс. Текущее значение счетчика энкодера - это и есть текущее угловое положение вала, только в отсчетах энкодера. Домножьте на соответствующий коэффициент - получите радианы или градусы (что Вам нужно?). Разница между двумя значениями счетчика энкодера из соседних пакетов - это уже и есть угловая скорость, только в размерности [отсчетов энкодера/мс]. Также можете перевести ее в [радиан/сек] или [градус/сек]. Разница между соседними значениями скоростей - это угловое ускорение в [отсчетов энкодера/мс^2]. Переведите в [радиан/сек^2] или [градус/сек^2]. Дальше можно заниматься аппрокимацией, обработкой и так далее. Как видите, Ваша задача в основном решается программными методами в ПК. От микроконтроллера требуется только "ведение" счетчиков энкодеров (по прерываниям), периодический съем значений этих счетчиков и двух каналов АЦП (точно 1 раз в 1 мс) и передача пакетов известного формата в компьютер. Напрямую, без всяких запросов со стороны ПК. Зачем Вы взяли ARM для этой задачи? Это задача для AVR или PIC среднего размера, тем более что c AVR Вы знакомы, как говорили. Зачем связались с USB, если нет опыта работы с ним? Через обычный UART можно спокойно передать всю информацию. Дальше - поставьте готовый мост UART-RS232 или UART-USB, и принимайте данные в ПК через COM-порт... P.S. Если Ваша цель не только решить задачу, но и попутно освоить ARM, USB-интерфейс и так далее, тогда выбор понятен. Если же Вы решаете конкретную практическую задачу (для заказчика), то, по-моему, Вы только усложняете себе жизнь и выполняете массу бесполезной работы.
|
|
|
|
|
Aug 26 2009, 14:24
|
Частый гость
 
Группа: Участник
Сообщений: 137
Регистрация: 14-11-06
Из: Луцка
Пользователь №: 22 318

|
Спасибо за наставление. Но я как-то другого пути не вижу кроме намеченного. Чтобы корректно аппроксимировать нужны точки для Х и для Y, тому нужно значение фиксировать. Полученое значение [отсчетов энкодера/мс], будут переводится на компе в(градус/сек, радиан/сек и.т.). Цитата От микроконтроллера требуется только "ведение" счетчиков энкодеров (по прерываниям), периодический съем значений этих счетчиков и двух каналов АЦП (точно 1 раз в 1 мс) и передача пакетов известного формата в компьютер. Напрямую, без всяких запросив… Все верно. Задача не коммерческая. Работаю над дисером. Сам инженер конструктор торгового оборудования(стеллажи, витрины), а освоение ARM, USB-интерфейс дело для меня принципиальное. Хочу и все.
--------------------
If the person is successful, he is successful in any sphere.
|
|
|
|
Guest_@Ark_*
|
Aug 26 2009, 15:18
|
Guests

|
Цитата Но я как-то другого пути не вижу кроме намеченного... Собственно, возможных путей-то здесь два. Первый (по которому Вы идете) - фиксировать время по таймеру при каждой смене положения энкодера и передавать все это в компьютер. Второй (который Вам предлагается) - фиксировать "набежавшее" значение счетчика энкодера в строго определенные моменты времени - через каждые 1мс. И передавать только последовательность значений счетчиков с известным точным временным интервалом между ними (1мс). Разница в объемах передаваемой информации может быть очень значительной - в первом случае может быть на порядок или два больше. Соотвественно, требования к аппаратуре и каналом информации будут намного выше. Самое интересное, что в конечной точности Вы почти ничего не выиграете...
|
|
|
|
|
Aug 26 2009, 15:30
|
Частый гость
 
Группа: Участник
Сообщений: 137
Регистрация: 14-11-06
Из: Луцка
Пользователь №: 22 318

|
Цитата(@Ark @ Aug 26 2009, 18:18)  Собственно, возможных путей-то здесь два.
Первый (по которому Вы идете) - .... Хорошо. Уболтали. Давайте «не вам и не нам». Сделаю два варианта и посмотрю, что лучше. Я думаю что это реально. Перед запуском системы просто буду выбирать один из двух режимов. Годится?
--------------------
If the person is successful, he is successful in any sphere.
|
|
|
|
Guest_@Ark_*
|
Aug 26 2009, 15:42
|
Guests

|
Это Вам решать как делать. Советы Вы все равно не очень слушаете. Если задача не коммерческая, то можете реализовать оба варианта и сравнить. Думаю, будет полезно для понимания некоторых вещей. Вы сейчас, к сожалению, некоторые проблемы просто не воспринимаете, так как не сталкивались с ними на практике... Желаю удачи.
|
|
|
|
|
Aug 26 2009, 15:58
|
Частый гость
 
Группа: Участник
Сообщений: 137
Регистрация: 14-11-06
Из: Луцка
Пользователь №: 22 318

|
@Ark Спасибо за комментарии! Согласен. Опыта маловато. Для того это и делается, что бы его получить. Поскольку Вы первым написали и предложили свой вариант, ему и жизнь. Думаю делать так. Задействую RTT для генерации прерываний. Коэффициент деления поставлю RTPRES=32, то тогда время генерации прерываний будет составлять 32/32768=0,976563мс. Сейчас вбиваю код. Когда сделаю, отчитаюсь
--------------------
If the person is successful, he is successful in any sphere.
|
|
|
|
|
Aug 26 2009, 20:03
|
Частый гость
 
Группа: Участник
Сообщений: 137
Регистрация: 14-11-06
Из: Луцка
Пользователь №: 22 318

|
Цитата(aaarrr @ Aug 26 2009, 19:20)  Ох. Забудьте про RTT - это самый бесполезный таймер кристалла. Тактируется он от RC-генератора, поэтому 32768 там весьма условные. Кроме того, есть косяк с генерацией прерываний.
Для генерации равномерных временных меток следует использовать PIT. Понял. Тогда как посчитать PIV для частоты 1кГц, при МСК = 47.923200МГц? Что-то у меня не выходит. Верно ли я понял 47 923 200/1000=47923,2 Приблизительно 47923 Цитата(Zliva @ Aug 26 2009, 22:35)  Понял. Тогда как посчитать PIV для частоты 1кГц, при МСК = 47.923200МГц? Что-то у меня не выходит. Верно ли я понял 47 923 200/1000=47923,2 Приблизительно 47923 Сам себе отвечу. Нужно еще поделить на 16 значение 47923, так как PIT тактируется через делитель МСК/16
Сообщение отредактировал Zliva - Aug 26 2009, 19:38
--------------------
If the person is successful, he is successful in any sphere.
|
|
|
|
|
Aug 30 2009, 14:55
|
Частый гость
 
Группа: Участник
Сообщений: 137
Регистрация: 14-11-06
Из: Луцка
Пользователь №: 22 318

|
Цитата(Zliva @ Aug 26 2009, 23:36)  Возникла новая проблема. С PIT вроде разобрался. Теперь появилась новая проблема, связанная с расстановкой приоритетов и пропуском значений энкодера. Буду разбираться. Проблема еще актуальна. Наконец-то спаял датчик ускорения ADXL-210. Теперь в ступоре. Дело в том, что я планировал подключать его к ТС по захвату, но теперь сомневаюсь. Там на выход датчика ШИМ. Как его лучше привязать к прерываниям по PIOA или по таймеру?
--------------------
If the person is successful, he is successful in any sphere.
|
|
|
|
|
Aug 30 2009, 21:19
|
Частый гость
 
Группа: Участник
Сообщений: 137
Регистрация: 14-11-06
Из: Луцка
Пользователь №: 22 318

|
Скопировал пример с ИАР и компильнул его под свою задачу. Что-то он не идет. Прерывания не работают. Где может быть косяк?
--------------------
If the person is successful, he is successful in any sphere.
|
|
|
|
|
Aug 31 2009, 18:21
|
Частый гость
 
Группа: Участник
Сообщений: 137
Регистрация: 14-11-06
Из: Луцка
Пользователь №: 22 318

|
С прерываниями разобрался. Записал инициализацию так: Код pAIC->AIC_SMR[AT91C_ID_TC0] = AT91C_AIC_SRCTYPE_INT_HIGH_LEVEL | TIMER0_INTERRUPT_LEVEL; pAIC->AIC_SVR[AT91C_ID_TC0] = (unsigned long) timer0_c_irq_handler; pAIC->AIC_IECR = (1UL << AT91C_ID_TC0); кажись работает. Помогите разобраться с ТС в режиме захвата. Вот что нашел в интернете (www.analog.com.ru/Public/AN604R.pdf), но как это все привязать для измерения ширины импульсов от датчика ускорения – не могу понять, то есть понимаю, но теоретически. Из документации следует, что с помощью захвата это легко делается, но у меня не получается. Помогите хотя бы получить интервалы Т1 и Т2 для X и Y.
--------------------
If the person is successful, he is successful in any sphere.
|
|
|
|
|
Aug 31 2009, 20:33
|
Гуру
     
Группа: Свой
Сообщений: 10 713
Регистрация: 11-12-04
Пользователь №: 1 448

|
Цитата(Zliva @ Aug 31 2009, 22:21)  С прерываниями разобрался. Записал инициализацию так: кажись работает. Кажись, или работает? Нужно было или добавить обертку, или дописать __irq к timer0_c_irq_handler. Цитата(Zliva @ Aug 31 2009, 22:21)  Помогите разобраться с ТС в режиме захвата. Вот что нашел в интернете (www.analog.com.ru/Public/AN604R.pdf), но как это все привязать для измерения ширины импульсов от датчика ускорения – не могу понять, то есть понимаю, но теоретически. Из документации следует, что с помощью захвата это легко делается, но у меня не получается. Помогите хотя бы получить интервалы Т1 и Т2 для X и Y. Ну а что мешает перейти к практике? - сконфигурируйте таймер в режиме capture с внутренним тактированием - подайте сигнал ШИМ на вход TIOA таймера - настройте LDRA на захват по переднему фронту TIOA - настройте LDRB на захват по заднему фронту TIOA В прерывании LDRA считаете период ШИМ, в LDRB - длительность импульса. Вот и все.
|
|
|
|
|
Aug 31 2009, 20:48
|
Частый гость
 
Группа: Участник
Сообщений: 137
Регистрация: 14-11-06
Из: Луцка
Пользователь №: 22 318

|
Прерывания работают. Все заделал как Вы писали. Верно ли я понял, замыкаю два входа TIOA1 и TIOВ1. Конфигурирую так как описано выше и измеряю X, затем также и для TIOA0 и TIOВ0 и измеряю Y.
--------------------
If the person is successful, he is successful in any sphere.
|
|
|
|
|
Sep 1 2009, 10:29
|
Частый гость
 
Группа: Участник
Сообщений: 137
Регистрация: 14-11-06
Из: Луцка
Пользователь №: 22 318

|
Цитата(aaarrr @ Sep 1 2009, 00:03)  Нет. И LDRA и LDRB срабатывают по TIOA, TIOB вообще не нужен в данном случае. Настроил захват для измерения ШИМ. Может будут какие-то комментарии. Сейчас на работе, реально залью прошивку дома. Код void AT91F_TC_Open ( AT91PS_TC TC_pt, unsigned int Mode, unsigned int TimerId) { unsigned int dummy; AT91F_PMC_EnablePeriphClock ( AT91C_BASE_PMC, 1<< TimerId ); TC_pt->TC_CCR = AT91C_TC_CLKDIS; TC_pt->TC_IDR = 0xFFFFFFFF; dummy = TC_pt->TC_SR; dummy = dummy; TC_pt->TC_CMR = Mode; TC_pt->TC_CMR = ((unsigned int) 0x0 << 15) | AT91C_TC_CLKI | AT91C_TC_BURST_NONE | AT91C_TC_LDBSTOP | AT91C_TC_LDBDIS | AT91C_TC_ETRGEDG_NONE | AT91C_TC_LDRA_RISING | AT91C_TC_LDRB_FALLING; TC_pt->TC_CCR = AT91C_TC_CLKEN; } В режиме симулятора timer1 работает. Дергаю PIN15 в симуляторе работает. Но когда дергаю PIN0 (смотрите схему), появляется You have tried to modify a port pin which is configured as output! Что делать? И еще глупые вопросы. Как после прерывания сбросить после считывания в 0? Что означает эта запись «dummy = dummy»? p.s. aaarrr – Вам огромное человеческое СПАСИБО. Хоть кто-то поддерживает меня. Не люблю быть должным. Со временем буду это все оформлять в статью. Если Вы не против, могу Вас включить.
--------------------
If the person is successful, he is successful in any sphere.
|
|
|
|
|
Sep 2 2009, 12:30
|
Гуру
     
Группа: Свой
Сообщений: 10 713
Регистрация: 11-12-04
Пользователь №: 1 448

|
Цитата(Zliva @ Sep 1 2009, 14:29)  В режиме симулятора timer1 работает. Дергаю PIN15 в симуляторе работает. Но когда дергаю PIN0 (смотрите схему), появляется You have tried to modify a port pin which is configured as output! Что делать? PIN0 - TIOA0, и относится к нулевому таймеру, его сконфигурировать не забыли? Цитата(Zliva @ Sep 1 2009, 14:29)  Как после прерывания сбросить после считывания в 0? Не понял вопрос. Цитата(Zliva @ Sep 1 2009, 14:29)  Что означает эта запись «dummy = dummy»? Это достаточно некрасивый трюк для подавления warning'а компилятора. Код dummy = TC_pt->TC_SR; dummy = dummy; можно заменить на Код TC_pt->TC_SR; Цитата(Zliva @ Sep 1 2009, 14:29)  Если Вы не против, могу Вас включить. Спасибо, конечно, но не стоит
|
|
|
|
|
Sep 2 2009, 17:41
|
Частый гость
 
Группа: Участник
Сообщений: 137
Регистрация: 14-11-06
Из: Луцка
Пользователь №: 22 318

|
Цитата(aaarrr @ Sep 2 2009, 15:30)  PIN0 - TIOA0, и относится к нулевому таймеру, его сконфигурировать не забыли? Как его настроить? Цитата Не понял вопрос. У меня сначала прога в прерывание заходила один раз и все. Но когда закомментировал AT91C_TC_LDBDIS, все вроде заработало. Верно ли я сконфигурировал TC_CMR? И еще. Сегодня пробовал тестировать на осциллографе дачик ускорения. Все вроде ок. ШИМ генерируется, аналоговый выход работает, но когда я кручу плату в плоскости X, Y(плоскость перпендикулярна земле) -. Взял контактор на 220В для эксперимента. Прикрепил дачки к якорю. Придерживая контактор отверткой изменяю его амплитуду. Изменений ШИМ и аналога нет. Тряс, крутил, что только не делал(по нем не прыгал) ничего. Можно считать что механика в нутрии датчика умерла? Кто нибудь работал с серией ADXL202/210? Думаю приобрести такой же датчик (просто все под него сделано) и парочку LIS302DL с интерфейсом SPI и на три оси. Что народ скажет?
Сообщение отредактировал Zliva - Sep 2 2009, 18:02
--------------------
If the person is successful, he is successful in any sphere.
|
|
|
|
|
Sep 2 2009, 18:23
|
Гуру
     
Группа: Свой
Сообщений: 10 713
Регистрация: 11-12-04
Пользователь №: 1 448

|
Цитата(Zliva @ Sep 2 2009, 21:41)  Как его настроить? Понятно, это была только часть кода. Что-то не вижу настройки PIO для TIOAx. Старайтесь не копировать "библиотечные" функции типа AT91F_ - получаете набор маразмов (типа dummy) и просто ошибок как здесь: Код void AT91F_TC_Open ( AT91PS_TC TC_pt, unsigned int Mode, unsigned int TimerId) { ... TC_pt->TC_CMR = Mode;
TC_pt->TC_CMR = ((unsigned int) 0x0 << 15) /*0 -режим захвата разрешен.*/ Mode пишется в никуда. Цитата(Zliva @ Sep 2 2009, 21:41)  У меня сначала прога в прерывание заходила один раз и все. Но когда закомментировал AT91C_TC_LDBDIS, все вроде заработало. Верно ли я сконфигурировал TC_CMR? А зачем запрещать или останавливать (как это сделано сейчас) таймер по LDRB? Так же все измерения лесом пойдут.
|
|
|
|
|
Sep 2 2009, 19:20
|
Частый гость
 
Группа: Участник
Сообщений: 137
Регистрация: 14-11-06
Из: Луцка
Пользователь №: 22 318

|
Цитата(aaarrr @ Sep 2 2009, 21:23)  Понятно, это была только часть кода. Что-то не вижу настройки PIO для TIOAx.
Старайтесь не копировать "библиотечные" функции типа AT91F_ - получаете набор маразмов (типа dummy) и просто ошибок как здесь: Mode пишется в никуда. Что именно здесь не так? Вот так инициализирую. Больше нигде не используется TIOA. Или нужно где-то прописать TIOA еще? Код #define TIOA0 (1<<0) #define TIOA1 (1<<15) #define TIOA0_MASK (1<<0) #define TIOA1_MASK (1<<15) #define TIOA_MASK (TIOA0_MASK|TIOA1_MASK) ……. int main (void) { *AT91C_PMC_PCER = (1UL << AT91C_ID_PIOA) | (1UL << AT91C_ID_IRQ0) | (1UL << AT91C_ID_US0) | (1UL << AT91C_ID_TC1);
pPIO->PIO_PER = LED_MASK; pPIO->PIO_OER = LED_MASK; pPIO->PIO_SODR = LED_MASK;
init_timer (); pioa_irq_init(); init_serial(); timer_init ();
while (1) { pPIO->PIO_CODR = LED1; wait(10); printf ("E1=%8.2f",accel_X); pPIO->PIO_SODR = LED1; wait(10); } } Что скажете насчет работоспособности датчика. Пост выше?
--------------------
If the person is successful, he is successful in any sphere.
|
|
|
|
|
Sep 3 2009, 10:37
|
Гуру
     
Группа: Свой
Сообщений: 10 713
Регистрация: 11-12-04
Пользователь №: 1 448

|
Цитата(Zliva @ Sep 2 2009, 23:20)  Вот так инициализирую. Больше нигде не используется TIOA. Или нужно где-то прописать TIOA еще? Тут только дефайны, где инициализация? Нужно перевести TIOAx в режим Peripheral. Цитата(Zliva @ Sep 3 2009, 12:37)  Подскажите пожалуйста (код выше). Дело в том что если LDRBS = 1 значение в В заноситься (спадающий фронт), LDRАS = 1 значение в А заноситься (нарастающий фронт). В чем может быть проблема? Что я делаю не так? Постарайтесь описать проблему так, чтобы можно было понять.
|
|
|
|
|
Sep 3 2009, 15:02
|
Частый гость
 
Группа: Участник
Сообщений: 137
Регистрация: 14-11-06
Из: Луцка
Пользователь №: 22 318

|
Цитата(aaarrr @ Sep 3 2009, 13:37)  Тут только дефайны, где инициализация? Нужно перевести TIOAx в режим Peripheral. Как это можно сделать? Что-то не встречал примеров, или просто не туда смотрю. Цитата Постарайтесь описать проблему так, чтобы можно было понять. Имелось ввиду, что когда возникает прерывание по фронтам, нужно его разрешить Код AT91C_BASE_TC1->TC_IER = AT91C_TC_LDRAS|AT91C_TC_LDRBS; Правильно ли я понял?
--------------------
If the person is successful, he is successful in any sphere.
|
|
|
|
|
Sep 3 2009, 15:12
|
Гуру
     
Группа: Свой
Сообщений: 10 713
Регистрация: 11-12-04
Пользователь №: 1 448

|
Цитата(Zliva @ Sep 3 2009, 19:02)  Как это можно сделать? Что-то не встречал примеров, или просто не туда смотрю. Смотреть надо документацию: 10.4 PIO Controller A Multiplexing 27. Parallel Input/Output Controller (PIO) На все случаи примеров не найдете. Код *AT91C_PIOA_BSR = TIOA_MASK; *AT91C_PIOA_PDR = TIOA_MASK; Цитата(Zliva @ Sep 3 2009, 19:02)  Имелось ввиду, что когда возникает прерывание по фронтам, нужно его разрешить Код AT91C_BASE_TC1->TC_IER = AT91C_TC_LDRAS|AT91C_TC_LDRBS; Правильно ли я понял? Все равно ничего не понял. Прерывание возникает, когда оно уже разрешено.
|
|
|
|
|
Sep 3 2009, 15:51
|
Частый гость
 
Группа: Участник
Сообщений: 137
Регистрация: 14-11-06
Из: Луцка
Пользователь №: 22 318

|
Цитата(aaarrr @ Sep 3 2009, 18:12)  Смотреть надо документацию: 10.4 PIO Controller A Multiplexing 27. Parallel Input/Output Controller (PIO) На все случаи примеров не найдете. Посмотрите пожалуйста полностью все исподники. Может будут какие-то комментарии. Не могу с *AT91C_PIOA_BSR = TIOA_MASK и с *AT91C_PIOA_PDR = TIOA_MASK разобраться. Цитата Все равно ничего не понял. Прерывание возникает, когда оно уже разрешено. Вот что имелось в виду (см. картинку). В момент появления нарастающего фронта Та возникает прерывание по нарастающему фронту (LDRАS = 1), значение заносится в RА и сохраняем его в Var_Та. Когда возникает прерывание (LDRВS = 1) по спадающему фронту в момент Тb значение заносится в RВ и сохраняется Var_Тb. При появление нарастающего фронта Те возникает прерывание по нарастающему фронту снова, и мы сохраняем его в Var_Те. Вот (я так думаю) нужна эта запись AT91C_BASE_TC1->TC_IER = AT91C_TC_LDRAS|AT91C_TC_LDRBS. Но я могу ошибаться. Я вот еще что думаю. Возможнее все-таки переполнение счетчика. Как здесь быть?
--------------------
If the person is successful, he is successful in any sphere.
|
|
|
|
|
Sep 3 2009, 16:12
|
Гуру
     
Группа: Свой
Сообщений: 10 713
Регистрация: 11-12-04
Пользователь №: 1 448

|
Цитата(Zliva @ Sep 3 2009, 19:51)  Посмотрите пожалуйста полностью все исподники. Может будут какие-то комментарии. Не могу с *AT91C_PIOA_BSR = TIOA_MASK и с *AT91C_PIOA_PDR = TIOA_MASK разобраться. Я тоже не могу все досконально проверить и еще пересказать документацию. Просто изучите даташит, ничего сложного в этом не вижу. Цитата(Zliva @ Sep 3 2009, 19:51)  Вот что имелось в виду (см. картинку). В момент появления нарастающего фронта Та возникает прерывание по нарастающему фронту (LDRАS = 1), значение заносится в RА и сохраняем его в Var_Та. Когда возникает прерывание (LDRВS = 1) по спадающему фронту в момент Тb значение заносится в RВ и сохраняется Var_Тb. При появление нарастающего фронта Те возникает прерывание по нарастающему фронту снова, и мы сохраняем его в Var_Те. Вот (я так думаю) нужна эта запись AT91C_BASE_TC1->TC_IER = AT91C_TC_LDRAS|AT91C_TC_LDRBS. Но я могу ошибаться. Я вот еще что думаю. Возможнее все-таки переполнение счетчика. Как здесь быть? Ну да, чтобы получать прерывания по факту загрузки RA и RB их нужно предварительно разрешить. В этом и состоял вопрос? С логикой все немного не так: по каждой загрузке RA смотрим разницу с предыдущим значением и получаем таким образом период ШИМ, по загрузке RB - смотрим разницу RB-RA и получаем длительность импульса. На основании этих двух чисел получаем результат. И переполнение таймера не страшно, если, конечно, его период не выбран меньше периода ШИМ-сигнала.
|
|
|
|
|
Sep 3 2009, 19:18
|
Частый гость
 
Группа: Участник
Сообщений: 137
Регистрация: 14-11-06
Из: Луцка
Пользователь №: 22 318

|
Вот так инициализирую Код #define LED1 (1<<17) #define LED2 (1<<18) #define NB_LED 2 #define LED_MASK (LED1|LED2)
#define SW1_MASK (1<<20) #define SW2_MASK (1<<19) #define SW_MASK (SW1_MASK|SW2_MASK) #define SW1 (1<<20) #define SW2 (1<<19) #define TIOA0 (1<<0) #define TIOA1 (1<<15) #define TIOA0_MASK (1<<0) #define TIOA1_MASK (1<<15) #define TIOA_MASK (TIOA0_MASK|TIOA1_MASK)
#define ENCODER1_A_MASK (1<<26) #define ENCODER1_B_MASK (1<<28) #define ENCODER2_A_MASK (1<<29) #define ENCODER2_B_MASK (1<<30) #define ENCODER_A_MASK (ENCODER1_A_MASK|ENCODER1_B_MASK|ENCODER2_A_MASK|ENCODER2_B_MASK)
#define ENCODER1_A (1<<26) #define ENCODER1_B (1<<28) #define ENCODER2_A (1<<29) #define ENCODER2_B (1<<30) …. /*OUTPUT*/ pPIO->PIO_PER = LED_MASK; pPIO->PIO_OER = LED_MASK; pPIO->PIO_SODR = LED_MASK; /*INPUT*/ pPIO->PIO_ODR = SW_MASK; pPIO->PIO_PER = SW_MASK; pPIO->PIO_IER = ENCODER_A_MASK; /*INPUT peripheral*/ pPIO->PIO_BSR = TIOA_MASK; pPIO->PIO_PDR = TIOA_MASK; Вся периферия работает. Но вот эта ошибка достала. Что делать? --------------------------- PIOA Error --------------------------- You have tried to modify a port pin which is configured as output!
--------------------
If the person is successful, he is successful in any sphere.
|
|
|
|
|
Sep 3 2009, 19:33
|
Частый гость
 
Группа: Участник
Сообщений: 137
Регистрация: 14-11-06
Из: Луцка
Пользователь №: 22 318

|
Цитата(aaarrr @ Sep 3 2009, 22:25)  Плюнуть на сообщения симулятора. Спасибо, так и заделаю. Буду дальше ШИМ душить
--------------------
If the person is successful, he is successful in any sphere.
|
|
|
|
|
Sep 3 2009, 20:06
|
Частый гость
 
Группа: Участник
Сообщений: 137
Регистрация: 14-11-06
Из: Луцка
Пользователь №: 22 318

|
Цитата(aaarrr @ Sep 3 2009, 22:52)  Правильно: вообще не стоит полагаться на симуляцию периферии. Если таймеры настроены идентично, а ругается он только на один, то это явный косяк. Что вы имеете ввиду? И еще, когда пины 27, 28, 29, 30 энкодера настраиваю на вход, в симуляции пин 27 выдает коварное сообщение (которое выше), которое я игнорирую, но когда пины 26, 28, 29, 30 энкодера настраиваю на вход, в симуляции пин 26 работает нормально.
--------------------
If the person is successful, he is successful in any sphere.
|
|
|
|
|
Sep 3 2009, 20:13
|
Гуру
     
Группа: Свой
Сообщений: 10 713
Регистрация: 11-12-04
Пользователь №: 1 448

|
Цитата(Zliva @ Sep 4 2009, 00:06)  Что вы имеете ввиду? Выше упоминалась такая ситуация с TIOAx. Цитата(Zliva @ Sep 4 2009, 00:06)  И еще, когда пины 27, 28, 29, 30 энкодера настраиваю на вход, в симуляции пин 27 выдает коварное сообщение (которое выше), которое я игнорирую, но когда пины 26, 28, 29, 30 энкодера настраиваю на вход, в симуляции пин 26 работает нормально. Угу. Просто надо все смотреть на железе.
|
|
|
|
|
Sep 5 2009, 22:38
|
Частый гость
 
Группа: Участник
Сообщений: 137
Регистрация: 14-11-06
Из: Луцка
Пользователь №: 22 318

|
Настало время USB. Пока доставят акселерометры, не буду тратить время. Вы говорили, что в моем случае класс CDC вполне подойдет и тип передачи данных bulk, так я писал, что нужна гарантия доставки данных. Начитался Агурова. Кругом голова идет. Много информации в книгах, а четко выраженной последовательности нет, или я пока себе её не сформировал. Ну да ладно. Впринципе, со стороны МК проблем не вижу, а вот со стороны ПК нужно потрудится. Может у кого-то есть заготовка для инициализации дескрипторов для МК в случаи использования класса CDC? И еще, не нашол информации. RS-232 дет скорость 115,2кБит/с, в случаи использования CDC, я могу получить скорость 12 МБит/с, или я ошибаюсь? Может когда-то по-играюсь с OTG через MS и с флеш карточкой.
--------------------
If the person is successful, he is successful in any sphere.
|
|
|
|
|
Sep 6 2009, 06:47
|
Частый гость
 
Группа: Участник
Сообщений: 80
Регистрация: 3-07-09
Пользователь №: 50 897

|
Цитата(Zliva @ Sep 6 2009, 01:38)  Может у кого-то есть заготовка для инициализации дескрипторов для МК в случаи использования класса CDC? Код const char devDescriptor[] = { /* Device descriptor */ 0x12, // bLength 0x01, // bDescriptorType 0x10, // bcdUSBL 0x01, // 0x02, // bDeviceClass: CDC class code 0x00, // bDeviceSubclass: CDC class sub code 0x00, // bDeviceProtocol: CDC Device protocol 0x08, // bMaxPacketSize0 0xFF, // idVendorL 0xFF, // 0xFF, // idProductL 0xFF, // 0x10, // bcdDeviceL 0x01, // 0x00, // iManufacturer // 0x01 0x00, // iProduct 0x00, // SerialNumber 0x01 // bNumConfigs };
const char cfgDescriptor[] = { /* ============== CONFIGURATION 1 =========== */ /* Configuration 1 descriptor */ 0x09, // CbLength 0x02, // CbDescriptorType 0x43, // CwTotalLength 2 EP + Control 0x00, 0x02, // CbNumInterfaces 0x01, // CbConfigurationValue 0x00, // CiConfiguration 0xC0, // CbmAttributes 0xA0 0x00, // CMaxPower
/* Communication Class Interface Descriptor Requirement */ 0x09, // bLength 0x04, // bDescriptorType 0x00, // bInterfaceNumber 0x00, // bAlternateSetting 0x01, // bNumEndpoints 0x02, // bInterfaceClass 0x02, // bInterfaceSubclass 0x00, // bInterfaceProtocol 0x00, // iInterface
/* Header Functional Descriptor */ 0x05, // bFunction Length 0x24, // bDescriptor type: CS_INTERFACE 0x00, // bDescriptor subtype: Header Func Desc 0x10, // bcdCDC:1.1 0x01,
/* ACM Functional Descriptor */ 0x04, // bFunctionLength 0x24, // bDescriptor Type: CS_INTERFACE 0x02, // bDescriptor Subtype: ACM Func Desc 0x00, // bmCapabilities
/* Union Functional Descriptor */ 0x05, // bFunctionLength 0x24, // bDescriptorType: CS_INTERFACE 0x06, // bDescriptor Subtype: Union Func Desc 0x00, // bMasterInterface: Communication Class Interface 0x01, // bSlaveInterface0: Data Class Interface
/* Call Management Functional Descriptor */ 0x05, // bFunctionLength 0x24, // bDescriptor Type: CS_INTERFACE 0x01, // bDescriptor Subtype: Call Management Func Desc 0x00, // bmCapabilities: D1 + D0 0x01, // bDataInterface: Data Class Interface 1
/* Endpoint 1 descriptor */ 0x07, // bLength 0x05, // bDescriptorType 0x83, // bEndpointAddress, Endpoint 03 - IN 0x03, // bmAttributes INT 0x0A, // wMaxPacketSize 0x00, 0xFF, // bInterval
/* Data Class Interface Descriptor Requirement */ 0x09, // bLength 0x04, // bDescriptorType 0x01, // bInterfaceNumber 0x00, // bAlternateSetting 0x02, // bNumEndpoints 0x0A, // bInterfaceClass 0x00, // bInterfaceSubclass 0x00, // bInterfaceProtocol 0x00, // iInterface
/* First alternate setting */ /* Endpoint 1 descriptor */ 0x07, // bLength 0x05, // bDescriptorType 0x01, // bEndpointAddress, Endpoint 01 - OUT 0x02, // bmAttributes BULK AT91C_EP_OUT_SIZE, // wMaxPacketSize 0x00, 0x00, // bInterval
/* Endpoint 2 descriptor */ 0x07, // bLength 0x05, // bDescriptorType 0x82, // bEndpointAddress, Endpoint 02 - IN 0x02, // bmAttributes BULK AT91C_EP_IN_SIZE, // wMaxPacketSize 0x00, 0x00 // bInterval };
const char languageIdDescriptor[] = { 0x04, 0x03, 0x09, 0x04 };
const char manufacturerDescriptor[] = {
10, 3, 'F', 0, 'I', 0, 'R', 0, 'M', 0 };
const char serialNumberDescriptor[] = {
10, 3, '1', 0, '2', 0, '3', 0, 'A', 0 };
const char nameDeviseDescriptor[] = {
14, 3, 'D', 0, 'E', 0, 'V', 0, 'I', 0,'C',0,'E',0 };
|
|
|
|
|
Sep 6 2009, 10:05
|
Гуру
     
Группа: Свой
Сообщений: 10 713
Регистрация: 11-12-04
Пользователь №: 1 448

|
Цитата(Zliva @ Sep 6 2009, 02:38)  Впринципе, со стороны МК проблем не вижу, а вот со стороны ПК нужно потрудится. В случае CDC все как раз наоборот. Цитата(Zliva @ Sep 6 2009, 02:38)  И еще, не нашол информации. RS-232 дет скорость 115,2кБит/с, в случаи использования CDC, я могу получить скорость 12 МБит/с, или я ошибаюсь? Тыц
|
|
|
|
|
Sep 7 2009, 19:43
|
Частый гость
 
Группа: Участник
Сообщений: 137
Регистрация: 14-11-06
Из: Луцка
Пользователь №: 22 318

|
Вот здесь скачал реализацию CDC, в IAR-е получил бинарник и залил в кристалл. Работает. В Keil-е не хочет. Вот код.
--------------------
If the person is successful, he is successful in any sphere.
|
|
|
|
2 чел. читают эту тему (гостей: 2, скрытых пользователей: 0)
Пользователей: 0
|
|
|