Ассемблер (ASM) для AVR в вопросах и ответах

Обсуждаем контроллеры компании Atmel.
Ответить
Друг Кота
Аватара пользователя
Сообщения: 4966
Зарегистрирован: Сб май 05, 2012 20:19:55
Откуда: Минск

Сообщение Seriyvolk »

afz писал(а):Только у меня более-менее универсальная, а здесь под каждый проект нужно клепать отдельную
Зачем? Ты, видимо, нифига не понял. Второе окошко с кодом - это и есть содержание файла vectors.asm. Первое - сам код.
И вот у тебя есть несколько камней, с которыми работаешь. Для этих камней за 5 минут стряпаются нужные заготовки, которые потом методом Ctrl+С/Ctrl+V самого .inc/.asm (без разницы) файла подключаются к нужному проекту.
Вместо RETI пропсываешь путь к обработчику прерывания по мере написания кода.
А у тебя куча прыжков непонятно откуда и куда, а потом такая-же куча заглушек. Смотрится вырвиглазно и если
переносить на другой камень
то действительно очень легко
можно допустить ошибку, которую долго придется искать.
Прибор, защищённый предохранителем, сгорает первым, защитив предохранитель. Закон Мерфи.
Реклама
ARV
Ум, честь и совесть. И скромность.
Аватара пользователя
Сообщения: 18787
Зарегистрирован: Чт дек 28, 2006 08:19:56
Откуда: Новочеркасск

Сообщение ARV »

вообще-то для векторов прерываний правильная практика - задавать адрес вектора директивой .org и указанием символьного имени соответствующего вектора - см. соответствующий inc-файл для вашего типа МК. в этом случае достаточно задавать только задействованные векторы, причем в любом порядке - ассемблер сам расставит их в нужном порядке, заодно не надо помнить о размере команды jmp. заодно может быть и экономия памяти за счет использования неиспользуемой части таблицы векторов под полезный код.

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

Мой уютный бложик... заходите!
Контактная информация:
Реклама
Друг Кота
Аватара пользователя
Сообщения: 4966
Зарегистрирован: Сб май 05, 2012 20:19:55
Откуда: Минск

Сообщение Seriyvolk »

Ну хоть лакированные, и то хорошо. :))
Прибор, защищённый предохранителем, сгорает первым, защитив предохранитель. Закон Мерфи.
Друг Кота
Аватара пользователя
Сообщения: 6347
Зарегистрирован: Вт апр 24, 2007 07:45:40
Откуда: Minsk

Сообщение Jack_A »

ARV писал(а): заодно может быть и экономия памяти за счет использования неиспользуемой части таблицы векторов под полезный код.
Конечно, каждому - свое, но я бы так не делал. Экономия мизерная ( как сгоревшие лампочки - вместо поплавка в сливном бачке :) ) А гемору может добавить, если случайно :( инициализировалось одно из неиспользуемых прерываний, можем получить трудно уловимый глюк. Мне возразят - не должно быть случайной инициализации. Согласен, в отлаженной проге. А так к сырому исходнику еще добавлять потенциальный баго-генратор ...
Но, повторюсь : Jedem - das Seine.
Реклама
Эиком - электронные компоненты и радиодетали
ARV
Ум, честь и совесть. И скромность.
Аватара пользователя
Сообщения: 18787
Зарегистрирован: Чт дек 28, 2006 08:19:56
Откуда: Новочеркасск

Сообщение ARV »

вы начитались детских страшных сказок про трудноуловимые глюки. если мы говорим про AVR studio (а мы ведь про этот ассемблер говорим, верно?), то никаких трудноуловимых глюков там в принципе быть не может - максимум две-три попытки запуска отладчика, чтобы все эти "глюки" выловить.

что касается "я бы так не делал", то отвечу так: каждый волен сам выбирать себе способ выстрелить в ногу... глюков с размером jmp на больших и маленьких МК гораздо больше встречается, и отловить их существенно сложнее, ибо в случае "случайного" возникновения незапланированного прерывания переход происходит на непредсказуемый адрес с неизвестным опкодом - вот тут и профессионал сильно задумается, чего там говорить о начинающем...

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

Мой уютный бложик... заходите!
Контактная информация:
Реклама
afz
Опытный кот
Аватара пользователя
Сообщения: 744
Зарегистрирован: Сб дек 22, 2012 08:17:42
Откуда: Караганда, Казахстан

Сообщение afz »

ARV писал(а):вообще-то для векторов прерываний правильная практика - задавать адрес вектора директивой .org и указанием символьного имени соответствующего вектора
Вот эта правильная практика мне, как раз и не нравится. В том числе и тем, что я или должен прописать руками каждый, вектор, причем не одной строчкой, или оставить потенциальный глюкодром для неотлаженной программы. Мой вариант предполагает чисто механические действия над листингом ассемблерного примера из даташита, легко поддающиеся "механизации", собственно, я уже сочинил соответствующую программу для писюка. Я, правда, надеялся сделать вторую часть в виде макрокоманды, но, раз нельзя, буду копипастить кусочек с закомментированными заглушками и .include для генерации заглушек для тех прерываний, которые не используются.

Вариант, который предлагает Seriyvolk тоже неплох, но там нужен большой объем ручной работы и, ИМХО, мой вариант таки нагляднее. Я считаю главной ценностью своего варианта именно наличие той самой таблицы заглушек. Все прерывания на виду, не нужно помнить метку из AVR-овского инклудника. Что это за прерывание, прописано в комментарии от AVR, скопипастил куда надо из этой таблицы один элемент вместе с комментарием, закомментировал оригинал (или, наоборот, раскомментировал копию, как я сейчас предполагаю делать), и вперед. Можно, конечно, сделать нечто подобное и из того кусочка инклудника, который описывает вектора, но там надо самому сочинять метки для переходов, а так вполне информативный набор меток любезно предоставлен авторами даташита (кроме метки ADC, которую я, обычно, подправляю до iADC).

Вообще, создается впечатление, что авторы АВР Студии ничего, кроме писюка не видели, все богатство идей, реализованных в ассемблерах до-писюшных времен осталось за бортом...
Последний раз редактировалось afz Вт май 26, 2015 09:09:19, всего редактировалось 1 раз.
Кто мешает тебе выдумать порох непромокаемый? (К. Прутков, мысль № 133)
Реклама
ARV
Ум, честь и совесть. И скромность.
Аватара пользователя
Сообщения: 18787
Зарегистрирован: Чт дек 28, 2006 08:19:56
Откуда: Новочеркасск

Сообщение ARV »

успехов вам!

P.S. как бы в попытках выдумать порох непромокаемый вам не удалось выдумать порох непросыхающй :)))
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...

Мой уютный бложик... заходите!
Контактная информация:
Друг Кота
Аватара пользователя
Сообщения: 15778
Зарегистрирован: Вт мар 16, 2010 22:02:27
Откуда: ДОНЕЦК

Сообщение BOB51 »

afz писал(а): Вообще, создается впечатление, что авторы АВР Студии ничего, кроме писюка не видели, все богатство идей, реализованных в ассемблерах до-писюшных времен осталось за бортом...
ММдяааа... а у меня впечатление, что Вам не слишком хорошо сам предмет обсуждения (ассемблер АВР) известен весьма... посредственно. 8)
Все необходимое для работы там имеется. Некоторые "заковыки" вызваны структурными особенностями ядра семейства, но не более того.
:beer:
Друг Кота
Аватара пользователя
Сообщения: 6347
Зарегистрирован: Вт апр 24, 2007 07:45:40
Откуда: Minsk

Сообщение Jack_A »

ARV писал(а):вы же слыхали про магические числа и их вред в программировании? так вот, фиксированные адреса - это магические числа.
При чем тут "магические числа" ? Смешались в кучу кони, люди... Еще немного, и МК начнет по прерыванию выскакивать не на прописанный ему "железом" адрес, а на заботливо предложенное ему символьное имя. Но это уже будет следующее поколение МК со встроенным телепатором.
Кажется, я начинаю спорить . А ведь я никогда не спорю :)
И напоследок. Может, кто-то изучал МК по сказкам и слухам, а я так все больше по даташитам. И десяток успешных немаленьких проектов подтвердят, что читал ДШ я внимательно.
Break. Game over. Kondec .
ARV
Ум, честь и совесть. И скромность.
Аватара пользователя
Сообщения: 18787
Зарегистрирован: Чт дек 28, 2006 08:19:56
Откуда: Новочеркасск

Сообщение ARV »

Jack_A писал(а):При чем тут "магические числа" ?
:)))
когда вы делаете

Код: Выделить всё

.org 0
jmp start
jmp vector0
jmp vector1
...
вы жестко привязываете команду jmp vector0 к адресу, равному 0+sizeof(jmp) (если, конечно, так можно выразиться). размер команды jmp вам, условно говоря, неизвестен, так как зависит от типа МК. то есть вы получаете код, который "гуляет" по адресному пространству, а вы об этом не подозреваете даже. в один прекрасный момент вы пишите то же самое для другого МК и вдруг внезапно оказывается, то вся стройная таблица разрушена, потому что размер jmp стал не таким, как был ранее, то есть у вас обработчики прерываний будут хрен знает куда попадать, а компилятор вам даже предупреждения не выдаст.

в то же самое время в каждом описании МК, данном вам в соответствующем inc-файле, определены константы символьные, обозначающие адрес вектора прерывания (по идее, для однотипных прерываний разных МК эти символьные константы должны быть одинаковыми, хоть это и не всегда так)
то есть разработчик МК и ассемблера как бы вам намекает - используй это!

Код: Выделить всё

.org 0
jmp start

.org vector0_addr
jmp vector0

.org vector1_addr
jmp vector1

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

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

Код: Выделить всё

.org 0
jmp start

.org vector10_addr
jmp vector10

start:
и все будет правильно. более того, вы можете вдруг "вспомнить" о нужном вам векторе, и написать в любом месте перед меткой start переход на этот вектор - и снова все будет отлично!!!

Код: Выделить всё

.org 0
jmp start

.org vector10_addr
jmp vector10

.org vector3_addr
jmp vector3

start:
вы получаете вариант, за которым следит компилятор, давая вам больше свободы. пользоваться этим или нет - дело ваше, но в наставлениях по masm и tasm было строго-настрого указано, что программист обязан определять вектора прерываний исключительно при помощи директивы ORG - не надеясь на фиксированные адреса в адресном пространстве! я к этому привык еще в ту пору, и пока что ничего лучше не видел (для ассемблера).

наконец, при предлагаемом подходе вы имеете полное право делать заглушки "лишних" прерываний, например так:

Код: Выделить всё

.org vector0_addr
reti

.org vector1_addr
reti
или так:

Код: Выделить всё

.org 0
reset:
jmp start

.org vector0_addr
rjmp reset

.org vector5_addr
rjmp reset
надеюсь, вы понимаете и согласитесь, что в варианте "табличных джампов" замена jmp на reti может быть настолько черевата, что рискнувшего это сделать можно только пожалеть?

что касается самого ассемблера AVR, то из-под пера Атмела он вышел на редкость кривеньким и убогоньким, сравнивать его даже с avr-as из комплекта avr-gcc просто нельзя! макросы даже в древнейшем ассемблере для 51-ых микроконтроллеров были во много раз более эффективными!
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...

Мой уютный бложик... заходите!
Контактная информация:
Друг Кота
Аватара пользователя
Сообщения: 15778
Зарегистрирован: Вт мар 16, 2010 22:02:27
Откуда: ДОНЕЦК

Сообщение BOB51 »

Все вопросы учитывались в avrssm2...
И не столько таблица векторов.... то уже совсем примитив... всем давно приелось...
:(
Открыл глаза
Аватара пользователя
Сообщения: 73
Зарегистрирован: Сб авг 23, 2014 21:49:24

Сообщение Дима_Медвед »

Всем привет. Есть такой вопрос. Указатель Z, он ведь 16-розрадный. Значит при такой записи:
Спойлерset_frequency: ldi ZH, high(1<<speed_tabl)
ldi ZL, low(1<<speed_tabl)
ldi YH, 0
mov YH, SV
add ZL, YL
adc ZH, YH
lpm r16, high(Z)
lpm r17, low(Z)
mov speedH, r16
mov speedL, r17
rjmp main

в speedL идёт младшая часть значения с таблици, а в speedH старшая часть. Почему тогда АВРстудио не компилирует код???
таблица:
Спойлерspeed_tabl:
.dw 61629 ; 1 Sec
.dw 62019 ; 0.9 Sec
.dw 62410 ; 0.8 Sec
.dw 62800 ; 0.7 Sec
.dw 63191 ; 0.6 Sec
.dw 63581 ; 0.5 Sec
.dw 63973 ; 0.4 Sec
.dw 64363 ; 0.3 Sec
.dw 64753 ; 0.2 Sec
.dw 65144 ; 0.1 Sec
.dw 65340 ; 0.05 Sec
.dw 65437 ; 0.025 Sec
.dw 65530 ; 0.001 Sec
.dw 65535 ; 0.0005 Sec
Ах да, SV это номер значения из таблици.
Друг Кота
Аватара пользователя
Сообщения: 20117
Зарегистрирован: Чт сен 18, 2008 12:27:21
Откуда: Столица Мира Санкт-Петербург

Сообщение Gudd-Head »

Бля, так сложно что ли написать как ругается компилятор?

Код: Выделить всё

lpm r16, high(Z)
Это хуйня. Синтаксис:
LPM;
LPM Rd, Z;
LPM Rd, Z+;
на выбор.
[ Всё дело не столько в вашей глупости, сколько в моей гениальности ] [ Правильно заданный вопрос содержит в себе половину ответа ]
Держит паяльник хвостом
Сообщения: 933
Зарегистрирован: Ср апр 13, 2011 11:09:20
Откуда: Екатеринбург

Сообщение Alkul »

Дима_Медвед писал(а):Почему тогда АВРстудио не компилирует код???
Да потому, что бред Вы написали, а не код.
Вот такая запись:

Код: Выделить всё

ldi ZH, high(1<<speed_tabl)
ldi ZL, low(1<<speed_tabl)
занесет в рег.пару Z не содержимое таблицы speed_tabl, а вот здесь

Код: Выделить всё

ldi ZH, high(1<<speed_tabl)
возьмет 1, сдвинет её влево на столько раз, чему равен адрес метки speed_tabl, а потом возьмет старший байт получившегося числа и занесет его в рег. ZH.

Вот эта строчка

Код: Выделить всё

ldi ZL, low(1<<speed_tabl)
сделает все то же самое, но в рег.ZL будет помещен младший байт получившегося числа.
Как Вы думаете, какое значение в итоге занесется в рег.пару Z, если учесть, что адрес наверняка будет больше 10h?

Вот это что за команда?

Код: Выделить всё

mov YH, SV
Вы в курсе, что оператор mov копирует содержимое одного регистра в другой?

Прежде, чем начинать программировать, надо выучить язык программирования.
Последний раз редактировалось Alkul Чт май 28, 2015 14:53:19, всего редактировалось 1 раз.
Держит паяльник хвостом
Сообщения: 933
Зарегистрирован: Ср апр 13, 2011 11:09:20
Откуда: Екатеринбург

Сообщение Alkul »

Gudd-Head писал(а):Это хуйня.
Грубо, но в целом верно. :))
Друг Кота
Аватара пользователя
Сообщения: 20117
Зарегистрирован: Чт сен 18, 2008 12:27:21
Откуда: Столица Мира Санкт-Петербург

Сообщение Gudd-Head »

Должно быть как-то так:

Код: Выделить всё

ldi ZH, high(speed_tabl*2);
ldi ZL, low(speed_tabl*2);	загрузили в Z адрес таблицы
add ZL, SV;			прибавили смещение [0...255]
adc ZH, zeroreg;		прибавили к старшему байту указателя бит переноса С если есть
lpm r16, Z+;			загрузили первый байт с пост-инкрементом указателя
lpm r17, Z;		загрузили следующий байт из таблицы
[ Всё дело не столько в вашей глупости, сколько в моей гениальности ] [ Правильно заданный вопрос содержит в себе половину ответа ]
Мудрый кот
Аватара пользователя
Сообщения: 1812
Зарегистрирован: Чт июн 10, 2010 08:55:35
Откуда: Сибирские Афины

Сообщение Kavka »

Gudd-Head, там, в таблице, вроде, два байта на число. Смещение подкоректировть надо будет.
Ну да ладно, пусть автор вопроса додумает хоть что-то сам... :)

Дима_Медвед, настоятельно рекомендую ознакомиться со следующим документом: Atmel AVR 8-bit Instruction Set.
Если "нихт парле инглиш" :) , то вот. Но это не первоисточник.
Когда уже ничего не помогает - прочтите, наконец, инструкцию.
Лучший оптимизатор находится у вас между ушей. (Майкл Абраш, программист Quake и QuakeII)
Избыток информации ведёт к оскудению души - Леонтьев А. (сказано в 1965 г.)
Друг Кота
Аватара пользователя
Сообщения: 20117
Зарегистрирован: Чт сен 18, 2008 12:27:21
Откуда: Столица Мира Санкт-Петербург

Сообщение Gudd-Head »

Kavka писал(а):там, в таблице, вроде, два байта на число.
Ну да, смещение сделать чётным.
[ Всё дело не столько в вашей глупости, сколько в моей гениальности ] [ Правильно заданный вопрос содержит в себе половину ответа ]
Родился
Сообщения: 3
Зарегистрирован: Вс дек 23, 2012 12:36:11

Сообщение Programmer86 »

Здравствуйте, коты! Прошу вас сразу не ругаться, я понимаю что код ну очень кривой. Я раньше с асм не общаялся.
Я написал прошивку для ATmega8A-PU, которая должна управлять серво-приводами с ПК. Не использовал готовые библиотеки, чтоб как бы посмотреть на все изнутри. Все вроде работает, но через какое-то время серво-приводы пересатют работать. Они все также удерживают свою позицию(рукой не крутятся, сопротивляются), но перестают реагировать на команды с ПК. Код под спойлером. Также приложил архив с проектом в AtmelStudio, т.к. код под спойлером получается не структурированным.
Не много про то как это работает. С компьютера посылаются 2 байта:
1) Первый байт это номер команды. Но до команд я не дошёл, по этому это попросту номер сервы.
2 ) Это как бы угол, отклонения сервы.
После этого, команда посылается обратно в компьютер, для проверки, того что принял МК. Вот когда зависат МК, то всеравно ответ от МК приходит.
Код писал, давненько, уже сам по забывал откуда некоторые числа. Ну там некоторые числа подобранны опытным путем.

Вы меня подтолкните, что может быть, я сам подправлю код.
Спойлер/*
* AssemblerApplication2.asm
*
* Created: 07.02.2015 14:12:09
* Author: ?????
*/

.include "m8Adef.inc"

.equ XTAL =1000000
.equ Baud_Rate = 4800
.equ Baud_Divider = XTAL/(16*Baud_Rate)-1
.equ MaxAngle = 233

.equ SubAngle = 255 - MaxAngle - 1

.def Temp = R16
.def Temp1 = R17
.def Temp2 = R18
.def Temp3 = R19
.def Data1 = R20
.def Data2 = R21
.def Servo1 = R22
.def Servo2 = R23
.cseg
.org 0

;Вектора прерываний
RJMP EXT_MAIN
RJMP EXT_INT0
RJMP EXT_INT1
RJMP EXT_TIMER2_COMP
RJMP EXT_TIMER2_OVF
RJMP EXT_TIMER1_CAPT
RJMP EXT_TIMER1_COMPA
RJMP EXT_TIMER1_COMPB
RJMP EXT_TIMER1_OVF
RJMP EXT_TIMER0_OVF
RJMP EXT_SPI_STC
RJMP EXT_USART_RXC
RJMP EXT_USART_UDRE
RJMP EXT_USART_TXC
RJMP EXT_ADC
RJMP EXT_EE_RDY
RJMP EXT_ANA_COMP
RJMP EXT_TWI
RJMP EXT_SPM_RDY

;-------------------------------------------------- функция
EXT_MAIN:
;Инициализируем стек
LDI Temp, low(RAMEND)
OUT SPL, Temp
LDI Temp, high(RAMEND)
OUT SPH, Temp

;Настраиваем наш МК
RCALL UART_INIT

;Настраиваем порт С на выход
ldi Temp1, 0b11111111
out DDRC, Temp1
ldi Temp1, 0b00000000
out PortC, Temp1

;Сбрасываеп переменные, устанавливаем начальный угол серв
LDI Data1, 0
LDI Data2, 0
LDI Servo1, 0x94 ; как бы "угол сервы" в диапозоне: 41-254
LDI Servo2, 0x94

Begin:
;-------------------Первая серва
ldi Temp1, 0b000101
out PortC, Temp1

MOV Temp1, Servo1
Loop_1: dec Temp1
brne Loop_1
MOV Temp1, Servo1
Loop2_1: dec Temp1
brne Loop2_1
MOV Temp1, Servo1
Loop3_1: dec Temp1
brne Loop3_1

ldi Temp1, 0b00000000
out PortC, Temp1

SEI

ldi Temp1,60
ldi Temp2,11
Loop4_1: dec Temp1
brne Loop4_1

dec Temp2
brne Loop4_1

MOV Temp1, Servo1
COM Temp1
SUBI Temp1, SubAngle
Loop_2: dec Temp1
brne Loop_2
MOV Temp1, Servo1
COM Temp1
SUBI Temp1, SubAngle
Loop2_2: dec Temp1
brne Loop2_2
MOV Temp1, Servo1
COM Temp1
SUBI Temp1, SubAngle
Loop3_2: dec Temp1
brne Loop3_2

CLI

;-------------------Вторая серва
ldi Temp1, 0b000110
out PortC, Temp1

MOV Temp1, Servo2
Loop_3: dec Temp1
brne Loop_3
MOV Temp1, Servo2
Loop2_3: dec Temp1
brne Loop2_3
MOV Temp1, Servo2
Loop3_3: dec Temp1
brne Loop3_3

ldi Temp1, 0b00000100

SEI

out PortC, Temp1

ldi Temp1,60
ldi Temp2,11
Loop4_2: dec Temp1
brne Loop4_2

dec Temp2
brne Loop4_2

MOV Temp1, Servo2
COM Temp1
SUBI Temp1, SubAngle
Loop_4: dec Temp1
brne Loop_4
MOV Temp1, Servo2
COM Temp1
SUBI Temp1, SubAngle
Loop2_4: dec Temp1
brne Loop2_4
MOV Temp1, Servo1
COM Temp1
SUBI Temp1, SubAngle
Loop3_4: dec Temp1
brne Loop3_4
; Начинаем все с начала

CLI

rjmp Begin

LDI Temp1, 0x00
;--------------------------------------------------
EXT_INT0:
EXT_INT1:
EXT_TIMER2_COMP:
EXT_TIMER2_OVF:
EXT_TIMER1_CAPT:
EXT_TIMER1_COMPA:
EXT_TIMER1_COMPB:
EXT_TIMER1_OVF:
EXT_TIMER0_OVF:
EXT_SPI_STC:
;-------------------------------------------------- по приему байта
EXT_USART_RXC:
CLI
CPI Data1, 0
BRNE Set_Data_2
Set_Data_1:
IN Data1, UDR
SEI
RET
Set_Data_2:
IN Data2, UDR
RCALL Read_COMMAND
RET
;--------------------------------------------------
EXT_USART_UDRE:
EXT_USART_TXC:
EXT_ADC:
EXT_EE_RDY:
EXT_ANA_COMP:
EXT_TWI:
EXT_SPM_RDY:

;Вспомогательные функции
;--------------------------------------------------
UART_INIT:
LDI R16, low(Baud_Divider)
OUT UBRRL,R16
LDI R16, high(Baud_Divider)
OUT UBRRH,R16
LDI R16,0
OUT UCSRA, R16
LDI R16, (1 << RXEN)|(1 << TXEN)|(1 << RXCIE)|(0 << TXCIE) ; Прерывание по приему разрешенно, по передаче запрещены, прием-передача разрешен.
OUT UCSRB, R16
LDI R16, (1 << URSEL)|(1 << UCSZ0)|(1 << UCSZ1) ; Формат кадра - 8 бит, пишем в регистр UCSRC, за это отвечает бит селектор
OUT UCSRC, R16
ldi R16, 1
RET
;--------------------------------------------------

;--------------------------------------------------
READ_COMMAND:
uart_snt:
SBIS UCSRA,UDRE
RJMP uart_snt
OUT UDR, Data1
uart_snt2:
SBIS UCSRA,UDRE
RJMP uart_snt2
OUT UDR, Data2

CPI Data1, 0
BREQ END_READ_COMMAND

CPI Data1, 1
BREQ Set_Servo_1

CPI Data1, 2
BREQ Set_Servo_2

rjmp END_READ_COMMAND
Set_Servo_1:
MOV Servo1, Data2
rjmp END_READ_COMMAND
Set_Servo_2:
MOV Servo2, Data2
rjmp END_READ_COMMAND

END_READ_COMMAND:
LDI Data1, 0
LDI Data2, 0
SEI
RET
;--------------------------------------------------

LDI Temp1, 0x00
LDI Temp2, 0x00
LDI Temp3, 10
inc R16

;Loop: dec Temp1
; brne Loop

; dec Temp2
; brne Loop

; dec Temp3
; brne Loop
Вложения
USART_SERVO.rar
(20.32 КБ) 129 скачиваний
Последний раз редактировалось Programmer86 Пт май 29, 2015 15:29:06, всего редактировалось 1 раз.
Друг Кота
Аватара пользователя
Сообщения: 20117
Зарегистрирован: Чт сен 18, 2008 12:27:21
Откуда: Столица Мира Санкт-Петербург

Сообщение Gudd-Head »

Окуеть. Целых 2 комментария :)))
[ Всё дело не столько в вашей глупости, сколько в моей гениальности ] [ Правильно заданный вопрос содержит в себе половину ответа ]
Ответить

Вернуться в «AVR»