реклама на сайте
подробности

 
 
> Вывод 2 байтов АЦП в одну переменную, ATMega 2561 - как считать ADCH:ADCL одним числом?
Slavast
сообщение Feb 7 2011, 09:52
Сообщение #1


Частый гость
**

Группа: Участник
Сообщений: 81
Регистрация: 25-10-10
Пользователь №: 60 395



Всем Доброго!
Atmega 2561. 1024 разрядный АЦП.
Мах значение на АЦП 0x03FF:
ADCH 0000.0011
ADCL 1111.1111
Хочу прочитать в одну переменную значение регистров АЦП ADCH и ADCL! Как в Си в старший разряд 2-байтовой переменной загнать значение ADCH, а в младший разряд - значение ADCL? Может есть какая-то команда сдвига внутри переменной, которую я никак не найду?
Ведь просто сложить ADCH и ADCL в одну переменную нельзя, т.к. мы нарушим паритет разрядности! (03+FF не будет равно 03FF)
Благодарю!
Go to the top of the page
 
+Quote Post
2 страниц V   1 2 >  
Start new topic
Ответов (1 - 21)
Alex_1811
сообщение Feb 7 2011, 10:15
Сообщение #2


Частый гость
**

Группа: Участник
Сообщений: 178
Регистрация: 31-10-06
Из: Яблунець
Пользователь №: 21 821



=ADCH<<8+ADCL
Go to the top of the page
 
+Quote Post
Сергей Борщ
сообщение Feb 7 2011, 10:31
Сообщение #3


Гуру
******

Группа: Модераторы
Сообщений: 8 455
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095



Alex_1811 подсказал, как сделать то, что вы хотите. Но хотите ли вы это делать? Посмотрите внимательно заголовочный файл для вашего процессора, обратите внимание на sfr с именем ADC.


--------------------
На любой вопрос даю любой ответ
"Write code that is guaranteed to work, not code that doesn’t seem to break" (C++ FAQ)
Go to the top of the page
 
+Quote Post
777777
сообщение Feb 7 2011, 11:00
Сообщение #4


Профессионал
*****

Группа: Участник
Сообщений: 1 091
Регистрация: 25-07-07
Из: Саратов
Пользователь №: 29 357



Цитата(Alex_1811 @ Feb 7 2011, 13:15) *
=ADCH<<8+ADCL

Так делать нельзя потому что читать нужно сначала ADCL, а потом ADCH, а какой код сгенерирует компилятор никто не гарантирует.

Нужно писать val = ADC; в этом случае компилятор сгенерирует чтение в правильной последовательности.
Go to the top of the page
 
+Quote Post
defunct
сообщение Feb 7 2011, 12:50
Сообщение #5


кекс
******

Группа: Свой
Сообщений: 3 825
Регистрация: 17-12-05
Из: Киев
Пользователь №: 12 326



Цитата(Alex_1811 @ Feb 7 2011, 12:15) *
=ADCH<<8+ADCL

Если написать так как вы советуете получите такую последовательность действий:

= ADCH << (8 + ADCL);
Go to the top of the page
 
+Quote Post
Slavast
сообщение Feb 11 2011, 08:08
Сообщение #6


Частый гость
**

Группа: Участник
Сообщений: 81
Регистрация: 25-10-10
Пользователь №: 60 395



Спасибо!
Получилось a=ADC!
Go to the top of the page
 
+Quote Post
firstvald
сообщение Feb 11 2011, 08:20
Сообщение #7


Знающий
****

Группа: Свой
Сообщений: 580
Регистрация: 3-06-08
Пользователь №: 38 041



вот несколько по другому:

adc=ADCL+ADCH*0x100;

кстати, компилятор запросто может один и тот же код сгенерировать и для этого и для варианта со сдвигом.
Go to the top of the page
 
+Quote Post
_Pasha
сообщение Feb 11 2011, 08:40
Сообщение #8


;
******

Группа: Участник
Сообщений: 5 646
Регистрация: 1-08-07
Пользователь №: 29 509



Цитата(firstvald @ Feb 11 2011, 12:20) *
вот несколько по другому:

вот несколько по-третьему
Код
val=ADCL;
val |= (uint16_t)ADCH<<8;

В отличие от . - сохраняет правильный порядок и не содержит ошибки с приведением типов.
Go to the top of the page
 
+Quote Post
demiurg_spb
сообщение Feb 11 2011, 09:01
Сообщение #9


неотягощённый злом
******

Группа: Свой
Сообщений: 2 746
Регистрация: 31-01-08
Из: Санкт-Петербург
Пользователь №: 34 643



Народ! Это же стандартная фишка для AVR!
Ну напишите макрос или инлайн вставку на асме и будет счастье!
Зачем всякий раз писать эту каку???


--------------------
“Будьте внимательны к своим мыслям - они начало поступков” (Лао-Цзы)
Go to the top of the page
 
+Quote Post
Палыч
сообщение Feb 11 2011, 15:02
Сообщение #10


Гуру
******

Группа: Свой
Сообщений: 2 399
Регистрация: 10-05-06
Из: г. Новочеркасск
Пользователь №: 16 954



Цитата(demiurg_spb @ Feb 11 2011, 12:01) *
Ну напишите макрос или инлайн вставку на асме и будет счастье!
Зачем это делать? Просто нужно усвоить/запомнить, что к шестнадцатибитным регистрам нужно обращаться по их именам, а не побайтно!
Go to the top of the page
 
+Quote Post
demiurg_spb
сообщение Feb 11 2011, 15:12
Сообщение #11


неотягощённый злом
******

Группа: Свой
Сообщений: 2 746
Регистрация: 31-01-08
Из: Санкт-Петербург
Пользователь №: 34 643



Цитата(Палыч @ Feb 11 2011, 18:02) *
Зачем это делать? Просто нужно усвоить/запомнить, что к шестнадцатибитным регистрам нужно обращаться по их именам, а не побайтно!
Это разумеется - компилятор обучен порядку чтения-записи слов.
Но бывает так, что старший и младший байты слова располагаются в памяти не в соседних ячейках.
Поубивал бы...


--------------------
“Будьте внимательны к своим мыслям - они начало поступков” (Лао-Цзы)
Go to the top of the page
 
+Quote Post
_Pasha
сообщение Feb 11 2011, 15:54
Сообщение #12


;
******

Группа: Участник
Сообщений: 5 646
Регистрация: 1-08-07
Пользователь №: 29 509



Цитата(demiurg_spb @ Feb 11 2011, 18:12) *
Но бывает так, что старший и младший байты слова располагаются в памяти не в соседних ячейках.
Поубивал бы...

+1 или за UART_RX_vect, USART_RX_vect, UART_RX_vect - приходится костылями обзаводиться.
Go to the top of the page
 
+Quote Post
arttab
сообщение Feb 12 2011, 03:47
Сообщение #13


Профессионал
*****

Группа: Свой
Сообщений: 1 432
Регистрация: 7-12-04
Из: Новосибирск
Пользователь №: 1 371



а если создать в озу указатель на регистровую пару ADCL ADCH типа int? для флешь и озу это нормально, а тут сообразить не могу.


--------------------
OrCAD, Altium,IAR, AVR....
Go to the top of the page
 
+Quote Post
demiurg_spb
сообщение Feb 12 2011, 08:10
Сообщение #14


неотягощённый злом
******

Группа: Свой
Сообщений: 2 746
Регистрация: 31-01-08
Из: Санкт-Петербург
Пользователь №: 34 643



Код
uint16_t* pADC = &ADC;
Вы об этом?

Цитата(_Pasha @ Feb 11 2011, 18:54) *
+1 или за UART_RX_vect, USART_RX_vect, UART_RX_vect - приходится костылями обзаводиться.
Да с U(S)ART'ами та ещё песня. Ну почему бы всегда не давать им номер?
Пусть будет под номером 0, даже если он один одинёшенек.
Что-то размечтался я:-)


--------------------
“Будьте внимательны к своим мыслям - они начало поступков” (Лао-Цзы)
Go to the top of the page
 
+Quote Post
_Pasha
сообщение Feb 12 2011, 10:30
Сообщение #15


;
******

Группа: Участник
Сообщений: 5 646
Регистрация: 1-08-07
Пользователь №: 29 509



Цитата(demiurg_spb @ Feb 12 2011, 11:10) *
Код
uint16_t* pADC = &ADC;
Вы об этом?

Он об этом - дык там всегда чтение младший-старший, запись старший-младший. А шо тут думать?
Go to the top of the page
 
+Quote Post
OlegNZH
сообщение Feb 12 2011, 18:08
Сообщение #16


Участник
*

Группа: Участник
Сообщений: 46
Регистрация: 19-11-08
Пользователь №: 41 782



Цитата(_Pasha @ Feb 12 2011, 13:30) *
Он об этом - дык там всегда чтение младший-старший, запись старший-младший. А шо тут думать?

А шо туть думать ? А если подумать?
Цитата
Практическая полезность представления результата с выравниванием слева существует, когда достаточно 8-разрядное разрешение, т.к. в этом случае необходимо считать только регистр ADCH. В другом же случае необходимо первым считать содержимое регистра ADCL, а затем ADCH, чем гарантируется, что оба байта являются результатом одного и того же преобразования. Как только выполнено чтение ADCL блокируется доступ к регистрам данных со стороны АЦП. Это означает, что если считан ADCL и преобразование завершается перед чтением регистра ADCH, то ни один из регистров не может модифицироваться и результат преобразования теряется. После чтения ADCH доступ к регистрам ADCH и ADCL со стороны АЦП снова разрешается.
Конец цитаты.

"...то ни один из регистров не может модифицироваться и результат преобразования теряется...." вот здесь скорее всего некорректно- "...то ни один из регистров не может модифицироваться и результат преобразования не должен потеряться". ИМХО (не проверял- просто - логика)
upd. Задело меня что-то - АЦП - последовательного приближения - старший байт - первый- рабочий ...Он - самый живой должен быть "и преобразование завершается перед чтением регистра ADCH" да есть уже в Н байт! L- вторично!


Сообщение отредактировал OlegNZH - Feb 12 2011, 18:15
Go to the top of the page
 
+Quote Post
demiurg_spb
сообщение Feb 12 2011, 21:00
Сообщение #17


неотягощённый злом
******

Группа: Свой
Сообщений: 2 746
Регистрация: 31-01-08
Из: Санкт-Петербург
Пользователь №: 34 643



Ничего не понял из написанного Вами, может это после 6-ти рабочих дней...
Что конкретно Вам не понятно или с чем Вы не согласны?


--------------------
“Будьте внимательны к своим мыслям - они начало поступков” (Лао-Цзы)
Go to the top of the page
 
+Quote Post
OlegNZH
сообщение Feb 13 2011, 08:39
Сообщение #18


Участник
*

Группа: Участник
Сообщений: 46
Регистрация: 19-11-08
Пользователь №: 41 782



Цитата(demiurg_spb @ Feb 13 2011, 01:00) *
Ничего не понял из написанного Вами, может это после 6-ти рабочих дней...
Что конкретно Вам не понятно или с чем Вы не согласны?

я просто развернул предыдущее сообщение - по поводу- кто старшее... младший-старший - это просто перевод из даташита- как нужно обращаться с байтами АЦП , ничего более.
Go to the top of the page
 
+Quote Post
ae_
сообщение Feb 13 2011, 11:40
Сообщение #19


Участник
***

Группа: Свой
Сообщений: 462
Регистрация: 2-04-07
Из: Иркутск
Пользователь №: 26 695



Цитата(OlegNZH @ Feb 13 2011, 02:08) *
А шо туть думать ? А если подумать?
...то ни один из регистров не может модифицироваться и результат преобразования теряется...." вот здесь скорее всего некорректно...

Код, написанный программистом, наконец-то удосужился прочитать результат (не)давнего измерения ADC, и, согласно документации, начинает с младшего байта, читает ADCL.
В этот момент, ВНЕЗАПНО, завершается новое измерение ADC.
Чтобы не пугать программиста, МК не перезаписывает новое значение в ADCH, давая завершить начатую программистом операцию чтения предыдущего значения ADC, что бы не получилось ADCH(от нового измерения)+ADCL(от предыдущего измерения).
Что здесь некорректно?
Go to the top of the page
 
+Quote Post
_Pasha
сообщение Feb 14 2011, 07:54
Сообщение #20


;
******

Группа: Участник
Сообщений: 5 646
Регистрация: 1-08-07
Пользователь №: 29 509



Цитата(OlegNZH @ Feb 13 2011, 12:39) *
я просто развернул предыдущее сообщение

Херовенько развернули. sad.gif
Для того, чтобы не задаваться вопросом, как и куда пишутся/читаются переменные типа 16-бит, раз и навсегда принято правило, чтобы не было конфуза при обращении к SFR
Go to the top of the page
 
+Quote Post
777777
сообщение Feb 14 2011, 10:21
Сообщение #21


Профессионал
*****

Группа: Участник
Сообщений: 1 091
Регистрация: 25-07-07
Из: Саратов
Пользователь №: 29 357



Цитата(demiurg_spb @ Feb 11 2011, 12:01) *
Народ! Это же стандартная фишка для AVR!
Ну напишите макрос или инлайн вставку на асме и будет счастье!
Зачем всякий раз писать эту каку???

Народ, я с вас худею. После того, как топикстартер ответил, что он написал a=ADC и у него все получилось, вы накидали еще страницу советов, причем каждый следующий более идиотский чем предыдущий. На хера, объясните мне, писать асмовую вставку, если можно написать a=ADC ?!
Go to the top of the page
 
+Quote Post
demiurg_spb
сообщение Feb 14 2011, 11:44
Сообщение #22


неотягощённый злом
******

Группа: Свой
Сообщений: 2 746
Регистрация: 31-01-08
Из: Санкт-Петербург
Пользователь №: 34 643



Перечитайте внимательно еще раз, а уже потом материтесь...
Умный и вежливый Вы наш!


--------------------
“Будьте внимательны к своим мыслям - они начало поступков” (Лао-Цзы)
Go to the top of the page
 
+Quote Post

2 страниц V   1 2 >
Closed TopicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 22nd June 2025 - 01:46
Рейтинг@Mail.ru


Страница сгенерированна за 0.01596 секунд с 7
ELECTRONIX ©2004-2016