Скорая Компьютерная Помощь г. Калуга

Полный спектр компьютерных услуг!

Здравствуйте, гость ( Вход | Регистрация )

> Внимание!

  • Вся информация, расположенная в данном и других разделах форума получена из открытых источников (интернет-ресурсы, средства массовой информации, печатные издания и т.п.) и/или добавлена самими пользователями. Администрация форума предоставляет его участникам площадку для общения / размещения файлов / статей и т.п. и не несет ответственности за содержание сообщений, а также за возможное нарушение авторских, смежных и каких-либо иных прав, которое может повлечь за собой информация, содержащаяся в сообщениях.
Ремонт компьютеров в калуге Рекламное место сдается
 
Ответить в эту темуОткрыть новую тему
> [Из песочницы] Ускоряем свою Arduino
Decker
сообщение 5.4.2012, 12:32
Сообщение #1


Администратор
*****

Группа: Главные администраторы
Сообщений: 14349
Регистрация: 12.10.2007
Из: Twilight Zone
Пользователь №: 1





Программинг микроконтроллеров*,

Arduino

Месяца 3 назад, как и многие горе-электроники, купил себе на мой тогдашний взгляд самую навороченную микропроцессорную плату из семейства Arduino, а именно Seeeduino Mega, на базе процессора Atmega1280. Побаловавшись всласть вращающимся сервоприводом и моргающим светодиодом, встал вопрос: «зачем же я её купил?».



Я работаю одним из ведущих конструкторов на одном крупном военном Зеленоградском заводе, и в данный момент веду проект по разработке метрологического средства измерения. В данной задаче существует бесконечное множество проблем, которые требуют индивидуального решения. Одной из таких задач является управление шаговым двигателем без шумов и с шагом не 1.8 градуса, как сказано в документации шагового двигателя, а до 0.0001 градуса. Казалось бы, задача сложна и нерешабельна, но, повозившись немного со схемами управления, пришёл к выводу, что всё реально и возможно. Требуется только генерация двух сигналов специфичной формы и со сдвигом фаз и частотой изменения напряжения до 1 МГц. (Подробное исследование шагового мотора и раскрытие всех тайн управления напишу в следующей статье) Сразу же в голове стали появляться проблески надежды, что я не зря потратил 1500 рублей на свою красненькую Seeeduino, и я, набравшись энтузиазма, начал разбираться.




Первоначальный ужас:


Подключив микропроцессорную плату к осцилографу, и написав цикл digitalWrite(HIGH), и ниже digitalWrite(LOW), на осцилографе обнаружил довольно унылый меандр с частотой 50Гц. Это кошмар. Это крах, подумал я, на фоне требуемых 1Мгц.

Далее, через осцилограф, я изучил еще несколько скоростей выполнения:

AnalogRead() — скорость выполнения 110 мкс.

AnalogWrite() — 2000 мкс

SerialPrintLn() — при скорости 9600 около 250мкс, а при максимальной скорости около 3мкс.

DigitalWrite() — 1800мкс

DigitalRead() — 1900мкс



На этом я, всплакнув, чуть не выкинул свою Seeeduino. Но не тут-то было!




Глаза боятся, руки делают!


Не буду рассказывать свои душевные муки и описывать три долгих дня изучения, лучше сразу скажу всё как есть!

Подняв всю возможную документацию на Arduino и на процессор Atmega1280, исследовав опыт зарубежных коллег, хочу предложить несколько советов, как заменять чтение/запись:




Улучшаем AnalogRead()


#define FASTADC 1



// defines for setting and clearing register bits

#ifndef cbi

#define cbi(sfr, bit) (_SFR_BYTE(sfr) &= ~_BV(bit))

#endif

#ifndef sbi

#define sbi(sfr, bit) (_SFR_BYTE(sfr) |= _BV(bit))

#endif



void setup() {

int start ;

int i ;



#if FASTADC

// set prescale to 16

sbi(ADCSRA,ADPS2) ;

cbi(ADCSRA,ADPS1) ;

cbi(ADCSRA,ADPS0) ;

#endif



Serial.begin(9600) ;

Serial.print("ADCTEST: ") ;

start = millis() ;

for (i = 0 ; i < 30000 ; i++)

analogRead(0) ;

Serial.print(millis() - start) ;

Serial.println(" msec (30000 calls)") ;

}



void loop() {

}





Результат: скорость 18,2 мкс против бывших 110 мкс.

Кстати, максимальная скорость АЦП Атмеги как раз 16мкс. Как вариант — использовать другую микросхему, заточенную именно под АЦП, которая позволит уменьшить скорость до 0,2мкс (читать ниже, почему)




Улучшаем digitalWrite()


Каждая Arduino/Seeeduino/Feduino/Orduino/прочаяduino имеет порты. Каждый порт — 8 бит, которые сначала надо настроить на запись. Например, на моей Seeeduino PORTA — c 22 по 30 ножку. Теперь всё просто. Управляем с 22 по 30 ножки с помощью функций

PORTA=B00001010 (битовая, ножки 23 и 25 — HIGH)

или

PORTA=10 (десятичная, всё так же)

Результат = 0,2мкс против 1800мкс, которые достигаются обычным digitalWrite()




Улучшаем digitalRead()


Практически то же самое, что и в улучшении с digitalWrite(), но теперь настраиваем ножки на INPUT, и используем, например:

if (PINA==B00000010) {...} (если на ножке 23 присутствует HIGH, а на 22 и 24-30 присутствует LOW)

Результат выполнения этого if() — 0.2мкс против 1900мкс, которые достигаются обычным digitalRead()




Улучшаем ШИМ модулятор, или analogWrite()


Итак, есть данные, что digitalRead() исполняется 0,2мкс, и ШИМ модулятор имеет дискретность 8 разрядов, минимальное время переключения ШИМ 51,2мкс против 2000 мкс.

Используем следующий код:

int PWM_time=32; //Число, которое мы как бы хотим записать в analogWrite(PIN, 32)

for (int k=0;k<PWM_time) PORTA=B00000001;

for (int k=0;k<256-PWM_time) PORTA=B00000000;



Вот и получили ШИМ с частотой 19кГц против 50Гц.




Подведём итоги


digitalWrite() было 1800мкс, стало 0,2мкс

digitalRead() было 1900мкс, стало 0,2мкс

analogWrite() было 2000мкс, стало 51,2мкс

analogRead() было 110мкс, стало 18,2мкс, а можно до 0,2мкс


Original source: habrahabr.ru (comments, light).

Читать дальше


--------------------

Вернуться в начало страницы
 
+Ответить с цитированием данного сообщения

Ответить в эту темуОткрыть новую тему
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 

Рекламное место сдается Рекламное место сдается
Текстовая версия Сейчас: 20.1.2022, 12:49
Рейтинг@Mail.ru
Яндекс.Метрика Яндекс цитирования