|
Как написать код на ассемблере AVR-на "С"-понятно. |
|
|
|
Sep 20 2013, 07:18
|
Участник

Группа: Участник
Сообщений: 29
Регистрация: 25-01-13
Из: Брянск
Пользователь №: 75 345

|
Здравствуйте.Подскажите пожалуйста.Вот код на Си -здесь всё понятно. if (u > 256) // 1.25V PORTD = 0b00000011; if (u > 384) // 1.875V PORTD = 0b00000111 А вот как реализовать на ассемблере,дело в том ,что переменная-"u"-это двухбайтное число(10 разрядов) у меня это регистры АЦП-ADCL , ADCH. И если не трудно подскажите ,что сделал автор в 23 строке своей программы u = (ADCL|ADCH << 8);-взято отсюда http://radioparty.ru/index.php/prog-avr/pr...adc-avr?start=1Если можно то подробнее.Спасибо.
|
|
|
|
|
Sep 20 2013, 07:32
|

Беспросветный оптимист
     
Группа: Свой
Сообщений: 4 640
Регистрация: 26-12-07
Из: Н.Новгород
Пользователь №: 33 646

|
Цитата(serj32 @ Sep 20 2013, 10:18)  И если не трудно подскажите ,что сделал автор в 23 строке своей программы u = (ADCL|ADCH << 8);-взято отсюда Код u = (ADCL|ADCH << 8); // Считываем ADC Считал два 8-разрядных регистра и составил из них 16р слово
--------------------
Программирование делится на системное и бессистемное. ©Моё :) — а для кого-то БГ — это Bill Gilbert =)
|
|
|
|
|
Sep 20 2013, 08:23
|
Участник

Группа: Участник
Сообщений: 29
Регистрация: 25-01-13
Из: Брянск
Пользователь №: 75 345

|
Цитата(MrYuran @ Sep 20 2013, 11:32)  Код u = (ADCL|ADCH << 8); // Считываем ADC Считал два 8-разрядных регистра и составил из них 16р слово Вот два регистра ADCL и ADCH они восьмиразрядные ну произведём над этими регистрами операцию побитового ИЛИ и получим результат -восьмиразрядное число,а ещё сдвинем влево на 8 разрядов результат-ну вообще все нули получатся-совсем я запутался.
|
|
|
|
|
Sep 20 2013, 09:42
|

Беспросветный оптимист
     
Группа: Свой
Сообщений: 4 640
Регистрация: 26-12-07
Из: Н.Новгород
Пользователь №: 33 646

|
Цитата(serj32 @ Sep 20 2013, 11:23)  Вот два регистра ADCL и ADCH они восьмиразрядные ну произведём над этими регистрами операцию побитового ИЛИ и получим результат -восьмиразрядное число,а ещё сдвинем влево на 8 разрядов результат-ну вообще все нули получатся-совсем я запутался. Вы не учитываете приоритет операций. У сдвига он выше. Итого, старший регистр сдвинется на 8 влево, сложится с младшим и результат запишется в результирующую переменную.
--------------------
Программирование делится на системное и бессистемное. ©Моё :) — а для кого-то БГ — это Bill Gilbert =)
|
|
|
|
|
Sep 20 2013, 10:02
|
Участник

Группа: Участник
Сообщений: 29
Регистрация: 25-01-13
Из: Брянск
Пользователь №: 75 345

|
Цитата(adnega @ Sep 20 2013, 12:47)  Подразумевается, что ADCH перед сдвигом копируется во временную переменную с расширением типа. Вопрос только какого? Видимо, типа как и "u"? Как я понимаю по строке 23 программы u = (ADCL|ADCH << 8);-взято отсюда http://radioparty.ru/index.php/prog-avr/pr...adc-avr?start=1Пусть например АЦП выдало результат преобразования число 1001. 0b1111101001 -число 1001 в двоичной это число будет находиться в регистрах ADCL и ADCH тогда соответственно ADCL=0b11101001 в этом регистре младшие разряды ADCH=0b00000011 в этом регистре старшие разряды То в коде u = (ADCL|ADCH << 8) следующее: В регистре ADCH будет 16 разрядное число - 0b0000000000000011 когда поизведём сдвиг влево на 8 разрядов ADCH << 8 то получим 0b0000001100000000 далее в ADCL у нас число 0b0000000011101001 произведя операцию поразрядного ИЛИ над числами 0b0000000011101001 и 0b0000001100000000 мы получаем в переменной "u" одно 16 разр.число u=0b0000001111101001 Это и есть число 1001 и теперь с ним можно работать. Правильно ли я написал.Спасибо.
|
|
|
|
|
Sep 20 2013, 10:51
|
Участник

Группа: Участник
Сообщений: 29
Регистрация: 25-01-13
Из: Брянск
Пользователь №: 75 345

|
Цитата(V_G @ Sep 20 2013, 14:29)  Вероятно, можно поступить проще, если повнимательней разобраться в сути неравенств из первого поста. Однозначно нижеприведенный вариант будет работать, если неравенства нестрогие (>=) 1. В настройке AЦП включить бит ADLAR (выравнивание результата по левому краю), результат сдвинется влево на 6 разрядов 2. Сравнивать только ADCH с 0x40 и с 0x60 В смысле работать с восьмиразрядным числом потеряв 2 младших разряда.А вот это мне непонятно-с 0x40 и с 0x60 Это маска?
|
|
|
|
|
Sep 20 2013, 16:58
|
Участник

Группа: Участник
Сообщений: 29
Регистрация: 25-01-13
Из: Брянск
Пользователь №: 75 345

|
Очевидно чтобы реализовать Си код if (u > 256) // 1.25V PORTD = 0b00000011; if (u > 384) // 1.875V PORTD = 0b00000111 на ассемлере будут команды : cp breq brcs Переменная "u"-это два байта-регистры-ADCL и ADCH. А константы 256 и 384 необходимо разбить на двухбайтные числа у нас будут старший и младший байт числа. Дальше необходимо сравнивать вначале младшие байты затем старшие и т.д и ничего не понимаю. Рад буду всем откликнувшимся.Спасибо.
|
|
|
|
|
Sep 20 2013, 19:56
|
Участник

Группа: Участник
Сообщений: 29
Регистрация: 25-01-13
Из: Брянск
Пользователь №: 75 345

|
Цитата(zombi @ Sep 20 2013, 22:56)  Сравнивайте старшие, а младшие только если старшие равны.
ЗЫ: У Вас оба сравнения ">" так должно быть? Здравствуйте.Да действительно">" так должно-это я пытаюсь отсюда http://electronix.ru/redirect.php?http://r...adc-avr?start=1Си код под ассемблер переделать.Вот я немного попытался написать код-проверьте пожалуйста. .include "m8def.inc" .def temp1 = R16 .def temp2 = R17 .equ cons1 = 256 .equ cons2 = 384 ;----вершина стека , инициализация портов,АЦП и т.д in temp1,ADCL ;младший байт результата АЦП in temp2,ADCH ;старший.................АЦП cp temp1,low(cons1) ;сравниваем ADCL с младшим байтом константы 256 brcs metka ;если temp1 > low(cons1) флага С не будет и переход не произойдёт cp temp2,high(cons1) ;тогда начинаем проверять старшие байты brcs metka out PORTD,0b00000011 cp temp1,low(cons2) brcs metka cp temp2,high(cons2) brcs metka out PORTD,0b00000111
Сообщение отредактировал serj32 - Sep 21 2013, 07:38
|
|
|
|
|
Sep 20 2013, 20:15
|

Гуру
     
Группа: Свой
Сообщений: 2 076
Регистрация: 10-09-08
Пользователь №: 40 106

|
Ход примерно правильный. Но!!! Я же уже писал что сперва нужно старшие байты сравнивать, а младшие только в случае равенства старших! Для сравнения регистра с константой команда CPI Цитата(serj32 @ Sep 20 2013, 22:56)  Да действительно">" так должно-это я пытаюсь отсюда ... Cыль не открывается Т.е. если значение АЦП больше 384 то пин D2 , за время выполнения этого кода, поменяет свое состояние дважды.
|
|
|
|
|
Sep 21 2013, 15:56
|
;
     
Группа: Участник
Сообщений: 5 646
Регистрация: 1-08-07
Пользователь №: 29 509

|
Цитата(zombi @ Sep 20 2013, 23:15)  Ход примерно правильный. Но!!! Я же уже писал что сперва нужно старшие байты сравнивать, а младшие только в случае равенства старших! Не учите людей плохому  Код ldi zL,low(constant1) ; загрузки по нормальному оформляют в виде макроса ldi zH,high(constant1);
in temp1,ADCL in temp2,ADCH cp temp1,zL cpc temp2,zH brge kakaya_to_metka; или brlo или что там еще Итд в таком же духе Авровский асм имеет много псевдонимов у команд, но они хорошо отражают смысл того, что происходит, поэтому можно не стесняться
|
|
|
|
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|