Wire-1 на ассемблере.

Дисплеи, датчики и прочие функциональные узлы, управляемые МК.
Ответить
Грызет канифоль
Сообщения: 299
Зарегистрирован: Пн май 16, 2011 10:54:32
Откуда: Красноярск

Сообщение Вадиматоричик »

Всех с наступившим.
Уже около месяца пытаюсь разобраться с Wire1. Перечитал все статьи, которые только можно было. Но это мне не особо помогло. Пытаюсь начать работать с датчиком температуры DS18B20 (100%!). Пишу на ассемблере. Пока что удается лишь узнать, есть ли на шине устройство или нет, а дальше все плохо. Попытался узнать код устройства. Посылаю 0x33. а в ответ все 8 байт 0b11111111. Пишу под Atmega16. Пока что на всем порту лишь одна шина, так что манипулирую всем портом сразу. Atmega16 тактируется от встроенного кварца на 8 мгц. Заливаю с помощью Jtag ICE (Иногда опознается как Jtag ICE Mkii, когда как...). Заливаю, ставлю паузу по окончанию приему последнего байта и перехода в бесконечный цикл. И там уже смотрю все регистры.
Код разбит на функции.
Инициализация.

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

.include "m16def.inc"
.def Temp = R16
.def Temp1= R17
.def Temp2= R18
.def Temp3= R19
.def MAX  = R29
       ser  MAX
.equ Wire = PB0                    ;Пин в порту Wire1.
.equ DDWIR= DDRB                   ;Порт входа Wire.
.equ PINWI= PINB                   ;Порт входа.

out DDRD, MAX
;Стек.-----------------------------------------------------------------------------------------
  	   ldi  Temp,  Low(RAMEND)
   	   out  SPL,   Temp
	   ldi  Temp,  High(RAMEND)
	   out  SPH,   Temp
Функция задержки использует 2 регистра и стек.

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

Delay:push  Temp
DDL:   dec  Temp    
       cpi  Temp,  0
      brne  DDL
	   dec  Temp1
	   pop  Temp
	   cpi  Temp1, 0
      brne  Delay
	   ret
Ожидание устройства (Тут все работает).

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

;Рестарт и поиск элемента на шине.------------------------------------------
Wres:  ldi  Temp,  1<<Wire         ;Пин на выход.
       out  DDWIR, Temp            ;Автоматически будет 0 на линии.
       ldi  Temp,  239             ;500 мкс ждем (482).
	   ldi  Temp1, 4
     rcall  Delay

       ldi  Temp,  ~(1<<Wire)      ;На вход.
	   out  DDWIR, Temp

       ldi  Temp,  145             ;Ждем 74 мкс.
	   ldi  Temp1, 1
     rcall  Delay

        in  Temp,  PINWI           ;Смотрим есть ли что на шине.
	  sbrs  Temp,  0               ;Если что-то есть - дальше.
	  rjmp  main
	  rjmp  Wres                   ;Иначе выход. 
Функция передачи 1.

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

;Передаем 1.----------------------------------------------------------------
Wr1:   ldi  Temp,  1<<Wire         ;Пин на выход.
       out  DDWIR, Temp            ;Автоматически будет 0 на линии.
       ldi  Temp,  25              ;Ждем 15 мкс.
	   ldi  Temp1, 1
     rcall  Delay
       clr  Temp                   ;Переводим во вход.
       out  DDWIR, Temp
       ldi  Temp,  145             ;Ждем 74 мкс.
	   ldi  Temp1, 1
     rcall  Delay
	   ret
Передачи 0 (Ничем кроме задержки шины в 0 не отличается).

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

;Передаем 0.----------------------------------------------------------------
Wr0:   ldi  Temp,  1<<Wire         
       out  DDWIR, Temp           .
       ldi  Temp,  220             ;Ждем 112 мкс.
	   ldi  Temp1, 1
     rcall  Delay
       clr  Temp                  
       out  DDWIR, Temp
       ldi  Temp,  145             
	   ldi  Temp1, 1
     rcall  Delay
	   ret
Функция приема.

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

;Принимаем бит.-------------------------------------------------------------
RidW:  ldi  Temp,  1<<Wire        ;На выход, 0. 
       out  DDWIR, Temp           .
       ldi  Temp,  25             ;Ждем 15 мкс.
	   ldi  Temp1, 1
     rcall  Delay
       clr  Temp                  
       out  DDWIR, Temp           ;На вход.
	    in  Temp2, PINWI          ;Считываем порт.
       ldi  Temp,  145            ;Ждем 74 мкс.       
	   ldi  Temp1, 1
     rcall  Delay
	   ret
На основе вышеописанных функций работают 2 "глобальные".
Передача байта.

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

;Передача байта.------------------------------------------------------------
;Ïåðåäà÷à áàéòà.------------------------------------------------------------
PrbW: sbrc  Temp3, 0               ;Åñëè áèò 0 = 1, ïåðåäàòü 1.
     rcall  Wr1
	  sbrs  Temp3, 0               ;Åñëè 0 = 0, ïåðåä. 0.
     rcall  Wr0 

      sbrc  Temp3, 1               
     rcall  Wr1
	  sbrs  Temp3, 1               
     rcall  Wr0 

      sbrc  Temp3, 2               
     rcall  Wr1
	  sbrs  Temp3, 2               
     rcall  Wr0 

      sbrc  Temp3, 3               
     rcall  Wr1
	  sbrs  Temp3, 3               
     rcall  Wr0 

      sbrc  Temp3, 4              
     rcall  Wr1
	  sbrs  Temp3, 4               
     rcall  Wr0 

      sbrc  Temp3, 5               
     rcall  Wr1
	  sbrs  Temp3, 5               
     rcall  Wr0 

      sbrc  Temp3, 6               
     rcall  Wr1
	  sbrs  Temp3, 6               
     rcall  Wr0 

      sbrc  Temp3, 7               
     rcall  Wr1
	  sbrs  Temp3, 7               
     rcall  Wr0 
	   ret  
Прием байта.

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

;Прием байта!---------------------------------------------------------------
RrWb:  clr  Temp3                  ;×èñòèì áàéò.
     rcall  RidW                   ;Ñ÷èòûâàåì áèò.
      sbrs  Temp2, 0;Wire            ;Åñëè áèò ¹Wire=0,
	   sbr  Temp3, (1<<0)               ;ñäåëàòü çàïèñü 1 íà ãåî ìåñòå â áàéòå.

     rcall  RidW   
      sbrs  Temp2, 0
	   sbr  Temp3, (1<<1)    
	   
     rcall  RidW                   
      sbrs  Temp2, 0           
	   sbr  Temp3, (1<<2)
	   
     rcall  RidW                   
      sbrs  Temp2, 0
	   sbr  Temp3, (1<<3)
	   
     rcall  RidW                   
      sbrs  Temp2, 0          
	   sbr  Temp3, (1<<4)
	   
     rcall  RidW                   
      sbrs  Temp2, 0
	   sbr  Temp3, (1<<5)

     rcall  RidW                   
      sbrs  Temp2, 0
	   sbr  Temp3, (1<<6)

     rcall  RidW                   
      sbrs  Temp2, 0
	   sbr  Temp3, (1<<7)
	   ret
Главный цикл программы. Для наглядности я решил записать полученные 8 байт в неиспользуемые регистры, чтобы потом посмотреть.

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

main:  ldi  Temp3, 0x33            ;Игнорироват код устройства.
     rcall  PrbW 

	 rcall  RrWb                   ;Принять 1-й байт.
	   mov  r20, Temp3
	 rcall  RrWb                   ;2
	   mov  r21, Temp3
	 rcall  RrWb                   ;3
	   mov  r22, Temp3
	 rcall  RrWb                   ;4
	   mov  r23, Temp3
	 rcall  RrWb                   ;5
	   mov  r24, Temp3
	 rcall  RrWb                   ;6
	   mov  r25, Temp3
	 rcall  RrWb                   ;7
	   mov  r26, Temp3
	 rcall  RrWb                   ;8
	   mov  r27, Temp3

L0: rjmp  L0
Все проверяю в железе. Т.к. протеус вообще не подает признаков жизни.
Схема и файлы проекта в архиве.
Wire1.rar
(32.91 КБ) 244 скачивания
Все можно сделать, было бы желание!
Реклама
Поставщик валерьянки для Кота
Аватара пользователя
Сообщения: 2365
Зарегистрирован: Вс янв 09, 2011 16:51:39
Откуда: Санкт-Ленинград

Сообщение Dmitry Dubrovenko »

Вадиматоричик писал(а):протеус вообще не подает признаков жизни
В Протеусе Ван-Вайер замечательно работает.
Очень рекомендую воспользоваться, и отлаживать по шагам.
Сразу увидите, где не тот бит получается. Тут и смотрите, в первую очередь на тайминг. Ван-Вайер весь на таймингах.
Собрал уже не одно устройство.
Все тайминги реализовываю по таймеру (а не программно).
Естественно необходимо предусмотреть отработку ошибок.
ICQ нет, и, в ближайшее время, не будет.
Контактная информация:
Реклама
Сверлит текстолит когтями
Аватара пользователя
Сообщения: 1231
Зарегистрирован: Вс май 21, 2006 16:07:59
Откуда: Алтай

Сообщение wws63 »

http://publ.lib.ru/ARCHIVES/B/BELOV_Ale ... _A.V..html
почитайте, там и ASM и Си и 18B20 найдёте.....
akl
Друг Кота
Сообщения: 4468
Зарегистрирован: Пт мар 07, 2008 06:54:43
Откуда: Ижевск

Сообщение akl »

Вадиматоричик Попробуйте переписать свой код в соответствии с этим рисунком, обратив внимание на чтение бита. По мне, сейчас всегда будет считываться 0. Сделал бы так
Спойлер

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

;Принимаем бит.-------------------------------------------------------------
RidW:  ldi  Temp,  1<<Wire        ;На выход, 0. 
       out  DDWIR, Temp           .
       ldi  Temp,  25             ;Ждем 15 мкс.
	   ldi  Temp1, 1
     rcall  Delay
       clr  Temp                  
       out  DDWIR, Temp           ;На вход.
;*************************************************
       ldi  Temp,  25             ;Ждем 15 мкс, чтобы резистор подтяжки зарядил линию до 1, если DS18B20 передает её.
	   ldi  Temp1, 1
     rcall  Delay

	    in  Temp2, PINWI          ;Считываем порт.
;*************************************************
       ldi  Temp,  145            ;Ждем 74 мкс.       
	   ldi  Temp1, 1
     rcall  Delay
	   ret
DS18B20.GIF
Реклама
Эиком - электронные компоненты и радиодетали
Грызет канифоль
Сообщения: 299
Зарегистрирован: Пн май 16, 2011 10:54:32
Откуда: Красноярск

Сообщение Вадиматоричик »

Благодарю за помощь. Байты приходят и уходят. Причем не те, что должны быть. С таймингами все норм. Приходят не те значения.
Все можно сделать, было бы желание!
Реклама
akl
Друг Кота
Сообщения: 4468
Зарегистрирован: Пт мар 07, 2008 06:54:43
Откуда: Ижевск

Сообщение akl »

Может не те, потому что Вы в программе их инвертируете?
Реклама
Грызет канифоль
Сообщения: 299
Зарегистрирован: Пн май 16, 2011 10:54:32
Откуда: Красноярск

Сообщение Вадиматоричик »

Готово! Вот проект, который получает данные о температуре с датчика. Большего мне не надо. Так что сойдет (Может потом таки решусь на таймерах сделать). Получаю целые числа. Результат в регистре r21.
Вложения
Wire1.rar
(34.48 КБ) 318 скачиваний
Все можно сделать, было бы желание!
Ответить

Вернуться в «Периферия»