КАК правильно програмировать МИКРОКОНТРОЛЕР????

lalapta100
Offline
Зарегистрирован: 01.01.2014

Вобщем вопрос такой - как лучше написать

 

  for (int i = 0; i < 4; i ++)
  {
    if (i == steps) digitalWrite( s[i], HIGH);
    else digitalWrite( s[i], LOW);
   
  }

Или вот так?? 

switch(steps){ 
   case 0: 
     digitalWrite(s[0], HIGH);  
     digitalWrite(s[1], LOW); 
     digitalWrite(s[2], LOW); 
     digitalWrite(s[3], LOW); 
   break;  
   case 1: 
     digitalWrite(s[0], LOW);  
     digitalWrite(s[1], HIGH); 
     digitalWrite(s[2], LOW); 
     digitalWrite(s[3], LOW); ; 
   break;  
   case 2: 
     digitalWrite(s[0], LOW);  
     digitalWrite(s[1], LOW); 
     digitalWrite(s[2], HIGH); 
     digitalWrite(s[3], LOW); 
   break;  
   case 3: 
     digitalWrite(s[0], LOW);  
     digitalWrite(s[1], LOW); 
     digitalWrite(s[2], LOW); 
     digitalWrite(s[3], HIGH); 
   break;  

 

В первом случае с циклом скрипт занимает меньше места в памяти. Но зато использует как минимум в два раза больше проверок (IF).

ХЗ конечно как там этот код будет выглядеть в конечном виде, но предполагаю что последний вариант(написаный в стиле "Китайского кода" более предпочтительней ибо МК  не ПЦ

Может посоветуете какиенибуть базоыве советы для програмирования МК. 

 

vdk
Offline
Зарегистрирован: 14.04.2013

lalapta100 пишет:

В первом случае с циклом скрипт занимает меньше места в памяти. Но зато использует как минимум в два раза больше проверок (IF).

Один вызов digitalWrite выжрет больше ресурсов, чем какой-то там if

lalapta100 пишет:

ХЗ конечно как там этот код будет выглядеть в конечном виде, но предполагаю что последний вариант(написаный в стиле "Китайского кода" более предпочтительней ибо МК  не ПЦ

(подозрительно) а чем это таким МК кардинально отличается от [микро]процессора?

кстати, этот ваш "китайский код" быстро выжрет и без того небольшую память МК. Это в "больших" компьютерах можно засунуть 16 гигабайт и разбрасываться ими, а в МК память считается килобайтами. Это на 6 порядков меньше!

lalapta100 пишет:

Может посоветуете какиенибуть базоыве советы для програмирования МК. 

Думать и оптимизировать

И, правильным будет третий вариант

Клапауций
Offline
Зарегистрирован: 10.02.2013

Заяц ПЦ!

*нет, что бы протестировать то и другое...

lalapta100
Offline
Зарегистрирован: 01.01.2014

vdk пишет:

И, правильным будет третий вариант

 

Если не секре что это за вариант ???

 

Да я походу просто не дооцениваю ардуино (я все время пытаюсь не загружать ее лишними вычислениями)

Тогда еще один вопрос. Как ардуино относится к дробным числам???Что лучше использовать для вычислений цисел с тысячными частями???  float или int умноженный на 1000 и потом полученый результат уже делить обратно на 1000??? или это тоже не существено??

vdk
Offline
Зарегистрирован: 14.04.2013

lalapta100 пишет:

Если не секре что это за вариант ???

Типа так:

digitalWrite(s[current], LOW); // current - текущий активный
digitalWrite(s[new], HIGH); // current - новый активный
current=new;

lalapta100 пишет:

Тогда еще один вопрос. Как ардуино относится к дробным числам???Что лучше использовать для вычислений цисел с тысячными частями???  float или int умноженный на 1000 и потом полученый результат уже делить обратно на 1000??? или это тоже не существено??

С int будет быстрее

lalapta100
Offline
Зарегистрирован: 01.01.2014

vdk пишет:

Типа так:



digitalWrite(s[current], LOW); // current - текущий активный
digitalWrite(s[new], HIGH); // current - новый активный
current=new;

[/quote]

правильно лия понял New увеличивает индекс на 1??? Но по отношению к чему? Получается что массив хранит в себе индекс  "последнего активного" элемента ??????

 

 

vdk
Offline
Зарегистрирован: 14.04.2013

lalapta100 пишет:

правильно лия понял New увеличивает индекс на 1???

неа, это придется делать вручную

кстати, надо переобозвать переменную в new_current, а то совсем забыл, что new зарезервированное слово

lalapta100 пишет:

Но по отношению к чему? Получается что массив хранит в себе индекс  "последнего активного" элемента ??????

нет, массив - отдельно, а индекс к нему - отдельно

lalapta100
Offline
Зарегистрирован: 01.01.2014

 

vdk пишет:

digitalWrite(s[current], LOW); // current - текущий активный
digitalWrite(s[new_current], HIGH); // current - новый активный
current=new_current;

 

Ясно, да кстати действительно третий вариант правильнвй.  Это я насмотрелся на хрено написаные библтотеки управления шагового двигателя =)   переписывать нада только 2 пина а не все 4 =)))

СПАСИБО

ites
Offline
Зарегистрирован: 26.12.2013

lalapta100 пишет:

 

vdk пишет:

digitalWrite(s[current], LOW); // current - текущий активный
digitalWrite(s[new_current], HIGH); // current - новый активный
current=new_current;

 

Ясно, да кстати действительно третий вариант правильнвй.  Это я насмотрелся на хрено написаные библтотеки управления шагового двигателя =)   переписывать нада только 2 пина а не все 4 =)))

СПАСИБО

На самом деле, всегда "возможны варианты". Общая идея "как праильно" понимается, когда смотришь на ассемблерный выход компилятора и соотносишь, почему компилятор сделал так или этак. Например, очень вредно писать тип int в цикле от 0 до 3, этот индекс прекрасно влазит в один байт. Компилятор в случае int, согласно желанию программиста, использует один лишний регистр или байт памяти, больше инструкций для инкремента и проверки -- больше размер программы и ниже эффективность, при этом нет никакого оправдания программисту почему. На счёт "возможны варианты" в данном примере: например, все пины сидят на одном порту. Можно в одну запись значения в порт устоновить что должно светиться, а что потухнуть, вместо 2-4 вызовов digitalWrite.

lalapta100
Offline
Зарегистрирован: 01.01.2014

ites пишет:

 На счёт "возможны варианты" в данном примере: например, все пины сидят на одном порту. Можно в одну запись значения в порт устоновить что должно светиться, а что потухнуть, вместо 2-4 вызовов digitalWrite.

Прикольно!! Не знал об этом, теперь буду юзать постояно !!! а если нужно поменять один пин? Что тогда предпочтительней Порт или digitalWrite ?

Еще чтонибуть интересное кнонибуть знает?? Я новечек буду рад любому совету

ites
Offline
Зарегистрирован: 26.12.2013

lalapta100 пишет:

ites пишет:

 На счёт "возможны варианты" в данном примере: например, все пины сидят на одном порту. Можно в одну запись значения в порт устоновить что должно светиться, а что потухнуть, вместо 2-4 вызовов digitalWrite.

Прикольно!! Не знал об этом, теперь буду юзать постояно !!! а если нужно поменять один пин? Что тогда предпочтительней Порт или digitalWrite ?

Еще чтонибуть интересное кнонибуть знает?? Я новечек буду рад любому совету

Даже всего один пин лучше самописной функцией. Тут на форуме миллион раз уже такое мелькало. Вот мой вариант, например: https://github.com/jabbervorx/arduino-any-pc-pwm/blob/master/include/digitalPortsFast.h

vdk
Offline
Зарегистрирован: 14.04.2013

lalapta100 пишет:

Прикольно!! Не знал об этом, теперь буду юзать постояно !!! а если нужно поменять один пин? Что тогда предпочтительней Порт или digitalWrite ?

Еще чтонибуть интересное кнонибуть знает?? Я новечек буду рад любому совету

На этапе освоения ардуины лучше не заморачивать себе голову и пользовать digitalWrite.

А к более сложным вещам переходить уже потом, по мере надобности

lalapta100
Offline
Зарегистрирован: 01.01.2014

ites пишет:

Даже всего один пин лучше самописной функцией. Тут на форуме миллион раз уже такое мелькало. Вот мой вариант, например: https://github.com/jabbervorx/arduino-any-pc-pwm/blob/master/include/digitalPortsFast.h

 

Если вас не затруднит то объясните нубу =))



#define _digitalWriteFast(P, V) \
        do {\
                if((P) < 8)\
                        portWrite((V) << (P),_BV(P), PORTD);\
                else if((P) < 14)\
                        portWrite((V) << ((P)-8),_BV((P)-8), PORTB);\
                else\
                        portWrite((V) << ((P)-14),_BV((P)-14), PORTC);\
        } while(0)

откуда взялось _BV((P) ??? я поползал по инклудам даже в iom328.h нигде не нашол определения этой функции =(  что она делает???

а  я с "С" недружу немогу понять что это значит  (V) << (P). по отдельности понятно "byte Р"-это номер пина в порте. "byte V" - это значение  которое поставим .  Но что это значит непонятно

Или это некие ссылки?? потомучто этот кусок тоже загадочен для меня

 



static inline byte digitalReadFast(byte pin) {
        byte ret;
        _digitalReadFast(pin, ret);
        return ret;
}



переменную ret передали в _digitalReadFas() передали как ссылку????  

и что означают "\" в конце строки ???

Конечно извеняюсь за подобные вопросы, но очень интересно.

 

lalapta100
Offline
Зарегистрирован: 01.01.2014

vdk пишет:

На этапе освоения ардуины лучше не заморачивать себе голову и пользовать digitalWrite.

А к более сложным вещам переходить уже потом, по мере надобности

По мне чем раньше начнеш - тем быстрее освоиш =))

 

lalapta100
Offline
Зарегистрирован: 01.01.2014

ites пишет:

Раз пошол такой код, решил сразу спросить.

Возможно ли сделать так чтобы ардуина во время работы считывала информацию из SD card и на ее основе дописывала или переписывала часть своего кода (те 32 kb ). точнее только часть.

допустим  чтобы ардуина при нажатии кнопки догружала некий код ,соответсвующий этой кнопке а при нажатии другой кнопки стерала этот код и загружала другой.

Чтобы както расширить эти 32кб за счет SD карты???  Возможно ли такое замутить простому смертному???

step962
Offline
Зарегистрирован: 23.05.2011

lalapta100 пишет:

откуда взялось _BV((P) ??? я поползал по инклудам даже в iom328.h нигде не нашол определения этой функции =(  что она делает???

Из каталога hardware\tools\avr\avr\include\avr, файл sfr_defs.h

Подготавливает маску для включения/выключения отдельного бита в байте:
#define cbi(sfr, bit) (_SFR_BYTE(sfr) &= ~_BV(bit))
#define sbi(sfr, bit) (_SFR_BYTE(sfr) |= _BV(bit))

lalapta100 пишет:

а  я с "С" недружу немогу понять что это значит  (V) << (P). по отдельности понятно "byte Р"-это номер пина в порте. "byte V" - это значение  которое поставим .  Но что это значит непонятно

Если не дружите (и не собираетесь дружить) с C, то лучше оставаться в рамках digitalWrite...

Смещение маски, заданной в V (обычно просто единичка) на P позиций влево.

step962
Offline
Зарегистрирован: 23.05.2011

lalapta100 пишет:

Возможно ли [...]

Возможно, если разместите этот управляющий код в области, отводимой под загрузчик. То есть, если напишете собственный загрузчик. И если удастся впихнуть всю логику в  2048 слова (=4096 байт - ATMega328P) - глава 26 даташита вам в помощь.

ites
Offline
Зарегистрирован: 26.12.2013

lalapta100 пишет:

ites пишет:

Даже всего один пин лучше самописной функцией. Тут на форуме миллион раз уже такое мелькало. Вот мой вариант, например: https://github.com/jabbervorx/arduino-any-pc-pwm/blob/master/include/digitalPortsFast.h

 

Если вас не затруднит то объясните нубу =))


#define _digitalWriteFast(P, V) \
        do {\
                if((P) < 8)\
                        portWrite((V) << (P),_BV(P), PORTD);\
                else if((P) < 14)\
                        portWrite((V) << ((P)-8),_BV((P)-8), PORTB);\
                else\
                        portWrite((V) << ((P)-14),_BV((P)-14), PORTC);\
        } while(0)

откуда взялось _BV((P) ??? я поползал по инклудам даже в iom328.h нигде не нашол определения этой функции =(  что она делает???

#define _BV(bit) (1 << (bit))

из файла подключаемого файла <avr/sfr_defs.h> который подключается в одном из <avr/ioXXXX.h> -- соответственно модели, которые подключаются в <avr/io.h>

lalapta100 пишет:
а  я с "С" недружу немогу понять что это значит  (V) << (P). по отдельности понятно "byte Р"-это номер пина в порте. "byte V" - это значение  которое поставим .  Но что это значит непонятно

В любой книжке по Си найди раздел "битовые операции", чтобы понять как работают << и >> с битами. В С++ этот момент может затуманить мозг, когда они битовые операции переопределили для работы с потоками. byte -- это целочисленный беззнаковый тип, который помещается в одном байте.

lalapta100 пишет:
Или это некие ссылки?? потомучто этот кусок тоже загадочен для меня

 


static inline byte digitalReadFast(byte pin) {
        byte ret;
        _digitalReadFast(pin, ret);
        return ret;
}


переменную ret передали в _digitalReadFas() передали как ссылку????  

и что означают "\" в конце строки ???

Конечно извеняюсь за подобные вопросы, но очень интересно.

 

Никуда ничего не передали, _digitalWriteFast -- это макрос препроцессора, который по шаблону подставляет текст, который затем будет компилироваться. Символы "\", за которыми идёт сразу перевод строки, означают, что следующая строка будет приклеена к текущей перед компилированием. В данном случае, это способ сделать макрос многострочным, чтобы выглядел красивее.

ites
Offline
Зарегистрирован: 26.12.2013

lalapta100 пишет:

Чтобы както расширить эти 32кб за счет SD карты???  Возможно ли такое замутить простому смертному???

Разумнее вписаться в 32кб или использовать другой контроллер, где памяти побольше.

lalapta100
Offline
Зарегистрирован: 01.01.2014

ites пишет:

lalapta100 пишет:

Чтобы както расширить эти 32кб за счет SD карты???  Возможно ли такое замутить простому смертному???

Разумнее вписаться в 32кб или использовать другой контроллер, где памяти побольше.

 

 

Да но если в некий агригат на основе ардуино нужно запихнуть 10-20 разных макросов. былобы удобей нажать кнопку что бы он подгрузил нужный код и выполнил а не подключатся к компу каждый раз. 

Но походу вы правы. Проще и разумнее всетаки юзать как оно есть чем читать 3 килограмовый талмуд =)))

Хотя когданибуть я всетаки доберусь и до этого?

lalapta100
Offline
Зарегистрирован: 01.01.2014

ites пишет:

lalapta100 пишет:




static inline byte digitalReadFast(byte pin) {
        byte ret;
        _digitalReadFast(pin, ret);
        return ret;
}




переменную ret передали в _digitalReadFas() передали как ссылку????  

и что означают "\" в конце строки ???

Конечно извеняюсь за подобные вопросы, но очень интересно.

 

Никуда ничего не передали, _digitalWriteFast -- это макрос препроцессора, который по шаблону подставляет текст, который затем будет компилироваться. Символы "\", за которыми идёт сразу перевод строки, означают, что следующая строка будет приклеена к текущей перед компилированием. В данном случае, это способ сделать макрос многострочным, чтобы выглядел красивее.

тогда как переменная "ret" возвращает значениt считанное из пина? Хотя вобщем не важно .  главное что возвращает =))