Ви не увійшли.
К сожалению, в IDE Arduino нет возможности полноценно управлять компилятором и получить ассемблерный листинг полученной программы, для анализа.
На самом деле такая возможность есть, но надо немного повозиться. Вот ЗДЕСЬ я описывал, как это сделать.
/*
********** Pin - D - **********
Arduino 00 – ATmega pin 02/0 –
Arduino 01 – ATmega pin 03/1 –
Arduino 02 – ATmega pin 04/2 – CLK - A энкодера
Arduino 03 – ATmega pin 05/3 – DT - B энкодера
Arduino 04 – ATmega pin 06/4 –
Arduino 05 – ATmega pin 11/5 –
Arduino 06 – ATmega pin 12/6 –
Arduino 07 – ATmega pin 13/7 –
********** Pin - B - **********
Arduino 08 – ATmega pin 14/0 –
Arduino 09 – ATmega pin 15/1 –
Arduino 10 – ATmega pin 16/2 –
Arduino 11 – ATmega pin 17/3 –
Arduino 12 – ATmega pin 18/4 –
Arduino 13 – ATmega pin 19/5 –
Arduino RC – ATmega pin 09/6 – (ZQ)
Arduino RC – ATmega pin 10/7 – (ZQ)
********** Pin - C - **********
Arduino 14_A0 – ATmega pin 23/0 –
Arduino 15_A1 – ATmega pin 24/1 –
Arduino 16_A2 – ATmega pin 25/2 –
Arduino 17_A3 – ATmega pin 26/3 –
Arduino 18_A4 – ATmega pin 27/4 –
Arduino 19_A5 – ATmega pin 28/5 –
****************************************************
****************************************************
Dx_Out; - установка пина Х как выход
Dx_In; - установка пина Х как вход
Dx_High; - установка высокого уровна на пине Х
Dx_Low; - установка низкого уровня на пине Х
Ax_Read; - чтение аналогового пина Х
****************************************************
****************************************************
if ((PIND&(1<<2)) == 0) {} // если на пин *2D* лог 0
if ((PIND&(1<<2)) != 0) {} // если на пин *2D* лог 1PORTD |= (1<<2); // установить на пин *2D* лог 1
PORTD &=~ (1<<2); // установить на пин *2D* лог 0
PORTD ^= (1<<2); // инвертировать состо¤ние пин *2D*
****************************************************
****************************************************
*/unsigned long currentTime;
unsigned long loopTime;
boolean e_B, e_A, spin;void setup() {
Serial.begin(57600);
Serial.println(" KY-040 Encoder Test Interrupt ");
DDRD = B00000000; // назначает выводы со 0 по 7 входными
PORTD = B11111111; // устанавливает на цифровых выводах с 0 по 7 HIGH
DDRB = B111111; // назначает вывод с 8 по 13 выходными
PORTB = B000000; // устанавливает на выводах с 8 по 13 LOW
DDRC = B000011; // назначает выводы с 14 по 15 выходными, с 16 по 19 входными
PORTC = B100000; // устанавливает на выводах с 14 по 18 LOW, с 19 HIGH
// определяем внешнее прерывание на выводе 2
attachInterrupt(0, KY040, FALLING);
}void loop() {
}
void KY040() {
if( millis() < (loopTime + 4) ) { return; }
loopTime = millis();
// считываем состояние выхода А и В энкодера
e_B = PIND&(1<<3); e_A = PIND&(1<<2);// выход В = 1, значит вращение против часовой стрелки
if((e_B && !e_A) && spin) { f01(); Serial.println(" counter-clockwise "); }
if(e_B && !e_A) { spin = true; }
// выход В = 0, значит вращение по часовой стрелке
if((!e_B && !e_A) && !spin) { f02(); Serial.println(" clockwise "); }
if(!e_B && !e_A) { spin = false; }}
void f01() { PORTB |= (1<<5); }
void f02() { PORTB &=~ (1<<5); }KY040 Encoder_203.txt
Открыть с помощьюKY040 Encoder_203.txt. Н
//=====================================================================
if( millis() < (loopTime + 4) ) { return; }
loopTime = millis(); Мне не понятно для чего это и что оно куда возвращает
для чего - автор таким образом пытается бороться с дребезгом контактов...
куда возвращает - по моему все видно куда и что возвращается...
но мне больше этот скетч нравится
/*
********** Pin - D - **********
Arduino 00 – ATmega pin 02/0 –
Arduino 01 – ATmega pin 03/1 –
Arduino 02 – ATmega pin 04/2 – CLK - A энкодера
Arduino 03 – ATmega pin 05/3 – DT - B энкодера
Arduino 04 – ATmega pin 06/4 –
Arduino 05 – ATmega pin 11/5 –
Arduino 06 – ATmega pin 12/6 –
Arduino 07 – ATmega pin 13/7 –
********** Pin - B - **********
Arduino 08 – ATmega pin 14/0 –
Arduino 09 – ATmega pin 15/1 –
Arduino 10 – ATmega pin 16/2 –
Arduino 11 – ATmega pin 17/3 –
Arduino 12 – ATmega pin 18/4 –
Arduino 13 – ATmega pin 19/5 –
Arduino RC – ATmega pin 09/6 – (ZQ)
Arduino RC – ATmega pin 10/7 – (ZQ)
********** Pin - C - **********
Arduino 14_A0 – ATmega pin 23/0 –
Arduino 15_A1 – ATmega pin 24/1 –
Arduino 16_A2 – ATmega pin 25/2 –
Arduino 17_A3 – ATmega pin 26/3 –
Arduino 18_A4 – ATmega pin 27/4 –
Arduino 19_A5 – ATmega pin 28/5 –
****************************************************
****************************************************
Dx_Out; - установка пина Х как выход
Dx_In; - установка пина Х как вход
Dx_High; - установка высокого уровна на пине Х
Dx_Low; - установка низкого уровня на пине Х
Ax_Read; - чтение аналогового пина Х
****************************************************
****************************************************
if ((PIND&(1<<2)) == 0) {} // если на пин *2D* лог 0
if ((PIND&(1<<2)) != 0) {} // если на пин *2D* лог 1PORTD |= (1<<2); // установить на пин *2D* лог 1
PORTD &=~ (1<<2); // установить на пин *2D* лог 0
PORTD ^= (1<<2); // инвертировать состо¤ние пин *2D*
****************************************************
****************************************************
*/unsigned long currentTime;
unsigned long loopTime;
boolean e_B, e_A, spin;void setup() {
Serial.begin(57600);
Serial.println(" KY-040 Encoder Test Interrupt ");
DDRD = B00000000; // назначает выводы со 0 по 7 входными
PORTD = B11111111; // устанавливает на цифровых выводах с 0 по 7 HIGH
DDRB = B111111; // назначает вывод с 8 по 13 выходными
PORTB = B000000; // устанавливает на выводах с 8 по 13 LOW
DDRC = B000011; // назначает выводы с 14 по 15 выходными, с 16 по 19 входными
PORTC = B100000; // устанавливает на выводах с 14 по 18 LOW, с 19 HIGH
// определяем внешнее прерывание на выводе 2
attachInterrupt(0, KY040, FALLING);
}void loop() {
}
void KY040() {
if( millis() < (loopTime + 4) ) { return; }
loopTime = millis();
// считываем состояние выхода А и В энкодера
e_B = PIND&(1<<3); e_A = PIND&(1<<2);// выход В = 1, значит вращение против часовой стрелки
if((e_B && !e_A) && spin) { f01(); Serial.println(" counter-clockwise "); }
if(e_B && !e_A) { spin = true; }
// выход В = 0, значит вращение по часовой стрелке
if((!e_B && !e_A) && !spin) { f02(); Serial.println(" clockwise "); }
if(!e_B && !e_A) { spin = false; }}
void f01() { PORTB |= (1<<5); }
void f02() { PORTB &=~ (1<<5); }KY040 Encoder_203.txt
Открыть с помощью
KY040 Encoder_203.txt. Н
//=====================================================================
if( millis() < (loopTime + 4) ) { return; }
loopTime = millis(); Мне не понятно для чего это и что оно куда возвращает
Для чпу ли мне это? Отчасти да, устройство будет подсчитывать импульсы и крутить двигатель, но это не чпу. Есть такой недостаток при большом разрешении энкодра наблюдается такой эффект, двигатель стоит о импульсы бегут! Дребезжание вала двигатель приводит к ложному подсчету импульсов
Мне нужен код для энкодер с 400 - 1000 импульсов на оборот потянет ли ардуино такой подсчёт
хоть миллион... какая разница ?
код ЕСТЬ в том посте или посту ...
принцип работы энкодера http://forum.arduino.ua/viewtopic.php?id=1070
Мне нужен код для энкодер с 400 - 1000 импульсов на оборот потянет ли ардуино такой подсчёт
Компиляция операторов СИ на ASM происходит по стандартным процедурам а меняется только условие и от них как я понимаю зависит время выполнения, поэтому я и поделил производительность на 4, видимо мало...
Собственно к чему это все, на какую производительность можно рассчитывать скажем при обсчете энкодера на двигателе? или переходить на ASM? Так всё равно придется писать тоже только на ASM, выиграть пару тактов при условии досконального знания ассемблера?
http://forum.arduino.ua/viewtopic.php?id=1135
ВТОРОЕ видео из первого поста...
Компиляция операторов СИ на ASM происходит по стандартным процедурам а меняется только условие и от них как я понимаю зависит время выполнения, поэтому я и поделил производительность на 4, видимо мало...
Собственно к чему это все, на какую производительность можно рассчитывать скажем при обсчете энкодера на двигателе? или переходить на ASM? Так всё равно придется писать тоже только на ASM, выиграть пару тактов при условии досконального знания ассемблера?
Привет всем, хочу обсудить производительность AVR, собственно я столкнулся с таким фактом. Код программного таймера или что-то похожее на это, в моём понимании.
В книге написано, что архитектура AVR позволяет давать производительность 1000000 операций на мегагерц, если частота ардуино 16 мегагерц то должна быть производительность 16000000 операций в секунду. Понятно, что даже в этом коде есть не только обратный счёт но и условия цикла и прочие. Допустим разделим производительность на 4 то получим 4000000 операций в секунду, то есть за секунду должно насчитать до 4000000 делим 65535 и получим 61 раз полное заполнение переменной а поскольку числа меньше то заход в if должен произойти еще чаще. Но в реальность это происходить примерно раз в 0.2 секунды. Возникает мысль толе я что-то не правильно делаю, понимаю или это так и должно быть.
Смотря на библиотеки там и вызов функций из функций и структуры и ссылки, указатели и прочий дремучий лес и все это работает быстро а тут обычный счётчик и такой конфуз
int temp = 0x3800;
while(1)
{
if (temp ==0)
{
какой то код...
temp = 0x3800;
}
temp--;
}