|
1-wire Интерфейс, Assembler'ные подпрограмы для начинаюших |
|
|
|
Apr 11 2007, 19:48
|

Участник

Группа: Новичок
Сообщений: 18
Регистрация: 11-04-07
Из: Россия, Бурятия, Улан-Удэ
Пользователь №: 26 954

|
Здравствуйте, Изучаю микроконтроллеры для себя, решил изучить интерфейс 1-wire наткнулся на странную ситуацию: вроде и все давно ясно и куча библиотек готовых есть под разные микроконтроллеры на С разных мастей и под Assembler. И в форумах не одна тема создана, а полной картины по 1-wire[AVR Assembler] как небыло так и нет. Предлагаю поделится опытом, советом, готовым примером, покритиковать, поддержать и просто высказать свое мнение Цель: Создание простых, универсальных и ясных подпрограмм для работы с 1-wire Резюмируя эту тему можна создать неплохую статью для начинающих в рамках проекта AVR для начинающих Electronix.ru А еще, чтобы не писать лишнего и не терять суть, предполагаю что вся необходимая документация касаемого стандарта интерфейса всем известна, а обсуждать только конкретные решения проблем. Ну так начнем! Возьмем в качестве отправной точки (Я начинающий!) Код AVR318: Ведущий однопроводной интерфейс 1-Wire компании Dallas (21 страница, пересмотр А, обновление от 09/04) В рекомендациях показывается, как реализовать 1-проводной ведущий интерфейс с помощью микроконтроллера AVR. Рассмотрено два подхода: полностью программный и с помощью встроенного модуля У(С)АПП Нас интересует только полностью программный подход Из него следует: Что для программной реализации протокола удобно разделить все команды на четыре уровня УРОВНИ (и команды) 1)Передача и прием отдельных битов a)Сброс всех устройств на шине [Restart] B)Запись бита "1" в устройство [WriteBit1] с)Запись бита "0" в устройство [WriteBit0] d)Чтение бита из устройства [ReadBit] 2)Передача и прием отдельных байтов a)Послать байт в устройство [SentByte] B)Принять байт из устройства [ReseiveByte] 3)Сетевой уровень a)Чтение ПЗУ [ReadROM] B)Совпадение ПЗУ [MatchROM] c)Пропуск ПЗУ [SkipROM] d)Поиск ПЗУ [SearchRom] 4)Команды для работы с конкретными устройствами например датчик температуры ds1820 series м некоторые прикладные подпрограммки a)Вычисление CRC8 (табличная реализация и прямое вычисление) B)Диагностика ошибок с)Чтение режима питания микросхем паразитное или отдельное Так как стандарт основывается на точном соблюдении всех задержек, всего 2 группы 6-64мкс и 470-1000мкс. Вопрос как универсально сформировать задержки для различных частот задающих кварцов? Так по теме словесное описанное описание команд первого уровня Код Restart: ;Сброс всех устройств ;Подсаживаем линию, задержка на 700мкс ;Задержка в 65мкс, проверка сигнала ;ок =уровень сигнала равен 0 передача управления дальше на3 ;error уровень Равен 1 =обрыв линии ;3 формируем задержку в 500мкс проверяем уровень сигнала ;ок =уровень сигнала равен 1 ;error уровень равен 0 =линия закорочена ;в переменную помешаем код ошибки и выходи 0=ок reti Readbit: ;Чтение чтение одного бита из устройства ;Формируем синхроимпульс, подсаживаем линию =задержка 1мкс отпускаем линию снова задержка 13мкс ;считываем уровень сигнала помешаем кудато ;заполняем слот задержкой в 60-120мкс (60мкс) reti writebit0: ;Запись в слот нулевого значения ;подсадить линию ;задержка в 80мкс ;отпустиь линию ; reti writebit1: ;Запись в слот единичного значения ;подсадить линию ;задержка в 4,5мкс ;отпустиь линию ;задержка в 75мкс reti
Сообщение отредактировал 3state-systems - Apr 11 2007, 19:48
|
|
|
|
3 страниц
1 2 3 >
|
 |
Ответов
(1 - 14)
|
Apr 12 2007, 12:46
|

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

|
Цитата(3state-systems @ Apr 11 2007, 18:48)  Предлагаю поделится опытом, советом, готовым примером, покритиковать, поддержать и просто высказать свое мнение Хм. "петь я не умею, но люблю". Т.е. на ассемблере пишу очень редко, но покритиковать - всегда пожалуйста. Цель благородная, поэтому постараюсь внести свою лепту, но примеры буду кидать на С, если хотите - переводите их на ассемблер. Цитата(3state-systems @ Apr 11 2007, 18:48)  1)Передача и прием отдельных битов a )Сброс всех устройств на шине [Restart] B )Запись бита "1" в устройство [WriteBit1] с )Запись бита "0" в устройство [WriteBit0] d )Чтение бита из устройства [ReadBit] с А согласен. Что касается b-d, то если мы внимательно посмотрим на диаграмму работы шины, то заметим что при передаче единицы и при приеме мастер шевелит ногой совершенно одинаково. Поэтому все три пункта объединяются в одну функцию (подпрограмму) "обмен битом", которая в качестве входного параметра принимает передаваемый бит а возвращает принятый бит. Если надо передать бит, мы не используем возвращаемый результат, если надо принять - вызываем ее с параметорм "1". Таким образом мы существенно упрощаем и сокращаем программу. Цитата(3state-systems @ Apr 11 2007, 18:48)  2)Передача и прием отдельных байтов a )Послать байт в устройство [SentByte] B )Принять байт из устройства [ReseiveByte] Аналогично предыдущему - обе функции сливаются в одну "обмен байтом". Передача = "обмен" с игнорированием ответа, прием = "обмен" с передачей 0xFF. Цитата(3state-systems @ Apr 11 2007, 18:48)  3)Сетевой уровень a )Чтение ПЗУ [ReadROM] B )Совпадение ПЗУ [MatchROM] c )Пропуск ПЗУ [SkipROM] d )Поиск ПЗУ [SearchRom] Ненаказуемо  Цитата(3state-systems @ Apr 11 2007, 18:48)  Так как стандарт основывается на точном соблюдении всех задержек, всего 2 группы 6-64мкс и 470-1000мкс. Вопрос как универсально сформировать задержки для различных частот задающих кварцов? Поскольку допуски довольно большие, вполне можно формировать задержки пустым циклом, т.е. функцией __delay_cycles() в IAR C или макросом вроде (я же предупреждал - пишу редко) Код Delay MACRO cycles local Loop LDI R16, cycles Loop: DEC R16 BNE Loop ENDM Один такой цикл (если не изменяет память) исполняется 3 такта, т.е. надо предусмотреть вариант когда требуется бОльшая задержка: Код Delay MACRO cycles local Loop #if cycles < 256 * 3 LDI R16, cycles / 3 Loop: DEC R16 BNE Loop #else // предполагаю, что цикл займет 7 тактов, если ошибся - изменить константу LDI R16, LOW(cycles / 7) LDI R16, HI(cycles / 7) Loop: // дописать код для двухбайтного счетчика
#endif ENDM Далее, следуя принципу IBM "машина должна работать, а человек - думать" пишем простой макрос, переводящий время задержки в количество тактов: Код #define OSC 7372800UL //Core frequency, Hz, unsigned long (32 bits) #define MS *OSC/1000 #define MKS *OSC/1000/1000 Меняется кварц - меняем строчку #define OSC. Теперь задержка делается просто: Код на С: __delay_cycles(15 MKS); __delay_cycles(60 MS); На асм: Delay 15 MKS Delay 60 MS Ваш ход.
--------------------
На любой вопрос даю любой ответ"Write code that is guaranteed to work, not code that doesn’t seem to break" ( C++ FAQ)
|
|
|
|
|
Apr 12 2007, 20:57
|

Участник

Группа: Новичок
Сообщений: 18
Регистрация: 11-04-07
Из: Россия, Бурятия, Улан-Удэ
Пользователь №: 26 954

|
Так сейчас закодил первый уровень вот что получилось Код Restart: ;Сброс всех устройств sbi DDRD,DataPin1;Настроить линию на выход cbi PORTD,DataPin1;подсадить линию rcall delay480 ;задержка в 480мкс sbi PORTD,DataPin1;отпустиь линию rcall delay70 ;задержка в 70мкс cbi DDRD,DataPin1;Настроить линию на вход clt ;Очистить флаг Т регистра Sreg 0 = Все нормально sbic PIND,DataPin1 ;Пропустить следущию команду если бит равен "0" set ;Записать "1" в регитр Sreg флаг Т 1 = Ошибка в линии Microlan rcall delay410 ;задержка в 410мкс reti
ReadBit: ;чтение одного бита из устройства в Регистр Sreg флаг Т sbi DDRD,DataPin1;Настроить линию на выход cbi PORTD,DataPin1;подсадить линию rcall delay6 ;задержка в 6мкс sbi PORTD,DataPin1;отпустиь линию rcall delay9 ;задержка в 9мкс cbi DDRD,DataPin1;Настроить линию на вход clt ;Очистить флаг Т регистра Sreg sbic PIND,DataPin1 ;Пропустить следущию команду если бит равен "0" set ;Записать "1" в регитр Sreg флаг Т rcall delay55 ;задержка в 55мкс reti
Writebit0:; ;Запись бита "0" в устройство sbi DDRD,DataPin1;Настроить линию на выход cbi PORTD,DataPin1;подсадить линию rcall delay60 ;задержка в 80мкс sbi PORTD,DataPin1;отпустиь линию rcall delay10 ;задержка в 10мкс reti
Writebit1: ;Запись бита "1" в устройство sbi DDRD,DataPin1;Настроить линию на выход cbi PORTD,DataPin1;подсадить линию rcall delay6 ;задержка в 6мкс sbi PORTD,DataPin1;отпустиь линию rcall delay64 ;задержка в 64мкс reti Но впереди конечно .equ DataPin1 =5 ;portd5 = DataPin 1-wire bus Эту куда подключена наша шина долго думал как сделать универсально получилось что можно свободно менять пин подключения в пределах одного порта D изменить только циферку Так и непонял что как организовать задержки ну лана будем мутить nop с циклами Прошу всех обратить внимание как вначале организовать порт с подтягивающими встроенными резисторами ну чтобы 0 это было 0 а не 1 и еще один вопрос можно ли для обмена байтами в следующем уровне использовать стек (PUSH POP)
Сообщение отредактировал 3state-systems - Apr 12 2007, 21:07
|
|
|
|
|
Apr 12 2007, 22:45
|

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

|
Цитата(3state-systems @ Apr 12 2007, 19:57)  Но впереди конечно .equ DataPin1 =5 ;portd5 = DataPin 1-wire bus Почему впереди? Надо сразу писать правильно и красиво. Код #define DataPort PIND #define DataPin 5 Указываем именно PINx, чтобы можно было получить адреса остальных регистров прибавляя 1, 2, 3. Кстати, я ориентируюсь на ассемблер IAR, а вы, судя по .equ имеете ввиду avrasm2? Цитата(3state-systems @ Apr 12 2007, 19:57)  вот что получилось Код Restart: ;Сброс всех устройств sbi DDRD,DataPin1;Настроить линию на выход cbi PORTD,DataPin1;подсадить линию rcall delay480 ;задержка в 480мкс sbi PORTD,DataPin1;отпустиь линию rcall delay70 ;задержка в 70мкс cbi DDRD,DataPin1;Настроить линию на вход Сразу большая ошибка: точно также как и в I2C, в 1-wire нельзя выдавать единицу на вывод. Потому что в это время другое устройство может притягивать линию к нулю и мы получим конфликт уровней. Возможно, сгорит не сразу, но делать так нельзя  При инициализации надо записать в PORTx ноль, и дальше работать только изменением направления: настроили на вывод - снаружи линия притянулась к нулю. Настроили на ввод - внешний резистор потянул линию к единице. И заканчиваются подпрограммы командой ret. reti завершает прерывания. Поэтому ваш код должен выглядеть примерно так: Код .equ DataPort PIND .equ DataPin 5
Restart: ;Сброс всех устройств cbi DataPort + 2, DataPin; PORTx = 0, подготовить к работе sbi DataPort + 1, DataPin; DDRx = 1, Настроить линию на выход - посадить линию в 0 rcall delay480 ;задержка в 480мкс cbi DataPort + 1, DataPin;Настроить линию на вход = отпустить линию rcall delay70 ;задержка в 70мкс clt ;Очистить флаг Т регистра Sreg 0 = Все нормально ; обычно используют флаг Z, так удобнее - он выставляется командой TST. sbic DataPort, DataPin ; Пропустить следущию команду если бит равен "0" set ; Записать "1" в регитр Sreg флаг Т 1 = нет устройств на шине rcall delay410 ; задержка в 410мкс ret ; хотя RCALL и следом за ним RET можно заменить на один RJMP delay410 Чтение/запись бита: Код WriteBit0: clt rjmp ExchangeBit WriteBit1: ReadBit: set ExchangeBit: ;Передаваемый бит в T sbi DataPort + 1, DataPin; DDRx = 1, Настроить линию на выход - посадить линию в 0 rcall delay6 ; задержка в 6мкс BRTC Write_0 ; Если передается ноль - оставить ногу посаженной в 0 cbi DataPort + 1, DataPin; Настроить линию на вход = отпустить линию Write_0: rcall delay9 ; задержка до точки чтения clt ; Очистить флаг Т sbic DataPort, DataPin ; Пропустить следущию команду если линия притянута к 0 set rcall delay45 ; задержка в 45мкс cbi DataPort + 1, DataPin; Настроить линию на вход = отпустить линию rjmp delay2 ; задержка >1мкс - пауза между битами и возвратиз подпрограммы. В флаге T - считанный бит Цитата(3state-systems @ Apr 12 2007, 19:57)  Так и непонял что как организовать задержки ну лана будем мутить nop с циклами Напишите две задержки разной длительности. Посмотрите, насколько похож код. Почитайте в описании ассемблера про макросы. Цитата(3state-systems @ Apr 12 2007, 19:57)  Прошу всех обратить внимание как вначале организовать порт с подтягивающими встроенными резисторами ну чтобы 0 это было 0 а не 1 Даже и не думать в эту сторону - внутренних подтяжек совершенно недостаочно для 1-wire Поэтому обязательно ставить внешнюю и про внутреннюю забыть! Цитата(3state-systems @ Apr 12 2007, 19:57)  и еще один вопрос можно ли для обмена байтами в следующем уровне использовать стек (PUSH POP) Можно, почему бы нет?
--------------------
На любой вопрос даю любой ответ"Write code that is guaranteed to work, not code that doesn’t seem to break" ( C++ FAQ)
|
|
|
|
|
Apr 13 2007, 09:47
|

Участник

Группа: Новичок
Сообщений: 18
Регистрация: 11-04-07
Из: Россия, Бурятия, Улан-Удэ
Пользователь №: 26 954

|
Цитата Кстати, я ориентируюсь на ассемблер IAR, а вы, судя по .equ имеете ввиду avrasm2? Да конечно на него, мы же пишем для начинающих Цитата И заканчиваются подпрограммы командой ret. reti завершает прерывания. Сорри попутал чуток Цитата При инициализации надо записать в PORTx ноль, и дальше работать только изменением направления: настроили на вывод - снаружи линия притянулась к нулю. Настроили на ввод - внешний резистор потянул линию к единице. Вроде с виду все правильно, может так оно и есть, просто я смотрел исходники для MCS-51 там вроде делается записью единицы. Цитата Даже и не думать в эту сторону - внутренних подтяжек совершенно недостаочно для 1-wire Поэтому обязательно ставить внешнюю и про внутреннюю забыть! Полностью согласен, по даташиту - резистор, правда номинал у всех довольно сильно варьируется в топиках. но это потом у\еще уточним. Приду домой внимательно посмотрю ваш код
|
|
|
|
|
Apr 13 2007, 12:36
|

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

|
Цитата(3state-systems @ Apr 13 2007, 08:47)  Да конечно на него, мы же пишем для начинающих  Три раз перечитал, так и не понял - "Да" - это IAR или avrasm2?  Цитата(3state-systems @ Apr 13 2007, 08:47)  Вроде с виду все правильно, может так оно и есть, просто я смотрел исходники для MCS-51 там вроде делается записью единицы. А! Тогда понятно. У 51 нет верхнего транзистора, для него что вывод 1, что ввод - одинаково. Он в этом смысле очень похож на вывод 1-wire. Вы обратили внимание, что у 51 нет регистра направления порта? Именно поэтому. На "честных" портах подход должен быть другим - как я описал.
--------------------
На любой вопрос даю любой ответ"Write code that is guaranteed to work, not code that doesn’t seem to break" ( C++ FAQ)
|
|
|
|
|
Apr 13 2007, 15:26
|

Участник

Группа: Новичок
Сообщений: 18
Регистрация: 11-04-07
Из: Россия, Бурятия, Улан-Удэ
Пользователь №: 26 954

|
Цитата (3state-systems @ Apr 13 2007, 08:47) * Да конечно на него, мы же пишем для начинающих smile.gif Три раз перечитал, так и не понял - "Да" - это IAR или avrasm2? smile.gif AvrAsm2 Цитата Указываем именно PINx, чтобы можно было получить адреса остальных регистров прибавляя 1, 2, 3. Сначала хотел возмутится в даташите на мегу в Register Summary все в обратном порядке потом глянул на адреса  Гениально придумано! Вот тока зачем добавлять 3? Код 0x1B (0x3B) PORTA 0x1A (0x3A) DDRA 0x19 (0x39) PINA Код .equ DataPort =PIND;Порту к которому подключена шина .equ DataPin =5 ;Пин к которому подключена шина 1-wire bus ;DataPort=PIN(x); ;DataPort+1=DDR(x) ;DataPort+2=PORT(x)
|
|
|
|
|
Apr 13 2007, 17:18
|

Участник

Группа: Новичок
Сообщений: 18
Регистрация: 11-04-07
Из: Россия, Бурятия, Улан-Удэ
Пользователь №: 26 954

|
Часа два разбирался с вашей универсальной подпрограммой обмена битами, вроде разобрался но для новичка конечно это жесть Так значит имеем 100пудовые подпрограммы для первого уровня Код .equ DataPort =PIND;Порту к которому подключена шина .equ DataPin =5 ;Пин к которому подключена шина 1-wire bus ;DataPort=PIN(x); ;DataPort+1=DDR(x) ;DataPort+2=PORT(x)
Restart: ;Сброс всех устройств cbi DataPort+2,DataPin;PORTx = 0, подготовить к работе sbi DataPort+1,DataPin;DDRx = 1, Настроить линию на выход - посадить линию в 0 rcall delay480 ;задержка в 480мкс cbi DataPort+1,DataPin;Настроить линию на вход = отпустить линию rcall delay70 ;задержка в 70мкс clt ;Очистить флаг Т регистра Sreg 0 = Все нормально sbic DataPort, DataPin ;Пропустить следущию команду если бит равен "0" set ;Записать "1" в регитр Sreg флаг Т=1 - нет устройств на шине rcall delay410 ;задержка в 410мкс ret ;[хотя RCALL и следом за ним RET можно заменить на один RJMP delay410]
WriteBit0: ;Запись Бита "0" clt rjmp ExchangeBit WriteBit1: ;Запись Бита "1" ReadBit: ;Чтение Бита set ExchangeBit: ;Передаваемый бит в T sbi DataPort+1,DataPin ;DDRx = 1, Настроить линию на выход - посадить линию в 0 rcall delay6 ;задержка в 6мкс BRTC Write_0 ;Если передается ноль - оставить ногу посаженной в 0 cbi DataPort + 1, DataPin;Настроить линию на вход = отпустить линию Write_0: rcall delay9 ;задержка до точки чтения clt ;Очистить флаг Т sbic DataPort,DataPin ;Пропустить следущию команду если линия притянута к 0 set rcall delay45 ;задержка в 45мкс cbi DataPort+1,DataPin ;Настроить линию на вход = отпустить линию rcall delay10 ;задержка 10мкс - пауза между битами и возвратиз подпрограммы. В флаге T - считанный бит ret Restart -Сброс всех устройств WriteBit0 - Запись Бита "0" WriteBit1 - Запись Бита "1" ReadBit - Чтение Бита
Сообщение отредактировал 3state-systems - Apr 13 2007, 17:20
|
|
|
|
|
Apr 13 2007, 20:35
|

Участник

Группа: Новичок
Сообщений: 18
Регистрация: 11-04-07
Из: Россия, Бурятия, Улан-Удэ
Пользователь №: 26 954

|
Так добрались до байт черновой вариант такой .def Temp =R16 ;Temp он и в африке Temp .def ByteBus =R20 ;Байт для передачи\приема 1-wire bus Код WriteByte: ;Запись байта в ведомое устройство lsr Bytebus ;Сдвинуть байт вправо ->С (Флаг переноса регистра Sreg) brcs Writebit1 ;Перейти если флаг переноса установлен(текущий бит равен 1) rcall Wriebit0 ;Перейти если флаг переноса сброшен (текущий бит равен 0) ;Нужен цикл повторить 8 раз ret Чтот у мня цикл взбунтовался не работает Чтение байта чтото подобное
|
|
|
|
|
Apr 14 2007, 10:37
|

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

|
Для начала отступление: я вас обманул. Вот тут: Цитата(Сергей Борщ @ Apr 12 2007, 21:45)  точно также как и в I2C, в 1-wire нельзя выдавать единицу на вывод. То есть про I2C - чистая правда, там нельзя. А в 1-wire почти правда. Нельзя выдавать единицу во время обмена. А между битами можно и в случае устройств типа термометров с паразитным питанием даже нужно. Поэтому возвращаемся к "100пудовым подпрограммам" и правим: Код Restart: ;Сброс всех устройств ; линия уже была настроена на вывод между обращениями cbi DataPort+2,DataPin;PORTx = 0, посадить линию в 0 rcall delay480;задержка в 480мкс cbi DataPort+1,DataPin;Настроить линию на вход = отпустить линию rcall delay70 ;задержка в 70мкс clt ;Очистить флаг Т регистра Sreg 0 = Все нормально sbic DataPort, DataPin;Пропустить следущию команду если бит равен "0" set ;Записать "1" в регитр Sreg флаг Т=1 - нет устройств на шине rcall delay410 ;задержка в 410мкс sbi DataPort+2,DataPin;PORTx = 1, подготовить к паразитному питанию sbi DataPort+1,DataPin;DDRx = 1, Настроить линию на выход - подать паразитное питание ret
ExchangeBit:;Передаваемый бит в T ; линия настроена на вывод между обменами cbi DataPort+2,DataPin;PORTx = 0, посадить линию в 0 ; sbi DataPort+1,DataPin;DDRx = 1, Настроить линию на выход - посадить линию в 0
...........
rcall delay45 ;задержка в 45мкс ; cbi DataPort+1,DataPin;Настроить линию на вход = отпустить линию sbi DataPort+2,DataPin;PORTx = 1, подготовить к паразитному питанию sbi DataPort+1,DataPin;DDRx = 1, Настроить линию на выход - подать паразитное питание rcall delay10;задержка 10мкс - пауза между битами ret; возврат из подпрограммы. В флаге T - считанный бит Цитата(3state-systems @ Apr 13 2007, 16:18)  Часа два разбирался с вашей универсальной подпрограммой обмена битами, вроде разобрался но для новичка конечно это жесть  Зато посмотрите насколько она короче. Когда вы будете писать для I2C или SPI вы сможете использовать эту же идею и снова получить компактную и при этом быструю подпрограмму. Если в 1-wire скорость большой роли не играет (все равно в задержках сидим), то I2C и SPI уже достаточно шустрые интерфейсы. Да и вообще, мало ли где такой прием пригодится. Цитата(3state-systems @ Apr 13 2007, 19:35)  Чтот у мня цикл взбунтовался не работает  Ну цикла я тут не увидел, но обратите внимание, что по brcs Writebit1 вы уходите в подпрограмму, а дойдя до ее ret вы вернетесть не туда, откуда вызвали Writebit1, а туда, откуда вызвали WriteByte, ведь вы использовали не RCALL для вызова Writebit1. А я вам подкину еще одну мысль: В теперешнем варианте вы берете бит Цитата Код lsr Bytebus;Сдвинуть байт вправо ->С (Флаг переноса регистра Sreg) и выясняете через какую ветвь зайти в ExchangeBit чтобы загрузить правильное значение в флаге T. Так почему бы не переписать ExchangeBit чтобы он ожидал и возвращал бит сразу в флаге С? Тогда цикл ExchangeByte будет выглядеть совсем просто: Код .def Counter=R16;Счетчик бит .def ByteBus =R20;Байт для передачи\приема 1-wire bus ExchangeByte: ldi Counter, 8 Loop: rol ByteBus; очередной передаваемый бит выдвинуть в C, принятый из С в ByteBus RCALL ExchangeBit dec Counter BNE Loop rol ByteBus;задвинуть последний принятый бит ret Цитата(3state-systems @ Apr 13 2007, 19:35)  Чтение байта чтото подобное Еще проще.Перед ExchangeByte дописать: Код ReadByte: LDI ByteBus, 0xFF WriteByte: ExchangeByte: ............. "По-моему так!" (с)Винни-Пух. Кто-нибудь покритикует?Кстати, нашел как сэкономить одну команду в ExchangeBit: Код вместо clt ;Очистить флаг Т sbic DataPort,DataPin ;Пропустить следущию команду если линия притянута к 0 set сделать sbis DataPort,DataPin;Пропустить следущию команду если линия притянута к 1 clt ;Очистить флаг Т Можете объяснить почему?
--------------------
На любой вопрос даю любой ответ"Write code that is guaranteed to work, not code that doesn’t seem to break" ( C++ FAQ)
|
|
|
|
|
Apr 14 2007, 11:29
|

Участник

Группа: Новичок
Сообщений: 18
Регистрация: 11-04-07
Из: Россия, Бурятия, Улан-Удэ
Пользователь №: 26 954

|
Цитата но обратите внимание, что по brcs Writebit1 вы уходите в подпрограмму, а дойдя до ее ret вы вернетесть не туда, откуда вызвали Writebit1, а туда, откуда вызвали WriteByte, ведь вы использовали не RCALL для вызова Writebit1. Вай, так и есть, подводный камень Я то думал что у мня цикл уходит в бесконечность ldi temp, 8 loop: dec temp nop brne loop Разбираюсь дальше.....
|
|
|
|
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|