Зарегистрирован: 23 сен 2010, 09:16 Сообщения: 77
прог. языки: Forth
Продолжу. В прошлый раз вы увидели легкость использования встроенного ассемблера и сокращение временных издержек, которое он обеспечивает. Я же в свою очередь получил опыт и теперь являюсь обладателем инструмента, который позволяет оценить временные параметры любого фрагмента кода. Теперь мерилом является Таймер1. Привожу лог аплоудера, в котором эхом выводится загружаемый в amForth исходник:
Код:
SP-FORTH - ANS FORTH 94 for Win95/98/Me/NT/2k/XP/Vista Open source project at http://spf.sf.net Russian FIG at http://www.forth.org.ru ; Started by A.Cherezov Version 4.20 Build 001 at 21.Jan.2009
>S" d:\ucontrollers\amforth\amforth-4.2\amforth-4.2_uploader.spf" INCLUDED Ok >commopen CommPort handle= 2A8 Ok >S" D:\uControllers\amforth\amforth-4.2\lib\my\" setdir! Ok >S" tttt1.frt" setfile! Ok >getfile
source file: D:\uControllers\amforth\amforth-4.2\lib\my\tttt1.frt 428 loaded: 1113 okay Ok >download
Зарегистрирован: 23 сен 2010, 09:16 Сообщения: 77
прог. языки: Forth
well, moving forth
Обращаю ваше внимание на слово delay. Собственно из-за необходимости иметь такое слово в лексиконе, я и затеял всю эту возню с таймерами и ассемблером. Определено на ассемблере, в комментарии ( после слова '\' ) приведено форт-определение - полный функциональный аналог. Чуть погодя мы сравним "скорострельность" обоих вариантов.
Слово ?us - вот истинный инструмент, о котором я уже упоминал выше. Именно с его помощью возможно оценить временные параметры любого фрагмента кода ( лишь бы он был оформлен в виде одного-единственного слова ). Основную работу выполняет фраза <t1 execute t1>. Привлекает внимание слово execute. Обращаясь к классике жанра ( перевод книги Staring Forth "Начальный курс программирования на языке Форт" (c) Лео Броуди можно взять тут http://fforum.winglion.ru/viewtopic.php?p=20944#20944 ) узнаем, что Слово EXECUTE выполняет определение, адрес которого задается в стеке ( глава 9 ) В этой же главе можно узнать, откуда берется на вершине стека этот самый адрес.
Ну что же, код загружен, приступим к практике. Запускаю HyperTerminal:
Код:
amforth 4.2 ATmega32 > words ?us delay <t1 t1> tccr1b tccr1a -tttt1- run park park park stm2 stm1 .x .rotate stm? stopoff wave! normal! half! reverse rotate step idx- idx+ init_stm! motor@ stepper: /stepper motor res1 total steps direction dly ststate shft sequence idx -- normal wave half-step phase -stepper help help-wl -help .base calc-baudrate .res .( erase -misc twi.scan twi.ping? twi.status? twi.status twi.rxn twi.rx twi.tx twi.action twi.stop twi.start twi.wait -twi twi.default +twi -spi -spi2x +spi2x +spi spi.f/128 spi.f/64 spi.f/16 spi.f/4 spi.mode3 spi.mode2 spi.mode1 spi.mode0 spi.MASTER spi.MSB spi.SPE _spi_ ftgl fclr? fset? fclr fset bv flag: pin_pullup_on pin_highZ toggle pin@ pin_low? pin_high? pin_input pin_output pin! is_high? is_low? pulse low high bitmask: portpin: tlist alsotask onlytask multi single task activate cell- task-awake task-sleep stop multitaskpause wake pass follower status dump edump idump dump> <dump trimm .addr .rcells .ecells .icells ? e? i? .item u.r endcase endof of case assembler vocabulary Rdefer Rdefer! Rdefer@ Udefer Udefer! Udefer@ Edefer Edefer! Edefer@ action-of anew possibly move blank nip tuck ? xt>nfa >body chars char+ c, aligned align restore-input save-input source-id postpone fm/mod sm/rem dabs ?negate ?dnegate dnegate u*/mod sqrt -math m+ 2variable 2constant 2! 2@ 2tuck 2nip 2rot 2swap 2over 2dup 2drop marker i@ (i!) i! e@ e! not s>d up! up@ >< cmove> unloop i sp! sp@ rp! rp@ +! rshift lshift 1- 1+ xor or and 2* 2/ invert um* um/mod m* + - log2 d< d> 0> u> u< true 0 0< > < 0<> 0= = <> r@ >r r> rot drop over swap ?dup dup c@ c! ! @ execute exit -int +int UDR UCSRB UCSRA UBRRL UBRRH TWSR TWDR TWCR TWBR TWAR TCNT2 TCCR2 OCR2 ASSR TCNT1L TCNT1H TCCR1B TCCR1A OCR1BL OCR1BH OCR1AL OCR1AH ICR1L ICR1H TIMSK TIFR TCNT0 TCCR0 OCR0 SPSR SPDR SPCR PORTD PIND DDRD PORTC PINC DDRC PORTB PINB DDRB PORTA PINA DDRA GIFR GICR EEDR EECR EEARL EEARH SREG SPL SPH OSCCAL MCUCSR MCUCR SPMCR ACSR SFIOR ADMUX ADCSRA ADCL ADCH ms 1ms ewords fill #int int@ show-wordlist b> >b b!- b!+ nb! b! b@- b@+ nb@ b@ a> >a a!- a!+ na! a! a@- a@+ na@ a@ wordlist forth definitions previous also forth-wordlist only set-order set-current spirw sleep wdr -wdt -jtag +usart baud tx? tx rx? rx order get-order get-current environment? environment end-code code abort abort" [char] immediate recurse user constant variable [ ] ; :noname : does> create ?do leave +loop loop do again until repeat while begin then else if literal int! applturnkey is Rdefer Edefer words s" ." .s u. dinvert d- d+ d2* init-user ee>ram ee-user tib d2/ cmove dnegate dabs d>s j * defer@ defer! icompare find search-wordlist to value unused noop ver ?stack interpret depth rp0 sp sp0 cold pause quit place word /string source cscan parse 2swap >number number char refill accept cskip throw catch handler ' type count spaces space cr icount itype s, digit? ud/mod ud.r ud. . d. .r d.r sign #> #s # <# hold hld within max min abs mod / negate u/mod */ /mod */mod turnkey bl hex decimal bin ['] , compile ( \ allot here edp dp /key key? key emit? emit pad #tib >in cell+ cells base state f_cpu ok
> .res amforth 4.2 ATmega32 running at 8000 kHz free FLASH cells 5357 free RAM bytes 1712 used EEPROM bytes 68 used data stack cells 0 used return stack cells 5 free return stack cells 35 ok >
Привел состояние системы ( amForth, конечно же ) после загрузки timer1 tools for timing tests. words выводит список всех слов, присутствующих в системе на текущий момент. Количество впечатляет? Это еще не видны слова, находящиеся в словаре assembler. Потестим слово noop:
Код:
> ' noop ?us (0x9 ) 9 us ok >
Как видите, по сравнению с прошлым тестом noop'а, добавились 2 микросекунды - накладные расходы на вызов execute. Это нестрашно. Потестим штатные слова 1ms и ( n -- ) ms:
Код:
> ' 1ms ?us ( 0x3DD ) 989 us ok > 1 ' ms ?us ( 0x3F5 ) 1013 us ok > 10 ' ms ?us ( 0x26C5 ) 9925 us ok > 60 ' ms ?us ( 0xE82E ) 59438 us ok > 66 ' ms ?us ( 0xFF64 ) 65380 us ok > 67 ' ms ?us ( 0x342 ) 834 us overrun ok >
Ну что ж, как видим, временные параметы 1ms и ms близки к заявленым. Теперь потестим delay. Форт-аналог ассемблерного назову delayf , чтобы они могли совместно присутствовать в словаре:
Код:
> : delayf begin 1- dup 0= until drop ; ok > 1 ' delay ?us ( 0xA ) 10 us ok > 1 ' delayf ?us ( 0x21 ) 33 us ok > 10 ' delay ?us ( 0xE ) 14 us ok > 10 ' delayf ?us ( 0xB6 ) 182 us ok > 100 ' delay ?us ( 0x3C ) 60 us ok > 100 ' delayf ?us ( 0x683 ) 1667 us ok > 1000 ' delay ?us ( 0x1FD ) 509 us ok > 1000 ' delayf ?us ( 0x4084 ) 16516 us ok > 0 ' delay ?us ( 0x800A ) 32778 us ok > 0 ' delayf ?us ( 0x8010 ) 32784 us overrun ok >
Почувствуйте, как говорится, разницу...
Итого, в сухом остатке - ?us и delay. Минимальная задержка delay = 10 микросекунд, максимальная = 32778. Вполне себе юзабельный результат. Точная подгонка "по месту" обеспечивается ?us. Смею предположить, что ?us может использоваться не только для подбора параметра delay.
Ну вот, можно возвращаться к драйверу мышки пиэспополам. Скоро будет...moving forth
code +ps/2_clk ps/2_clk over over 1 - swap cbi, \ set input swap sbi, \ and pull-up end-code
code +ps/2_data ps/2_data over over 1 - swap cbi, \ set input swap sbi, \ and pull-up end-code
code -ps/2_clk ps/2_clk over over 1 - swap sbi, \ set output swap cbi, \ and low end-code
code -ps/2_data ps/2_data over over 1 - swap sbi, \ set output swap cbi, \ and low end-code
code ?ps/2_clk+ \ begin ps/2_clk pin_high? until label> ps/2_clk 2 - swap sbis, <radr rjmp, end-code
code ?ps/2_clk- \ begin ps/2_clk pin_low? until label> ps/2_clk 2 - swap sbic, <radr rjmp, end-code
code ?ps/2_data- \ begin ps/2_data pin_low? until label> ps/2_data 2 - swap sbic, <radr rjmp, end-code
code ?ps/2_data+ \ begin ps/2_data pin_high? until label> ps/2_data 2 - swap sbis, <radr rjmp, end-code
code ps/2_bit ( p c ) R16 1 ldi, R16 R24 and, \ get current bit R17 Y+ ld, \ get parity bit R17 R16 eor, \ check parity -Y R17 st, \ save parity bit R24 lsr, \ next data bit -Y R25 st, -Y R24 st, R24 R16 mov, \ current data bit end-code ( p' c' b )
code ps/2_bit@ \ 1 rshift ps/2_data pin_high? if 0x80 or then R24 lsr, ps/2_data 2 - swap sbic, R24 $80 ori, end-code
forth only
1 constant odd \ пижонство, ага
: ps/2! ( c -- ) \ ps/2 write byte
odd swap ( p c ) +ps/2_clk +ps/2_data 600 delay \ idle state -ps/2_clk 600 delay \ -ps/2_data 18 delay \ start +ps/2_clk \ bit
8 0 do ?ps/2_clk- ( p' c' ) ps/2_bit if +ps/2_data else -ps/2_data then ?ps/2_clk+ loop drop ( p )
\ parity ?ps/2_clk- if +ps/2_data else -ps/2_data then ?ps/2_clk+
\ stop bit ?ps/2_clk- +ps/2_data ?ps/2_clk+
\ ack bit ?ps/2_clk- ?ps/2_data- ?ps/2_clk+ ?ps/2_data+
Зарегистрирован: 23 сен 2010, 09:16 Сообщения: 77
прог. языки: Forth
In Forth We trust.
Ну-с, помолясь, приступаю... Мой анабасис по просторам робофорума завершается вполне себе удовлетворительно. Мыша под контролем, шаговички шевелятся сообразно мышкиным телодвижениям. Кривовато, но но при первом приближении - благостно
Особо удалось возвращение шаговичков в исходное положение при нажатии правой кнопки мыша - работает исправно. Кривость имеет своей причиной сырой код и проявляется в не всегда адекватном вращении двигателей. Лечится переосмыслением и переработкой stepper12.f и polar.f, а также ( предположительно ) настройкой scaling и resolution параметров мыша. К качеству драйвера мыша ps2m.f лично у меня претензий нет, более того, считаю получившийся код плотным и прозрачным для понимания ( пригодным для применения в других проектах ). Прошивочку не выкладываю по двум причинам: - 1. без бубна не заработает ( необходима инициализация структур двигателей в озу и инициализация multitasker'a ). - 2. зафиксировано отсутствие практического интереса к этой теме у читателей данной периферийной ветки робофорума, иными словами - похоже, что неактуально. Кстати, бубен к п.1 довольно прост: увидев в консоли amforth'a готовность, необходимо набрать -polar-
Код:
> amforth 4.2 ATmega32 > -polar- ok >
после чего amforth "забудет" все, начиная со строчки marker -polar- и до самого конца. После этого скормить amforth'у аплоадером ( штатный uploader лежит в папочке /tools ) файлик polar.f и набрать в консоли polar-go!...
Код:
> polar-go! FA AA 0 FA ok > stm1 stm0 stm? stm?
port.............3B mask.............F ................. idx..............0 sequence.........1 delay............2 direction........0 steps to rotate..0 total steps......0 motor status.....0
port.............3B mask.............F0 ................. idx..............0 sequence.........1 delay............5 direction........-1 steps to rotate..0 total steps......0 motor status.....0 ok > .res amforth 4.2 ATmega32 running at 8000 kHz free FLASH cells 4484 free RAM bytes 1356 used EEPROM bytes 72 used data stack cells 0 used return stack cells 5 free return stack cells 35 ok > words polar-go! task-stm? task-azimuth task-altitude task-control polar-stm? polar-azimuth polar-altitude polar-control azimuth altitude stm_control ?action park? park! run stm+! steps! stm1 stm0 -polar- m? workout mflags m@ !m m!@ l-btn r-btn m-btn x-sign y-sign x-ovflw y-ovflw mice_status mice_read mice_remote mice_id mice_reset mice_ack -mice- ps/2@ ps/2! odd ps/2_bit@ ps/2_bit ?ps/2_data+ ?ps/2_data- ?ps/2_clk- ?ps/2_clk+ -ps/2_data -ps/2_clk +ps/2_data +ps/2_clk ps/2_data ps/2_clk portbit#: (portbit#) -rot -ps/2- stm? stm_unlock stm_lock stm_lock? lock_stm park stopoff wave! normal! half! reverse direction! rotate step total- total+ idx- idx+ init_stm! motor@ stepper: motor! /stepper motor res1 total steps direction dly ststate shft sequence idx -- normal wave half-step phase -stepper- ?us .t1 <t1> delay <t1 t1> tccr1b tccr1a -tttt1- .x help help-wl -help .base calc-baudrate .res .( erase -misc twi.scan twi.ping? twi.status? twi.status twi.rxn twi.rx twi.tx twi.action twi.stop twi.start twi.wait -twi twi.default +twi -spi -spi2x +spi2x +spi spi.f/128 spi.f/64 spi.f/16 spi.f/4 spi.mode3 spi.mode2 spi.mode1 spi.mode0 spi.MASTER spi.MSB spi.SPE _spi_ ftgl fclr? fset? fclr fset bv flag: pin_pullup_on pin_highZ toggle pin@ pin_low? pin_high? pin_input pin_output pin! is_high? is_low? pulse low high bitmask: portpin: tlist alsotask onlytask multi single task activate cell- task-awake task-sleep stop multitaskpause wake pass follower status dump edump idump dump> <dump trimm .addr .rcells .ecells .icells ? e? i? .item u.r endcase endof of case assembler vocabulary Rdefer Rdefer! Rdefer@ Udefer Udefer! Udefer@ Edefer Edefer! Edefer@ action-of anew possibly move blank nip tuck ? xt>nfa >body chars char+ c, aligned align restore-input save-input source-id postpone fm/mod sm/rem dabs ?negate ?dnegate dnegate u*/mod sqrt -math m+ 2variable 2constant 2! 2@ 2tuck 2nip 2rot 2swap 2over 2dup 2drop marker i@ (i!) i! e@ e! not s>d up! up@ >< cmove> unloop i sp! sp@ rp! rp@ +! rshift lshift 1- 1+ xor or and 2* 2/ invert um* um/mod m* + - log2 d< d> 0> u> u< true 0 0< > < 0<> 0= = <> r@ >r r> rot drop over swap ?dup dup c@ c! ! @ execute exit -int +int UDR UCSRB UCSRA UBRRL UBRRH TWSR TWDR TWCR TWBR TWAR TCNT2 TCCR2 OCR2 ASSR TCNT1L TCNT1H TCCR1B TCCR1A OCR1BL OCR1BH OCR1AL OCR1AH ICR1L ICR1H TIMSK TIFR TCNT0 TCCR0 OCR0 SPSR SPDR SPCR PORTD PIND DDRD PORTC PINC DDRC PORTB PINB DDRB PORTA PINA DDRA GIFR GICR EEDR EECR EEARL EEARH SREG SPL SPH OSCCAL MCUCSR MCUCR SPMCR ACSR SFIOR ADMUX ADCSRA ADCL ADCH ms 1ms ewords fill #int int@ show-wordlist b> >b b!- b!+ nb! b! b@- b@+ nb@ b@ a> >a a!- a!+ na! a! a@- a@+ na@ a@ wordlist forth definitions previous also forth-wordlist only set-order set-current spirw sleep wdr -wdt -jtag +usart baud tx? tx rx? rx order get-order get-current environment? environment end-code code abort abort" [char] immediate recurse user constant variable [ ] ; :noname : does> create ?do leave +loop loop do again until repeat while begin then else if literal int! applturnkey is Rdefer Edefer words s" ." .s u. dinvert d- d+ d2* init-user ee>ram ee-user tib d2/ cmove dnegate dabs d>s j * defer@ defer! icompare find search-wordlist to value unused noop ver ?stack interpret depth rp0 sp sp0 cold pause quit place word /string source cscan parse 2swap >number number char refill accept cskip throw catch handler ' type count spaces space cr icount itype s, digit? ud/mod ud.r ud. . d. .r d.r sign #> #s # <# hold hld within max min abs mod / negate u/mod */ /mod */mod turnkey bl hex decimal bin ['] , compile ( \ allot here edp dp /key key? key emit? emit pad #tib >in cell+ ceЃ&s base state f_cpu ok > stm1 stm0 stm? stm?
port.............3B mask.............F ................. idx..............4 sequence.........1 delay............2 direction........0 steps to rotate..0 total steps......-996 motor status.....0
port.............3B mask.............F0 ................. idx..............2 sequence.........1 delay............5 direction........0 steps to rotate..0 total steps......162 motor status.....0 ok > stm1 stn m0 stm? stm?
port.............3B mask.............F ................. idx..............7 sequence.........1 delay............2 direction........0 steps to rotate..0 total steps......-641 motor status.....0
port.............3B mask.............F0 ................. idx..............5 sequence.........1 delay............5 direction........0 steps to rotate..0 total steps......589 motor status.....0 ok > stm1 stm0 stm? stm?
port.............3B mask.............F ................. idx..............0 sequence.........1 delay............2 direction........0 steps to rotate..0 total steps......0 motor status.....0
port.............3B mask.............F0 ................. idx..............0 sequence.........1 delay............5 direction........-1 steps to rotate..0 total steps......0 motor status.....0 ok > stm1 stm0 stopoff stopoff ok >
Ну вот, мой анабасис и завершился. "Полярную" тему я пока отложу, бо нету подходящих задач, вам - безразлично, а мне - стало скучно. Интересно былобы мини-бота поднять на amforth'e, но один - не возьмусь, а энтузиастов не наблюдается ( да и мини-бота у мене немае...). Опять же, ребята с эмбеддерз.орг попеняли мне - чего, мол, не у них выложился ( а нефиг форт гнобить и надсмехаться ). Есть еще интерес - camelforth для msp430 пошевелить, но это уже не здесь будет, видимо... Moving forth... Исходнички ( для любопытствующих ) приложил.
Зарегистрирован: 23 сен 2010, 09:16 Сообщения: 77
прог. языки: Forth
Разжился датчиком ds1822 . Скоро буду измерять температуру за бортом. Поисковый алгоритм для сети 1-wire microlan тоже будет, но не сразу. moving forth.
Зарегистрирован: 23 сен 2010, 09:16 Сообщения: 77
прог. языки: Forth
Цитата:
Я установил AVR Studio, но откомпилировать не смог. постоянно ошибки не найден файл.
я тоже с этим парился. возможное решение - при открытом проекте ( в AVR Studio ) зайти ->Project->Assembler options и поправить Additional include path как-то так: ...\amforth-4.2\core. точнее не скажу, не видел сообщений AVR Studio.
Цитата:
И второй вопрос: на ATMega168 запустится?
запустится, но придется экономить память, лишаясь некоторых удобств. (...\amforth-4.2\lib\files.frt )
на некоторые вопросы можно найти ответы на http://amforth.sourceforge.net/ в разделе FAQ последним пунктом - Compiling amforth under Windows. рекомендую ознакомиться.
прилагаю свою свежую рабочую папочку с проектом AVR Studio 4.18.700 ; AVR ATmega32 @16MHz. работает. библиотечных файлов не загружал (пока). фьюзы - вложены. в листинге AVR Studio все подробно видно - включенные файлы и использованный ресурс микроконтроллера.
Начинаю оценивать мощь Форта. Действительно можно программировать прямо на МК. Это круто!. А режим интерпретации дает вообще неограниченные возможности по интерактивному изучению МК.
Код:
amforth 4.2 ATmega168 > hex ok > 1 24 ! ok > 1 25 ! ok > 0 25 ! ok >
Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 4
Вы не можете начинать темы Вы не можете отвечать на сообщения Вы не можете редактировать свои сообщения Вы не можете удалять свои сообщения Вы не можете добавлять вложения