\ chu 13:59 17.04.2013
\ 22:57 17.04.2013
\
marker =adc=
: adc-start ADCSRA ADCSRA_ADSC over c@ or swap c! ;
: adc-complete? ADCSRA c@ ADCSRA_ADSC and 0= ;
: adc-data? ADCSRA c@ ADCSRA_ADIF and ;
: adc-end ADCSRA ADCSRA_ADIF over c@ or swap c! ;
\ adc turn on
: adc+
\ sound_sensor pin_pullup_off \ input & low
%01100000 ADMUX c! \ REFS=01, ADLAR=1, MUX=00000
[ ADCSRA_ADEN \ ADC on
ADCSRA_ADPS or \ 16MHz/128=125KHz
] literal
ADCSRA c!
;
\ turn off
: adc-
ADCSRA
ADCSRA_ADEN invert
over c@ and swap c!
;
\
\ =============================================================================
\ adc init
\ $20 constant ADLAR
: ad<left ADMUX ADMUX_ADLAR over c@ or swap c! ;
: ad>right ADMUX dup c@ ADMUX_ADLAR invert and swap c! ;
\ select analog channel
: adc! ( n --- )
ADMUX_MUX and ADMUX c@
ADMUX_MUX invert and or ADMUX c!
;
\ read adc result
: adc@ ADC c@ ADC 1+ c@ 8 lshift + ; ( --- un )
\ get ad convertion
: !adc@ adc-start begin adc-complete? until adc@ ;
\
\ =============================================================================
: adc-tst begin !adc@ .x cr pause 500 ms key? until key drop ;
\ ADC info
\ chu 1:23 19.04.2013
\
marker =adc-info=
: ?adc.
ver bl emit ." AD Converter" cr
\
ADMUX c@
." *******" cr
." (ADMUX) ADC Multiplexer Selection Register = " dup .x cr
\
dup ADMUX_REFS and dup ." Reference Selection Bits = " .x cr
6 rshift
case
&0 of ." AREF, Internal Vref turned off " endof
&1 of ." AVCC with external capacitor at AREF pin " endof
&2 of ." Reserved " endof
&3 of
." Internal 2.56V Voltage Reference with external capacitor at AREF pin "
endof
endcase cr
\
." ADLAR = "
dup ADMUX_ADLAR and if
." left adjust" else
." right adjust" then cr
\
." Analog Channel and Gain Selection Bits" cr
ADMUX_MUX and dup
case
&0 &8 range of ." Single Ended Input - A" .x endof
&9 &30 range of
." Differential Inputs, see p224 datasheet" drop endof
&30 of ." 1.22V (Vbg)" drop endof
&31 of ." 0V (GND)" drop endof
endcase cr
." ********" cr
\
ADCSRA c@
." (ADCSRA) ADC Control and Status Register A = " dup .x cr
\
." ADC is turned "
dup ADCSRA_ADEN and if ." ON" else ." OFF" then cr
\
." AD Convertion is "
dup ADCSRA_ADSC and if
." in progress" else
." complete" then cr
\
dup ADCSRA_ADATE and if
." triggered" else
." single convertion" then cr
\
dup ADCSRA_ADIF and if
." ADC conversion completes and the Data Registers are updated" then cr
\
." ADC Interrupt "
dup ADCSRA_ADIE and if
." enabled" else
." disabled" then cr
\
." ADC Prescaler Select Bits = "
ADCSRA_ADPS and dup .x ." , "
." ADC clocks = "
f_cpu &1000 um/mod swap drop
swap
case
0 &2 range of &2 endof
&2 of &4 endof
&3 of &8 endof
&4 of &16 endof
&5 of &32 endof
&6 of &64 endof
&7 of &128 endof
endcase / base @ swap decimal . base ! ." KHz" cr
;
Release 5.6 is out and it is by far the biggest change in amforth ever.
It is the first version that runs on two different controller types:
AVR Atmegas and the TI MSP430 (Launchpad G2553).
...
Enjoy
Matthias
setar писал(а):а в чем прикол ?
сейчас есть гораздо более интересные векторы приложения для обучения.
Например GoLang, который впитал в себя лучшее из C , Python , java , лишен их недостатков
и к тому же компилируемый и мультипоточный из коробки.
Синтаксис Go на порядок более читаемый и понятный интуитивно
setar писал(а):Этот фактор влияет прежде всего на количество ошибок, прежде всего логических
setar писал(а):Да кто же спорит, асемблер тоже много где встречается.
От этого от не становится более читаемым.
Лично я не горю желанием изучать язык если при первом взгляде на текст программы я не понимаю что в ней написано.
вероятно это моя личная фича, но предположу что так у 90% пользователей.
На мой взгляд выбрать для изучения Форт сегодня может только человек которому досталось "тяжелое наследство" которое нужно обслуживать
setar писал(а):Лично я не горю желанием изучать язык если при первом взгляде на текст программы я не понимаю что в ней написано.
// Called 8 times per bit period
// Phase locked loop tries to synchronise with the transmitter so that bit
// transitions occur at about the time vw_rx_pll_ramp is 0;
// Then the average is computed over each bit period to deduce the bit value
void vw_pll()
{
// Integrate each sample
if (vw_rx_sample)
vw_rx_integrator++;
if (vw_rx_sample != vw_rx_last_sample)
{
// Transition, advance if ramp > 80, retard if < 80
vw_rx_pll_ramp += ((vw_rx_pll_ramp < VW_RAMP_TRANSITION)
? VW_RAMP_INC_RETARD
: VW_RAMP_INC_ADVANCE);
vw_rx_last_sample = vw_rx_sample;
}
else
{
// No transition
// Advance ramp by standard 20 (== 160/8 samples)
vw_rx_pll_ramp += VW_RAMP_INC;
}
if (vw_rx_pll_ramp >= VW_RX_RAMP_LEN)
{
// Add this to the 12th bit of vw_rx_bits, LSB first
// The last 12 bits are kept
vw_rx_bits >>= 1;
// Check the integrator to see how many samples in this cycle were high.
// If < 5 out of 8, then its declared a 0 bit, else a 1;
if (vw_rx_integrator >= 5)
vw_rx_bits |= 0x800;
vw_rx_pll_ramp -= VW_RX_RAMP_LEN;
vw_rx_integrator = 0; // Clear the integral for the next cycle
if (vw_rx_active)
{
// We have the start symbol and now we are collecting message bits,
// 6 per symbol, each which has to be decoded to 4 bits
if (++vw_rx_bit_count >= 12)
{
// Have 12 bits of encoded message == 1 byte encoded
// Decode as 2 lots of 6 bits into 2 lots of 4 bits
// The 6 lsbits are the high nybble
uint8_t this_byte =
(vw_symbol_6to4(vw_rx_bits & 0x3f)) << 4
| vw_symbol_6to4(vw_rx_bits >> 6);
// The first decoded byte is the byte count of the following message
// the count includes the byte count and the 2 trailing FCS bytes
// REVISIT: may also include the ACK flag at 0x40
if (vw_rx_len == 0)
{
// The first byte is the byte count
// Check it for sensibility. It cant be less than 4, since it
// includes the bytes count itself and the 2 byte FCS
vw_rx_count = this_byte;
if (vw_rx_count < 4 || vw_rx_count > VW_MAX_MESSAGE_LEN)
{
// Stupid message length, drop the whole thing
vw_rx_active = false;
vw_rx_bad++;
return;
}
}
vw_rx_buf[vw_rx_len++] = this_byte;
if (vw_rx_len >= vw_rx_count)
{
// Got all the bytes now
vw_rx_active = false;
vw_rx_good++;
vw_rx_done = true; // Better come get it before the next one starts
}
vw_rx_bit_count = 0;
}
}
// Not in a message, see if we have a start symbol
else if (vw_rx_bits == 0xb38)
{
// Have start symbol, start collecting message
vw_rx_active = true;
vw_rx_bit_count = 0;
vw_rx_len = 0;
vw_rx_done = false; // Too bad if you missed the last message
}
}
}
\ ----------------------------------------------------
\ Called 8 times per bit period
\ Phase locked loop tries to synchronise with the transmitter so that bit
\ transitions occur at about the time vw_rx_pll_ramp is 0;
\ Then the average is computed over each bit period to deduce the bit value
: vw_pll
SAMPLE ?TRANSITION
LAST-SAMPLE? if GET-BIT
RX-ACTIVE? if
WHOLE-BYTE? if
GET-BYTE IS-COUNT? if vw_rx_count !
RX-COUNT-GOOD? 0= if exit then
else
PUT-BYTE ?ALL-BYTES then
RESET-BIT-COUNT then
else
?START-SYMBOL then then
;
arithmetic
+ ( a b--a+b) addition
- ( a b--a-b) subtraction
* ( a b--a*b) multiply
/ ( a b--a/b) division
% ( a b--a%b) modulo (division reminder)
_ ( n-- -n) negate
bit manipulation
& ( a b--a&b) 32 bits and
| ( a b--a|b) 32 bits or
~ ( n -- n') not, all bits inversed (0=>1 1=>0)
stack
# ( a--a a) duplicate top of stack
\ ( a b--a) drop top of stack
$ ( a b--b a) swap top of stack
@ ( a b--a b a) (over) copy next of stack on top
register
x ( --) select register x (x: a..z)
; ( --value) fetch from selected register
: ( value--) store into selected register
? ( --value) selected register contains an address. Fetch value from there
! ( value--) selected register contains an address. Store value there.
+ ( --) immediately after register, increment content by 1
- ( --) immediately after register, decrement content by 1
functions
{X ( --) start function definition for function X (A..Z)
} ( --) end of function definition
X ( --) call function X (A..Z)
I/O
. ( value--) display value as decimal number on stdout
, ( value--) send value to terminal, 27 is ESC, 10 is newline, etc.
^ ( --key) read key from terminal, don't wait for newline.
" ( --) read string until next " put it on stdout
0..9 ( --value) scan decimal number until non digit. to push two values
on stack separete those by space (4711 3333)
to enter negative numbers call _ (negate) after the number
0..9.0 ( --value) to enter float numbers digits must contain one . (only
available if float module is active, see 0`)
conditions
< ( a b--f) true (-1) if b is < a, false (0) otherwise
> ( a b--f) true (-1) if b is > a, false (0) otherwise
= ( a b--f) true (-1) if a is queal to b, flase (0) otherwise
( ( f--) if f is true, execute content until ), if false
skip code until )
[ ( f--f) begin while loop only if f is true. keep flag on stack
if f is false, skip code until ]
] ( f--) repeat the loop if f is true. If f is false, continue
with code after ]
extensions (expermiental)
` ( n--) call extension function n
0 ... switch to floating point mode
+ - * / . _ < >
1 ... switch back to interger mode
2 ... dbg, function dbg() to set breakpoint for debugging
3 ... switch traceing on (IP, TOKEN, SP, STACK) (not in stable_fast)
4 ... switch traceing off. Tracing int file trace
5 ... < = > without dropping their 2nd operand (NOS). This
is the behavior of Santors original virtual engine.
6 ... mstime, time in milliseconds, for timing
7 ... ( n--) edit block number n
8 ... ( n--) load block number n. Data segment remains. So this
is a kind of shared memory. Registers could be used as arguments.
After leaving the application and 0 is on TOS, STABLE will be
terminated. A value not equal 0 on TOS will load this block.
If the block is not valid, the command block will be loaded
Use block 0 as an index for all your block numbers
9 ... ( n 9--) copy block n (1000 cells) into memory begining of 1000.
write back the old content before. At exit write back current
data block. STABLE is starting with block 0 loaded.
10 ... trace only current state (ip, rp, sp, ..) on stdout
11 ... quit VM ( n--) n is exit code to os
12 ... ( --n) push current data block number on stack
13 ... ( --) copy 1000 cells from address 1000 to 2000
14 ... ( --) copy 1000 cells from address 2000 to 1000
MISC (компьютер с минимальным набором команд, Minimal Instruction Set Computer) — архитектура для проектирования процессора, которая отличается наилучшей эффективностью и простотой в сравнении с CISC и RISC. Может содержать в себе блок RISC, обрабатывающий в себе от 10 базовых команд (+, —, /, *, if, else & etc), из которых формируются более сложные операции над значениями, методом ветвления полученных результатов в ПЗУ. С точки зрения быстродействия, время выполнения инструкции, скорость записи и передачи данных в память, сократилось бы в разы, так как не нужно было бы ожидать, пока заполнится и очистится конвейер, а выполнять всё «потоково» без задержек.
Причиной, по которой данная архитектура не стала популярной в компьютерных технологиях – сложность написания программ под различные процессоры. Ведь все нюансы по подбору методов вычисления и оптимизаций возлагались на плечи программистов. К тому же, с повышением сложности выполняемых задач, требовалось более сложное ПО, что тормозило бы развитие микропроцессорного рынка. Поэтому, было разумнее переложить и стандартизировать процессы выполнения стандартных формул (инструкций) на плечи процессорных специализированных блоков и написать программу «дирижёр», которая управляла бы этими процессами (как в CISC).
Тем не менее, если встроить в данные процессоры более совершенный блок инструкций, который декодировал бы их на аппаратном уровне, то равных по производительности энергоэффективности и простоте, данному процессору практически не нашлось бы.
Первая вариация данного процессора под названием MuP21 (1995г)
, имеет вычислительную способность 100 MIPS, при техпроцессе 1.2 мкм (!), энергопотребление 50 мВт. Работа процессорa на 100 мГц и количество транзисторов равно 7000 штук (!).
Впечатляет. У Pentium 1 (60 МГц) с 3.1 млн. транзисторов, 0,8 мкм и до 15 ватт энергопотреблением, вычислительные возможности были примерно на том же уровне.
...
В отличие и от самых эффективных эмуляторов Java-машины, и от лучших JIT-компиляторов
(осуществляющих трансляцию Java-кодов в коды целевой платформы в ходе загрузки
задачи), аппаратные стековые машины привлекательны не только (и не столько) очень
высокой производительностью, хотя их быстродействие впечатляет. Так, при потреблении
в 5 раз (!) меньшей мощности они уверенно — почти в 2 раза — обходят своих далеко
не самых медленных конкурентов из регистрового мира RISC: классическая стековая
машина "выдает" на тестах CM (CaffeineMark) 1900 единиц против 1000
единиц очень удачного процессора ARM7TDMI при тактовой частоте 100 MHz (для сравнения,
этот показатель соответствует уровню производительности процессора Intel Pentium
150 MHz или даже Pentium Pro 200 MHz — в зависимости от качества реализации виртуальной
машины Java). При этом следует учесть, что тесты CM комплексные, и полученная
оценка является интегрированной, включающей и интенсивные вычисления с плавающей
точкой, которые обычно производителями стековых машин аппаратно не поддерживаются!
Но все же главная привлекательность безадресных архитектур кроется в исключительно
высоких показателях скорости переключения между задачами/потоками в многозадачных/поточных
программных системах. Каноническим регистровым машинам в таких случаях надо сохранить
текущий контекст в стеке, размещающемся в некоторой области оперативной памяти.
Так как контекст современных процессоров достаточно объемен (обычно у них много
регистров), а операции записи во внешнюю память относительно медленны, то и время
переключения получается (в терминах процессора) очень продолжительным. Стековым
машинам такие операции не нужны — их контекст уже хранится в стеке, поэтому переключение
обычно осуществляется за один такт. Чтобы понять порядок величин, следует привести
такой пример: переключение между потоками даже в весьма неплохих ОС реального
времени, написанных на компилируемых языках и тщательно оптимизированных, отнимает
одну-две миллисекунды процессорного времени. Для процессора aJ-100 и программы,
написанной на Java, переключение между двумя потоками занимает строго 1 микросекунду.
Такая разница (на три порядка!) означает, что процессору легче "справляться"
со множеством разных задач, что исключительно важно уже не только для "настольных"
машин, но и для самых разнообразных персональных устройств.
..
Вернуться в МиниБот — национальный класс роботов
Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 9