Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: АЦП PIC16F877 для новичков
Форум разработчиков электроники ELECTRONIX.ru > Сайт и форум > В помощь начинающему > MCS51, AVR, PIC, STM8, 8bit
студент ю
Я новичок в универе учился на пиках, конкретно на PIC16F877. Так как знания поверхностные то пытаюсь сам докопаться до истины, а чтоб конкретно докопаться решил сделать что то типа реле напряжения, вобщем устройство работает следующим образом АЦП меряет все время напряжение и заносит результат в регистры (AdresL) и (AdresH), только я не пойму если АЦП 10-разрядное (десятичное число выглядит как 1023) то как записывается туда результат. У меня два предположения либо поровну, 512 в регистр (AdresL) и 512 (AdresH) если сложить два регистра то получим 1024, либо восемь разрядов лежат в регистре (00000000 AdresL), а остальные два в регистре (00 AdresH) если их сложить, то получим 10 разрядное число = 1023. Я не знаю какое рассуждение правильное. И так к нашему заданию, АЦП меряет напряжение и у меня есть некое измеренное число (результат измерения). И есть некая константа даже две, я не знаю как в программе написать условие, если результат измерения меньше числа .106, то на одном из выходов порта D установить ноль, если больше то пусть там сохраняется единица. И второе условие если результат измерения больше чем число .145 то на одном из выводов порта D установить ноль, иначе должно все время присутствовать единица.
Вот это равенство я не могу представить программно как сравнить одно с другим. Пишу на ассемблере, очень прошу помощи.
Allregia
Цитата(студент ю @ Nov 22 2011, 15:45) *
Я новичок в универе учился на пиках, конкретно на PIC16F877. Так как знания поверхностные то пытаюсь сам докопаться до истины, а чтоб конкретно докопаться решил сделать что то типа реле напряжения, вобщем устройство работает следующим образом АЦП меряет все время напряжение и заносит результат в регистры (AdresL) и (AdresH), только я не пойму если АЦП 10-разрядное (десятичное число выглядит как 1023) то как записывается туда результат. У меня два предположения либо поровну, 512 в регистр (AdresL) и 512 (AdresH) если сложить два регистра то получим 1024, либо восемь разрядов лежат в регистре (00000000 AdresL), а остальные два в регистре (00 AdresH) если их сложить, то получим 10 разрядное число = 1023.


Именно так - в ADRESL младнмй байт, в ADRESH - станший.
Толко если мне память не изменяет, то в конфигурации АЦП есть битик. определяющий левое или правое выравнивание, и биты могут располагаться так при правом выравнивании:
b7 b6 b5 bh4 b3 b2 b1 b0 = ADRESL
0 0 0 0 0 0 b9 b8 = ADRESH

а при левом:
b1 b0 0 0 0 0 0 0 = ADRESL
b9 b8 b7 b6 b5 b4 b3 b2 = ADRESH

Левое хорошо когда достаточно 8-битного результата, тогда просто работаем с ADRESH а ADRESL игнорируем.

А правое легко преобразуется в 2-х байтную переменную:
int ADC;

ADC = 256u*ADRESH + ADRESL;


Цитата
Я не знаю какое рассуждение правильное. И так к нашему заданию, АЦП меряет напряжение и у меня есть некое измеренное число (результат измерения). И есть некая константа даже две, я не знаю как в программе написать условие, если результат измерения меньше числа .106, то на одном из выходов порта D установить ноль, если больше то пусть там сохраняется единица.


if(ADC<106) PD0 =0; else PD0=1;

или что тоже самое:
PD0= (ADC<106) ? 0 : 1 ;

Цитата
И второе условие если результат измерения больше чем число .145 то на одном из выводов порта D установить ноль, иначе должно все время присутствовать единица.


аналогично:

if (ADC > 145) PD1 = 0; else PD1=1;

Цитата
Вот это равенство я не могу представить программно как сравнить одно с другим.


Вычесть одно из другого и посмотреть на знак результата.

Цитата
Пишу на ассемблере, очень прошу помощи.


Учи Си....
esaulenka
Цитата(студент ю @ Nov 22 2011, 17:45) *
... PIC16F877...
АЦП меряет все время напряжение и заносит результат в регистры (AdresL) и (AdresH), только я не пойму если АЦП 10-разрядное (десятичное число выглядит как 1023) то как записывается туда результат.

Об этом вполне доступно написано в документации ( http://ww1.microchip.com/downloads/en/devicedoc/30292c.pdf ).
Если в регистре ADCON1 7-й бит - единичка, результат выравнивается вправо:
ADRESH ADRESL
000000xx xxxxxxxx
если наоборот, 7-й бит - ноль, результат выравнивается влево:
ADRESH ADRESL
xxxxxxxx xx000000

Цитата(студент ю @ Nov 22 2011, 17:45) *
...если результат измерения меньше числа .106, то ...

Есть много вариантов. Самый простой вариант - предположим, что АЦП 8-битное. Тогда и результат, и граничные значения влезают в регистр, с ними удобно работать. Для этого надо выровнять результат влево и пользоваться только ADRESH, игнорируя младшие биты в ADRESL.

Второй вариант - рассматривать надо обе "половинки" числа. Ассембер пиков я тоже крайний раз видел в институте, поэтому только в общих словах:
берём старшие части результата и границы; получаем три (в общем случае) варианта
- старшая часть результата больше. Значит, весь результат тоже больше границы
- старшая часть результата меньше. Соответственно, всё значение также меньше границы.
- старшие части равны. Надо рассматривать младшие части, там тоже будет три варианта.
Для этого алгоритма, мне кажется, удобнее выравнивать результат АЦП вправо.

PS а самое удобное - доверить компилятору Си "склеить" эти результаты в одно 16-битное число ;-)
студент ю
На си я пробовал писать но с трудом получалось, ассемблер ближе но путаюсь в нем сильно, пока рано мне переходить на си хоть знаю что намного проще пишется программа. А можно ли сделать вставку кода на си в программу написанную на ассемблере, если можно то как. наоборот знаю что вставляют в си ассемблерные вставки, а чтоб в ассемблер вставки на си не видел. Если десяти разрядное число поделить на части таким образом 00_0000_0000, то в моем случае двумя байтами можно пренебречь они все равно будут нули. Остается две части 0000_0000, если рассматривать два полубайта отдельно, (взять только 0000 старших разряда) то это сильно грубо получится, а у меня если результат измерения меньше 0110 1010, то RD5 установить 0, если число больше 1001 0001, то на RD6 установить 0, вот я и ломаю голову как такую кучу битов контролировать.
esaulenka
Во-первых, старший байт проверять надо. Откуда уверенность, что там не появится единица? Помеха какая-то, например.

А во-вторых, совершенно не понял идеи разделять младший байт пополам. Берём его целиком (не думая, что там аж целых 8 бит!) и сравниваем...


upd: поправил опечатки
студент ю
Цитата(esaulenka @ Nov 23 2011, 00:53) *
не думаю, что там аж целых 8 бит

Так число 106 занимает в двоичной системе семь бит 1101010, а число 145 занимает восемь бит 10010001, так что по любому восемь их и контролировать, диапазон у меня будет узкий поэтому двумя старшими разрядами я могу пренебречь, хотя может и ошибаюсь
esaulenka
Ещё раз: про биты забываем, работаем с байтами.
Проверяем старший байт. Если там не ноль, значит, число ОЧЕНЬ большое, делаем, что нам надо.
Проверяем младший байт. Сравниваем с 106 и с 145, делаем, что надо. В чём затруднения-то?
студент ю
затруднение простое, как на ассемблере написать результат измерения сравнить с 106 и 145, если меньше то установить ноль в порте D
Ruslan1
Цитата(студент ю @ Nov 23 2011, 14:00) *
затруднение простое, как на ассемблере написать результат измерения сравнить с 106 и 145, если меньше то установить ноль в порте D

Ну если вы такой любитель ассемблера, то хоть макросы применяйте, ну для затравки тут тут посмотрите

Хотя ассемблер- это тупик, причем уже много-много лет. Не тратьте молодые годы на ассемблер, это ни вам ни окружающим не нужно, поверьте sm.gif
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.