sanyaav | Дата: Суббота, 20.07.2013, 16:27 | Сообщение # 1 |
Репутация:
Группа:Журналист
Сообщений: 134
Награды: 8
Статус:Offline
Для начала определимся со схемой. Нужен 1 вывод для датчика температуры, также нужны 4 вывода для динамической индикации и 8 выводов для записи семисегментного кода. 8 выводов - это как раз Порт Б, 4 вывода для перебора - пусть будут биты 1-4 Порта А (всё для удобства) и 1 вывод для датчика- это бит0 Порта А. В итоге получилась схема:
Теперь перейдем к работе с датчиком, ниже в картинке приведен последовательность действий для измерения.
Обращаю внимание на то, что такой набор команд можно применять в случае использования короткой линии с малым уровнем помех.
Процедура инициализации должна предшествовать любой команде из числа команд, входящих в 1-ю группу. В данном случае, это команда пропуска процедуры выбора активного датчика Skip ROM (датчик всего один). Кроме того, что эта “связка” должна исполняться в начале цикла замера температуры (см.верхние 2 строки), она должна быть исполнена и перед применением команды, разрешающей считывание байтов из ячеек оперативной памяти Read Scratchpad (см. строки 5 и 6). Это связано с алгоритмом работы DS1820, заданным разработчиками. Естественно, прежде чем считывать результат замера, нужно запустить процедуру преобразования температуры (команда Convert T) и подождать, пока эта процедура закончится. В конце цикла замера температуры, нужно считать, из области оперативной памяти DS1820, первые 2 байта (результат замера), в заранее назначенные 2 регистра общего назначения, с целью их дальнейшей обработки. В данном случае, нет никакой практической необходимости считывать из области оперативной памяти все ее содержимое, так как, кроме первых двух байтов, остальные не используются.
Исходник программы и схема выложены тут Исходник , по просьбам трудящихся подробно прокомментирован.
В ПП START, настраиваем выводы портов и отключаем компаратор. Далее производим инициализацию датчика DS1820, с проверкой на отклик (call INIT). После перехода в ПП INIT, первым делом, нужно выставить на сигнальной линии (0 бит порта А) единицу. Это нужно для того чтобы, в дальнейшем, можно было бы сформировать, на ней спад (строб) импульса сброса. При этом, условие “между двумя соседними перепадами, на линии RA0, должно пройти время не менее 1 мкс.” гарантированно обеспечивается за счет исполняемых команд. На линии RA0, все единичные уровни “выставляются” за счет внешнего, подтягивающего резистора в ПП PIN_HI. Далее, возврат по стеку в ПП INIT. Нулевой уровень, в отличие от единичного, “мастер” формирует обычным образом, то есть, путем установки нулевого уровня на выходе защелки вывода RA0, с последующей перестройкой направления работы вывода RA0 “на выход”. Далее, возврат по стеку в ПП INIT. Теперь нужно подождать не менее 480 мкс. для того чтобы обеспечить необходимую длительность импульса сброса. В данном случае, сформирована задержка в 600 мкс. После возврата из ПП задержки (PAUSE_X), нужно закончить формирование импульса сброса путем выставления, на линии RA0 единицы.(call PIN_HI). Далее пережидаем 70 мкс., если датчик "ответит", то после этой задержки на линии RA0 гарантированно будет 0, остается только переждать 480 мкс, для начала передачи. Если же ответа от датчика не было, то нужно снова повторить инициализацию. Итак, инициализация датчика завершилась и можно командовать. Так как датчик один и поэтому нет смысла производить адресацию, то ПИК выдает, в линию RA0, команду CCh (Skip ROM). Сначала числовое значение команды Skip ROM (CCh) записывается в регистр оперативной памяти Temp для того, чтобы, в дальнейшем, можно было осуществить операции с его содержимым. После этого, происходит переход по стеку в ПП передачи байта TRANSMIT. ПП TRANSMIT представляет собой ПП поочередной (последовательной) передачи, в линию RA0, битов, начиная с младшего Устроена она стандартно: в начале, в счетчик битов, записывается число битов байта (8), а в конце, содержимое счетчика битов декрементируется. Если результат декремента не =0, то происходит обработка следующего бита, а если =0, то считается, что байт обработан, и происходит возврат из ПП. Перед входом в ПП TRANSMIT, на линии RA4 “стоит” единица, и нужно сформировать на линии переход от 1 к 0, нужно держать нулевой уровень в течение 1 … 15 мкс., но сначала нужно подготовить текущий бит к выводу его на линию DQ в том смысле, что, для начала, его нужно “выпихнуть” в бит С регистра Status. Делается это с использованием команды rrf (так как сначала передается бит младшего разряда). После того, как текущий бит “ушел” в бит С, производится анализ его значения, и в зависимости от того, каково оно, исполняется либо ПП передачи нуля (OUT_0), либо ПП передачи единицы (OUT_1). В конце ПП TRANSMIT, происходит переход на исполнение процедуры декремента и анализа содержимого счетчика битов (goto METKA_2). В случае, если, после декремента содержимого счетчика битов, результат не =0, то начинается процедура вывода на линию RA0 следующего бита (goto METKA_1). Всё это будет продолжаться до тех пор, пока в линию DQ не будет выведен бит самого старшего разряда (№7). Итог: на линию RA0 выведен байт команды Skip ROM с числовым значением CCh.
После этого, происходит возврат рабочей точки программы, по стеку, из ПП TRANSMIT Теперь можно запустить процесс преобразования температуры, то есть, выполнить команду Start Conv. После передачи команды Start Conv, нужно подождать, пока процесс преобразования температуры завершится. Следовательно, нужно уйти в задержку. В простейшем случае, можно сформировать фиксированную задержку такой величины, чтобы она “перекрыла” максимальное время отработки этого процесса, но выгоднее использовать “плавающую” задержку. Особенность DS1820 (а также и других DS…) такова, что если, после запуска процесса преобразования температуры, мастер попытается считать еще не сформированный результат преобразования температуры, то DS1820, после первой же такой “попытки”, выдаст, в линию RA0, нулевой уровень, который на ней будет вплоть до окончания процесса преобразования температуры. Сразу же после окончания процесса преобразования температуры, DS1820 отпустит линию, после чего на ней, за счет подтягивающего резистора, установится единица. Таким образом, периодическое считывание байтов с линии RA0 рано или поздно закончится считыванием байта, все биты которого являются единицами, и произойдет это сразу же после того, как процесс преобразования температуры закончится.
Далее нужно запустить в работу "связку" инициализация –команда Skip ROM. Теперь можно считать результат замера температуры (команда Read Scratchpad с числовым значением BEh) После осуществляется переход в ПП приема байта IN. Сначала, из области оперативной памяти DS1820, в соответствии с алгоритмом процедуры чтения, определенным разработчиками, будет считан младший байт температуры. Со счетчиком битов такая же история, как и в случае передачи байта. Далее, нужно подготовить регистр Temp к последовательному его заполнению считываемыми битами (clrf Temp). Затем, нужно сформировать, на линии RA0, импульс с нулевым уровнем продолжительностью 1 … 15 мкс. Следовательно, нужно сначала уйти в ПП PIN_L0, вернуться по стеку, а затем уйти в ПП PIN_HI. Один NOP, который исполняется после возврата из ПП PIN_HI, нужен для “подгонки” момента считывания бита под сформулированное ранее условие: считывание бита нужно производить в непосредственной близости от правой границы 15-микросекундного интервала времени, отсчитываемого от строба (перехода от 1 к 0). Далее, производится запись, в бит С регистра Status, уровня текущего бита, выставленного датчиком на линии, с целью дальнейшей его переправки в регистр Temp. После того, как в бит С будет записан уровень текущего бита, происходит сдвиг вправо содержимого регистра Temp (rrf Temp,F), в результате чего, содержимое бита С записывается в бит №7 регистра Temp.
Теперь нужно переждать то время, в течение которого DS1820 выставляет, на линии текущий бит. После этого содержимое счетчика битов декрементируется, а результат этой операции анализируется (decfsz N,F). Если результат не нулевой, то циклы чтения битов повторяются до тех пор, пока не считается весь байт. После этого, считанный байт будет “лежать” в регистре Temp. Для обеспечения его дальнейшего копирования в регистр хранения младшего байта температуры (через W), содержимое регистра Temp копируется в регистр W, после чего происходит возврат по стеку в группу команд, обслуживающих исполнение команды Read Scratchpad, в ней-то происходит копирование принятого байта в регистр младшего байта температуры Temp_LSB. После этого, описанным выше способом, происходит считывание старшего байта температуры и запись его в регистр старшего байта температуры. В данном случае, из области оперативной памяти DS1820, происходит считывание только первых (верхних) двух байтов. Теперь нужно сделать так, чтобы эти байты можно было бы вывести в 4-разрядный семисегментный индикатор. То есть, нужно осуществить некие числовые преобразования в ветке BIN_TO_DEC. В регистре Temp_MSB хранится только знак, если температура положительна, то в нём записаны нули, если отрицательна, то FFh (или 11111111), производим его анализ, если температура отрицательная, то необходимо преобразовать число из дополнительного кода в прямой, и выставить знак минус, если же температура положительна, то работаем дальше с прямым кодом.
В нулевом бите регистра Temp_LSB хранится значение после запятой, если там стоит 1, то после запятой нужно указать 5 в 4-ом разряде индикатора, если там 0, то нужно указать 0. Проверка выполняется в ветке DIG_4.
Далее нужно сдвинуть байт вправо ( rrf Temp_LSB,1), для того чтобы "отсечь" значение после запятой и работать с целым числом, обратите внимание на обнуление бита С (0 бит) в регистре STATUS, это нужно для того, чтобы при сдвиге в старший бит гарантированно "залез" 0.
Далее производим деление на 100, с анализом флага переноса-заёма, для вычисления количества сотен, затем на 10,с анализом флага переноса-заёма, для вычисления количества десятков, записываем значения в регистры DIG1 и DIG2, в DIG3 записываем значение остатка. (кто не понимает как это работает, записывайте произвольное число на бумаге, и выполняйте команды вручную, пересчитывая каждый регистр) Теперь можно вывести числа на индикацию. Индикация динамическая, думаю как она работает все в курсе. Перед основным "телом" индикации, я ввел в программу несколько команд, для гашения незначащих нулей, в отрицательных числах это 1 или 2 индикатор, и сдвиг знака "-" если число одноразрядное. При желании можно вывести на индикатор какое-нибудь приветствие вначале или вместо знака после запятой вывести знак градуса ° , но это уже дело вкуса.
Сообщение отредактировал sanyaav - Суббота, 20.07.2013, 16:42 | |
|
I'll be back
|
|
| |
sanyaav | Дата: Воскресенье, 28.07.2013, 23:50 | Сообщение # 3 |
Репутация:
Группа:Журналист
Сообщений: 134
Награды: 8
Статус:Offline
evum, читайте Корабельникова обязательно, у него всё подробно. Здесь я стараюсь разбирать периферию и интерфейсы, рассчитывая на то, что у тех кто хочет заняться программированием есть представление о системах счисления и об операциях с числами. Такт-это один импульс, тактовый генератор-это устройство, которое эти импульсы выдаёт. А машинный цикл-это время, за которое микроконтроллер выполняет 1 команду. в PIC контроллерах (на примере 12f675, 16f628 и подобных) 1 машинный цикл выполняется за 4 такта (4 импульса тактового генератора), Это особенность PIC микроконтроллеров. Опрос кнопок был в программе ШИМ ТУТ , Про работу с таймерами расскажу как-нибудь позже, если нет терпения, то почитайте у Корабельникова, там только TMR0, но принцип для остальных примерно тот же, главное опираться на даташит.
Сообщение отредактировал sanyaav - Понедельник, 29.07.2013, 00:28 | |
|
I'll be back
|
|
| |