И така,вече направихме нещо,но не можем да го асимилираме защото имаме неяснотии.В краина сметка нашия микроконтролер вече не е парче пластмаса.Сега от него свети един светодиод, и даже мига...тоест имаме успех все пак .Когато аз размигах първия си светодиод бях много щастлив-има една поговорка:"Колко малко му трябва на човек да е щастлив-парче хляб, малко сол , една малка 7 метрова яхта, и една малка триетажна вила в Маями .
Сега ще поговорим за алгоритмите.
Алгоритъм-това е една последователност от команди.
Линеен алгоритъм-това е такъв алгоритъм в който командите се изпълняват последователно една след друга-точно линеино.
Пример за линеен алгоритъм:
1.Прибери се в къщи
2.направи си кафе
3.запали си цигара
4.изпуши си цигарата с кеф и си пии кафето..... и т.н.
Нелинеен алгоритъм/променлив,диференциален/алгоритъм,тои изглежда така:
1.прибери се в къщи
2.направи си кафе.
3.ако има цигара я вземи,ако няма цигара ,си направи ядене
4.ако е имало цигара я запали и изпуши пиеики си кафето,ако е нямало цигара се наяж.
Диференциалния алгоритъм се отличава от линеиния алгоритъм по това че според някакви обстоятелства,то тои може да се изпълни по няколко различни начина.....Линеиния алгоритъм от началото до края се изпълнява по една последователност и по един начин.
Диференциалния алгоритъм се създава от различни каманди :
Ако(таковата) - тогава(ще го таковаме), иначе(няма да го таковаме)
В ассемблера също има такива команди.Сега ще разгледаме някои от тях.
brne (Branch if Not Equal) - преход към метката, ако резултата от предишното действие – не е нула
Пример:
brne Label - премини към метке Label.
Още не сме разказали за метките!
Метка значи някакво място в програмата,позволяващо в един свободно избран момент да се прескочи директно в това място като не се изпълняват опарациите преди него.
Всяка метка има свое единствено и неповторимо име вътре в една програма.И тъи като асамблера е нечувствителен към регистрите,затова думи като Label,label,LABEL-за компилатора са напълно еднакви,за разлика от С.
В асамблера метката се поставя така:
...
and Temp1,Temp3
Label: ldi Temp1,100
mov Temp,Temp1
...
Тогава при преход на метка Label,програмата започва да изпълнява команда”ldi Temp1,100”.
Разбира се на метка може да се отиде не само по условие,но и „просто еи така за кеф”.Такъв преход се нарича безусловен:
rjmp - безусловен преход към метката
Пример:
rjmp Label
И за пълна красота ,ето още няколко условни прехода:
breq - (Branch if Equal)преход, ако резултата от предишното действие - нула
brmi - (Branch if Minus) преход, ако резултата е отрицателен. (При това, числото 0 се счита за положително.)
brpl - (Branch if Plus) преход, ако резултата е положителен
това е,сега може да напишем нашия алгоритъм.
Но преди това ето още две команди:
inc - (Increment) увеличаване на значението на РОН на 1 (инкремент)
dec - (Decrement) намаляване на значението на 1 (декремент).
Пример:
inc Temp2
dec Temp3
а сега да видим как работи тази програма:
ldi Temp,0
Loop: dec Temp
brne Loop
Първо сме инициализирали Temp с числото 0.После от Temp се вади 1.Неговото значение става -1/казано по друг начин,255/След това проверяваме дали не се е получила 0.Тъи като числото 255 не е равно на 0,отново отиваме на операцията декремент.
Значението на Temp се намалява още с 1.Сега то е 244.Но това също не е 0,и отново отиваме в началото....И така до тогава,докато в един прекрасен момент в отговор се получи 0.Когато всичкото това свърши излизаме от цикъла и продължаваме напред-тоест надоло по сорс кода на програмата...
Това което гледахме да сега,се нарича цикъл със задръжки.
Защо?Защото тази част от програмата по същност нищо не прави,но изпълнява процесорните тактове-минава време демек.Този цикъл ще ни трябва много пъти във всяка една програма.Този цикъл определя времето за деиствие или бездеиствие –тоест скороста с която ще се изпълни дадено деиствие.
Може да се правят няколко цикъла на задръжка:
ldi Temp1,0
ldi Temp2,0
ldi Temp3,100
Loop: dec Temp1
brne Loop
dec Temp2
brne Loop
dec Temp3
brne Loop
Сега вече имаме нужните знания,за да напишем програма за бягаща светлина или за мигалка.
Пишем!
.cseg
.org 0
ldi Temp,0b11111111 ;настройкана всичките крачета от порт B
out DDRB,Temp ;порт В на изход
;DDRB-таз команда превключва порт Б на изход.
Begin: ldi Temp,0b00000001 ;светка 1-я светодиод-където има 1
out PortB,Temp ;порт В го кръщаваме Temp
ldi Temp1,0 ;задържане чрез цикли,темп1 и темп2 ги
;правим=0,и почва цикъл да се намялят
;от 0/255/ надоло през -244,-243,-242 и т.н
;докато отново станат нула.
ldi Temp2,0
ldi Temp3,100
Loop1: dec Temp1
brne Loop1 ;когато темп1 стане нула отново,продлъжава прогр
;амата надоло
dec Temp2
brne Loop1
dec Temp3
brne Loop1
ldi Temp,0b00000010 ;светкаме 2-я светодиод
out PortB,Temp
ldi Temp1,0 ;задържаме
ldi Temp2,0
ldi Temp3,10
Loop2: dec Temp1
brne Loop2
dec Temp2
brne Loop2
dec Temp3
brne Loop2
ldi Temp,0b00000100 ;светкаме 3-я светодиод
out PortB,Temp
ldi Temp1,0 ;задържаме
ldi Temp2,0
ldi Temp3,10
Loop3: dec Temp1
brne Loop3
dec Temp2
brne Loop3
dec Temp3
brne Loop3
ldi Temp,0b00001000 ;светка 4-я светодиод
out PortB,Temp
ldi Temp1,0 ;задържаме
ldi Temp2,0
ldi Temp3,10
Loop4: dec Temp1
brne Loop4
dec Temp2
brne Loop4
dec Temp3
brne Loop4
rjmp Begin ;ржумп-веднага да отиде на бегин
;значи цикъла на програмата почва отново
Програмата е написана само за 4 светодиода.Мисля че да се допише и за останалите 4 от този порт няма да е голяма трудност.
И така както до сега:компилираме,шием,гледаме умно...Ако искаме да разберем колко точно е един цикъл или машинен такт то пишем темп1,1 и мерим с осцилоскопа колко мкс идва, после пишем темп1,100 и пак мерим и правим сравнение и т.н.
Викам си че без излишни коментарии се разбира че програмата стана прекалено голяма.По натам ще видим как да я намалим от към писане и когато привършим с асамблера и минем на беисик примерно това което сега е десетина реда може да го направим с 2 реда примерно но всяко нещо с времето си.