Ассемблер и среда разработки Arduino

alexxkr
Offline
Зарегистрирован: 30.12.2012

Господа, возник такой ламерский вопрос. можно ли в скетч вставлять куски ассемблерного кода? к примеру, если есть желание поковыряться с АЦП или еще каким узлом контроллера. если возможноть работы с регистрами напрямую есть в скетчах, то где покурить подробный мануал?

maksim
Offline
Зарегистрирован: 12.02.2012

alexxkr пишет:

если возможноть работы с регистрами напрямую есть в скетчах, то где покурить подробный мануал?

http://www.atmel.com/Images/doc8161.pdf

alexxkr
Offline
Зарегистрирован: 30.12.2012

спасибо, даташитом на мою мегу 1280 владею, и кое-какой опыт работы в avr studio тоже есть. Вопрос заключается в том, можно ли в теле С/С++ скетча вставлять куски ассемблерного кода? собсно, мануал нужен на более подробное описание языка ардуино, так как список функций, представленный на сайте неполон. к примеру, обратные тригонометрические функции здесь не описаны.

carduino.ru
Offline
Зарегистрирован: 06.12.2011

Можно

01void setup() 
02{
03pinMode(13, OUTPUT);
04pinMode(12, INPUT);
05Serial.begin(115200); 
06
07void loop() 
08
09unsigned char reg=26;
10cli();
11asm volatile(  "push %0 \n"
12                
13"label_1%=:  \n"
14              "COM %0  \n"
15              "out %1, %0   \n"
16"rjmp label_1%=  \n"
17              
18              "pop %0   \n"
19            : "=&r" (reg)
20            : "I" (_SFR_IO_ADDR(PORTB))  ) ;
21sei();
22}

 

alexxkr
Offline
Зарегистрирован: 30.12.2012

спасибо, надо попробовать

poskotinov_av
Offline
Зарегистрирован: 20.12.2014

а как ассемблеру передать ссылку на массив?

selevo
selevo аватар
Offline
Зарегистрирован: 21.12.2013

писать можно на чистом асме без всяких извращений с кавычками и подчёркиваниями,просто код..

http://robocraft.ru/blog/981.html

Logik
Offline
Зарегистрирован: 05.08.2014

ответ не заставил себя ждать многим более 2-х лет )))

ua6em
ua6em аватар
Offline
Зарегистрирован: 17.08.2016

Logik пишет:

ответ не заставил себя ждать многим более 2-х лет )))

Медаль нашла своего героя )))
 

uldin@mail.ru
Offline
Зарегистрирован: 15.02.2012

Помогите сделать ассемблерную вставку: определить блок 512байт, затем на ассемблере байт АЦП в 1ю и так 512 раз, выскочить. Можно так? Это для пультоскопа.

DetSimen
DetSimen аватар
Offline
Зарегистрирован: 25.01.2017

Курсовики тут не делают.

mykaida
mykaida аватар
Offline
Зарегистрирован: 12.07.2018

uldin@mail.ru пишет:

Помогите сделать ассемблерную вставку: определить блок 512байт, затем на ассемблере байт АЦП в 1ю и так 512 раз, выскочить. Можно так? Это для пультоскопа.

Можно, я разрешаю.

uldin@mail.ru
Offline
Зарегистрирован: 15.02.2012

значит сделаешь!

wdrakula
wdrakula аватар
Offline
Зарегистрирован: 15.03.2016

uldin@mail.ru пишет:

значит сделаешь!

Странная логика. Он разрешает.

Вот ты у учителя спрашиваешь: "Можно выйти?", и он разрешает. Ты думаешь, что курить в сортире он тоже сам будет или ты? ;))

yuhenotix@2p-ma...
Offline
Зарегистрирован: 09.06.2019

Как вариант... Напиши это на ардуино, посмотри  код ассемблера и отдай преподу . Google подскажет как  посмотреть  листинг  кода ардуиновского в  асме.

 

uldin@mail.ru
Offline
Зарегистрирован: 15.02.2012

нету препода

uldin@mail.ru
Offline
Зарегистрирован: 15.02.2012

Нету препода...

uldin@mail.ru
Offline
Зарегистрирован: 15.02.2012

Могли бы деду и помочь, а не хихикать...

Komandir
Komandir аватар
Offline
Зарегистрирован: 18.08.2018

Вставка на ассемблере для родного АЦП не даёт преимущества ...

yuhenotix@2p-ma...
Offline
Зарегистрирован: 09.06.2019

Как без боли писать на ассемблере в arduino IDE

http://robocraft.ru/blog/981.html

https://embedderslife.wordpress.com/2012/02/19/avr-gcc-asm-and-c/

Нисмотря на то что автор  по первой ссылке  в названии написал какую-то дичь, статья именно  про лучший способ  писать на ассемблере в этой среде. Смысл в том  что надо создать отдельный файл и писать в нем и затем  вызывать   по мере  надобности.

 

DetSimen
DetSimen аватар
Offline
Зарегистрирован: 25.01.2017

uldin@mail.ru пишет:

Могли бы деду и помочь, а не хихикать...

Если ты знаешь ассемблер AVR, то вот, пользуйся без головняков 

http://arduino.ru/forum/otvlechennye-temy/znaete-li-vy-shto-assembler-arduino-ide

 

dimax
dimax аватар
Offline
Зарегистрирован: 25.12.2013

uldin@mail.ru пишет:

Помогите сделать ассемблерную вставку: определить блок 512байт, затем на ассемблере байт АЦП в 1ю и так 512 раз, выскочить. Можно так? Это для пультоскопа.

Для ускорения пультоскопа нужно менять МК на  32-битный :). Ассемблер иногда конечно нужен, но не в данном случае. Смотрим:

Опрос АЦП из скетча пультоскопа на СИ:

1ADMUX = (1<<REFS0)|(1<<ADLAR);// channel adc0
2ADCSRB=0;
3ADCSRA =  (1<<ADEN)|(1<<ADSC)|(1<<ADATE) |(1<<ADPS1);
4       for (int i = 0; i < BUFSIZE; i++) { //for..
5        while (!(ADCSRA & ADIF)); //wait adif flag  
6        ADCSRA |= 0x10;  //clear adif          
7        adcBuf[i] = ADCH; //load to buff         
8        }

 

Дизассемблируем этот код с помощью avr-objdump, справа мои комментарии

01ldi r24, 0x60      ;  r24 = (1<<REFS0)|(1<<ADLAR);                  
02sts 0x007C, r24    ;   ADMUX=r24                                     
03sts 0x007B, r1     ;   ADCSRB=0                                      
04ldi r24, 0xE2      ; r24=(1<<ADEN)|(1<<ADSC)|(1<<ADATE) |(1<<ADPS1);
05sts 0x007A, r24    ;   ADCSRA=r24                                    
06ldi r24, 0x00      ; r25+r24=512                                    
07ldi r25, 0x02      ; r25+r24=512                                    
08lds r18, 0x007A    ;  r18= ADCSRA                                    
09sbrs    r18, 2         ; в цикл если ADIF не установлен                 
10rjmp    .-8            ; в цикл если ADIF не установлен                 
11lds r18, 0x007A    ;   r18=ADCSRA                                     
12ori r18, 0x10      ; r18 OR ADIF                                    
13sts 0x007A, r18    ;     ADCSRA =r18                                   
14lds r18, 0x0079    ;  r18=ADCH                                        
15sbiw      r24, 0x01    ; цикл for 512--                                      
16brne    .-26           ; в большой цикл если не 0                               
17ldi r25, 0x00      ; иначе обнулить адресный регистр                
18ldi r24, 0x00      ; иначе обнулить адресный регистр                
19ret                                                                      

Получаем ассемблерный код практически без излишеств. Т.е. если переписать тот фрагмент на голом ассемблере то выигрыша не будет совсем.

uldin@mail.ru
Offline
Зарегистрирован: 15.02.2012

А если 512 раз написать: читать АЦП, писать в ячейку буфера, модифицировать адрес - так моно? Интересно, ск тактов надо АЦП для преобразования?

 

Komandir
Komandir аватар
Offline
Зарегистрирован: 18.08.2018

АЦП медленный (даже на самой высокой скорости) и нет разницы на каком языке писать программу !

dimax
dimax аватар
Offline
Зарегистрирован: 25.12.2013

uldin@mail.ru, как уже сказал командир - слабое звено тут АЦП, а не алгоритм. Пока АЦП тужится что-б выдать свой очередной семпл -МК за это время успевает отстрочить полсотни тактов. Алгоритм любой медлительности успеет положить взятый ранее байт в буфер,  вернуться, и крутиться дальше в цикле ожидая флага готовности. Так что если хочется быстрее - вперёд осваивать ARM  :)

uldin@mail.ru
Offline
Зарегистрирован: 15.02.2012

да уж...

uldin@mail.ru
Offline
Зарегистрирован: 15.02.2012

uldin@mail.ru
Offline
Зарегистрирован: 15.02.2012

Внук помог - написал расчет в массив и загрузка на комп. Осталось быстро-быстро заполнить массив из АЦП в 8266, передать по WiFi на Андроид и получить пультоскоп))

Komandir
Komandir аватар
Offline
Зарегистрирован: 18.08.2018
sadman41
Offline
Зарегистрирован: 19.10.2016

float привести к int, а потом запихать во write()? За какой ассемблер тут речь вообще?

mykaida
mykaida аватар
Offline
Зарегистрирован: 12.07.2018

Подпрограмма AddMeasuring() не нужна, Короче и проще

yuhenotix@2p-ma...
Offline
Зарегистрирован: 09.06.2019

а кто проверит, поддерживает ли компилятор,  RAW  формат ввода ?

01asm(R"(
02дальше какой-то код...
03TIMER1_COMPA:
04    CLI
05    OUT     TCNT1H, Temp0
06    OUT     TCNT1L, Temp0
07    CPI     Temp3, 255
08    BREQ    LeftToRight
09    CPI     Temp3, 0
10    BREQ    RightToLeft
11    RJMP    Timer1Out
12LeftToRight:
13    LSR     Temp2
14    CPI     Temp2, 0b00000001             
15    BREQ    ChangeDirection    
16    RJMP    Timer1Out      
17RightToLeft:
18    LSL     Temp2
19    CPI     Temp2, 0b10000000          
20    BREQ    ChangeDirection    
21    RJMP    Timer1Out
22)");

 

с11  уже включена  была такая возможность.

mykaida
mykaida аватар
Offline
Зарегистрирован: 12.07.2018

yuhenotix@2p-mail.com пишет:

а кто проверит, поддерживает ли компилятор,  RAW  формат ввода ?

А сам? Если компилятор не заругался- значит поддерживает.

yuhenotix@2p-ma...
Offline
Зарегистрирован: 09.06.2019

 у меня  небыло  возможности

yuhenotix@2p-ma...
Offline
Зарегистрирован: 09.06.2019

Проверил, работает.

 

01void loop() {
02  digitalWrite(LED_BUILTIN, HIGH);   // turn the LED on (HIGH is the voltage level)
03  delay(100);                       // wait for a second
04  digitalWrite(LED_BUILTIN, LOW);    // turn the LED off by making the voltage LOW
05  delay(100);
06  
07asm(R"(
08ldi r16,0x03
09out 0x05,r16
10out 0x04,r17
11)");

 но имена портов не понимает PORTB PINB и т.д. . Такие   конструкции: ldi r17,(1<<DDB3)|(1<<DDB2)|(1<<DDB1)|(1<<DDB0) - тоже не понимает возможно еще потому  что формат  assembler'a стоит по умолчанию AT&T а не  intel. Надо  как-то  ключ компилятору отправить и попробовать.

 

Но это уже    лучше чем  через запятую все писать. Однако отдельным файлом еще лучше подключать.

Komandir
Komandir аватар
Offline
Зарегистрирован: 18.08.2018

yuhenotix@2p-mail.com пишет:

Но это уже    лучше чем  через запятую все писать.

Это о чем Вы ?

Чем это лучше, чем:

asm volatile(

 "ldi r16,0x03 \n\t"

 "out 0x05,r16 \n\t"

 "out 0x04,r17 \n\t"

)

yuhenotix@2p-ma...
Offline
Зарегистрирован: 09.06.2019

Komandir пишет:

Это о чем Вы ?

Чем это лучше, чем:

asm volatile(

 "ldi r16,0x03 \n\t"

 "out 0x05,r16 \n\t"

 "out 0x04,r17 \n\t"

)

Ты дурак или прикидываешся ? По-моему даже  дарак видит разницу,а ты не увидел...

Между  твоим венегретом с какой-то левой х-той 

asm

volatile(

 "ldi r16,0x03 \n\t"

 "out 0x05,r16 \n\t"

 "ldi r16,0x03 \n\t"

)

и предложенным RAW форматом, безо всякой твоей  х.еты с лишними символами в коде в каждой строчке.

 asm(R"(
ldi r16,0x03
out 0x05,r16
ldi r16,0x03
)");
Komandir
Komandir аватар
Offline
Зарегистрирован: 18.08.2018

Дурака вы каждое утро видите в зеркале !!!

yuhenotix@2p-ma...
Offline
Зарегистрирован: 09.06.2019

Значит хуже дурака...

Komandir
Komandir аватар
Offline
Зарегистрирован: 18.08.2018

Только дураки не знают как пользоваться именами портов и пинов !

difine сделаны только для того что бы быстро переназначить порты/выводы

\n\t вставляются только для того, что бы в листинге было красиво.

01#define SCL0PORT PORTB
02#define SCL0PIN PORTB1
03#define SDA0PORT PORTB
04#define SDA0PIN PORTB2
05#define SCL1PORT PORTB
06#define SCL1PIN PORTB3
07#define SDA1PORT PORTB
08#define SDA1PIN PORTB4
09void __attribute__ ((noinline)) i2c_init(uint8_t device=0) {
10  asm volatile(
11    "TST %8\n\t"
12    "BRNE i2c_init_1\n\t"
13    "CBI %0-1,%1\n\t"
14    "CBI %2-1,%3\n\t"
15    "CBI %2,%3\n\t"
16    "CBI %0,%1\n\t"
17    "RJMP i2c_init_2\n\t"
18    "i2c_init_1:\n\t"
19    "CBI %4-1,%5\n\t"
20    "CBI %6-1,%7\n\t"
21    "CBI %6,%7\n\t"
22    "CBI %4,%5\n\t"
23    "NOP\n\t"
24    "i2c_init_2:\n\t"
25    ::"I" (_SFR_IO_ADDR(SCL0PORT)), "I" (SCL0PIN), "I" (_SFR_IO_ADDR(SDA0PORT)), "I" (SDA0PIN),
26      "I" (_SFR_IO_ADDR(SCL1PORT)), "I" (SCL1PIN), "I" (_SFR_IO_ADDR(SDA1PORT)), "I" (SDA1PIN),
27      "r" (device)
28  );
29}

 

nik182
Offline
Зарегистрирован: 04.05.2015

Круто! Вот только ардуины не вижу в последнем сообщении. Может быть можно хоть один ардуиновский оператор вставить? А то как то совсем не по теме форума получается.  В отвлечённые темы больше просится.

Komandir
Komandir аватар
Offline
Зарегистрирован: 18.08.2018

Могу весь скетч вставить, если интересно ... (Пишем в два i2c девайса на любых пинах под камень 16Мгц с полностью выдержанными интервалами в посылках). В качестве i2c - дисплей SSD1306 128x64.

 

Green
Offline
Зарегистрирован: 01.10.2015

Komandir пишет:

Только дураки не знают как пользоваться именами портов и пинов !


Так это же Серёжа Селево! Хочет всё и сразу.) Он безобидный парень, только ругается иногда.)))

Komandir
Komandir аватар
Offline
Зарегистрирован: 18.08.2018

yuhenotix@2p-mail.com пишет:

и предложенным RAW форматом, безо всякой твоей  х.еты с лишними символами в коде в каждой строчке.

 asm(R"(
ldi r16,0x03
out 0x05,r16
ldi r16,0x03
)");

Ну так покажите нам как в вашей не х.ете (и она не моя, а разработана GCC для не скудоумных) обращаться к переменным, константам, ..., ... ?

yuhenotix@2p-ma...
Offline
Зарегистрирован: 09.06.2019

Ты оказывается  не только глуп но еще и ленив, тут два раза давали ссылки на статьи   в которых описано  как происходит  взаимодействие   Си-ассемблер в  функциях и переменных

Komandir
Komandir аватар
Offline
Зарегистрирован: 18.08.2018

Ну вы же подняли тему RAW формата, а он про inline вставки на ассемблере. Чего завиляли то сразу ??? Нет сил/ума освоить несколько страниц - https://web.stanford.edu/class/ee281/projects/aut2002/yingzong-mouse/media/GCCAVRInlAsmCB.pdf