при этом глючить стал порт РС0 - значит все же косяк в программе... буду копать...
Добавлено after 18 minutes 20 seconds: oleg110592, вы оказались правы! я добавил во всех таких местах rjmp на следующую же строку - и все заработало без задержки... интересно - почему? попробую выяснить, какая подпрограмма это делает...
Яж просил ПОЛНУЮ ВЕРСИЮ показать, а не кусманчик... Вот к примеру (из старых заготовок) для MCS51: Спойлер
Код:
; ; "mlan.txt" файл обработчика шины microLAN ; с модулем обработки CRC8 ; ; заготовка для работы с DS18...20 или аналогичныой ИС ; используются акумулятор ; ;---------- ; ; ---------- константы ---------- ; dat_mlan equ 4 ; позиционный номер линии MLD tm20 equ 10 tm26 equ 13 tm46 equ 23 tm80 equ 40 tm86 equ 43 tm400 equ 200 tm480 equ 240 bloknot equ 0x30 ; подставляется адрес начала поля копии блокнота ; обычно по старому правилу в области 0х30-0х39 port_mlan equ P3 ; переприсвоение порта ; ; ---------- регистры ---------- ; .DSEG cntp_mlan: .ds 1 ; счетчик длины пакета cntb_mlan: .ds 1 ; счетчик бит приемника/передатчика байта cntt_mlan: .ds 1 ; счетчик задержки (djnz cntt_mlan,$ = 2машинных цикла) ; ; ---------- флаги ---------- ; .BSEG erd_mlan: .dbit 1 ; флаг ошибки "линия mLAN не отвечает" ; в области флагов ошибок ecrc_mlan: .dbit 1 ; флаг ошибки при проверке CRC кода пакета mLAN ; в области флагов ошибок ; ; ----- собственно утилиты ----- ; .CSEG ; ;---------- ; ; DTTC - генератор импульса reset термодатчика и проверка импульса ; "присутствия" dttc: clr port_mlan.dat_mlan mov cntt_mlan,#tm480 djnz cntt_mlan,$ setb port_mlan.dat_mlan ; более удачным является контроль импульса присутствия ; через каждые 10 мкС с последующим ожиданием его отключения ; ведомым прибором mov cntb_mlan,#tm80 ; в данном случае можно использовать mlatw: mov cntt_mlan,#tm20 djnz cntt_mlan,$ ; тайм-аут 10мкс mov c,port_mlan.dat_mlan ;проверка отзыва через каждые 10 мкС за 400 мкС jnc mlatw1 ; ловушка "нуля" отзыва датчика djnz cntb_mlan,mlatw setb erd_mlan ; ошибка "датчик не отвечает" ret mlatw1: mov c,port_mlan.dat_mlan jnc mlatw1 ; ждать конец импульса присутствия ret ; ;---------- ; ; приемник байта в стандарте сетей microLAN ; вызов acall rxb1 ; по выходу принятый байт в регистре А rxb1: mov cntb_mlan,#8 loopr1: clr port_mlan.dat_mlan nop nop nop setb port_mlan.dat_mlan mov cntt_mlan,#tm26 djnz cntt_mlan,$ mov c,port_mlan.dat_mlan rrc a ; текущий бит в А mov cntt_mlan,#tm46 djnz cntt_mlan,$ djnz cntb_mlan,loopr1 ret ; ;---------- ; ; передатчик байта в стандарте сетей microLAN ; перед вызовом передаваемый байт разместить в А ; вызов acall txb1 txb1: mov cntb_mlan,#8 loopt1: clr port_mlan.dat_mlan nop nop nop rrc a mov port_mlan.dat_mlan,c mov cntt_mlan,#36 djnz cntt_mlan,$ djnz cntb_mlan,loopt1 ret ; ;---------- ; ; CRC - КОНТРОЛЬ ; блок данных предварительно размещается в r30-r38 РПД ; используется R7,R5,R3,R2 и R0 текущего регистрового банка crck: clr ecrc_mlan clr a mov r7,a mov r0,#bloknot mov r2,#9 crcl: mov a,@r0 mov r5,a mov r3,#8 crclp: xrl a,r7 rrc a mov a,r7 jnc zero_m xrl a,#0x18 zero_m: rrc a mov r7,a mov a,r5 rr a mov r5,a djnz r3,crclp inc r0 djnz r2,crcl clr a adda,r7 jz wcrc setb ecrc_mlan wcrc: ret ; ;---------- ;
и набросок-заготовка под АВР (не помню проверял ли на практике... ): Спойлер
Код:
; ; av_mlan.asm ; ; файл-заготовка модуля обмена сети uLAN ; для МК семейства АВР при системной ; тактовой частоте 1 МГц и ; "трехпроводной" (полной) схеме ; соединительной линии ; ;_____ ;таблица обьявленных имен - пользовательские константы ; .equ m_cfg9 = 0b00011111 ; разрешение 9 бит, время преобразования 93,75 mS .equ m_cfg10 = 0b00111111 ; разрешение 10 бит, время преобразования 187,5 mS .equ m_cfg11 = 0b01011111 ; разрешение 11 бит, время преобразования 375 mS .equ m_cfg12 = 0b01111111 ; разрешение 12 бит, время преобразования 750 mS .equ mk_conv_t = 0x44 ; CONVERT_T команда запуска преобразования температуры .equ mk_rd_spad = 0xBE ; READ_SCRATCHPAD команда чтения "блокнота" из DS18B20 .equ mk_wr_spad = 0x4E ; WRITE_SCRATCHPAD команда записи Th:Tl:Config ; в блокнот DS18B20 .equ mk_wr_eep = 0x48 ; COPY_SCRATCHPAD команда записи Th:Tl:Config ; из блокнота DS18B20 в EEPROM DS18B20 .equ mk_rd_eep = 0xB8 ; RECALL_E2 команда чтения Th:Tl:Config ; из EEPROM DS18B20 в блокнота DS18B20 .equ mk_skip_rom = 0xCC ; SKIP_ROM команда ; "не выполнять персональную адресацию" ; применяется преамбулой во всех блоках ; обмена при одиночном датчике .equ mk_read_rom = 0x33 ; READ_ROM чтение из DS18B20 группового кода изделия ; и индивидуального номера (пакет из 8 байт в составе ; байт family code, 6 байт serial number и байт CRC) ;
.equ uL_dat = 6 ; линия порта обмена, используемого для uLAN #define uL_port PORTD ; имя порта вывода, используемого для uLAN #define uL_pin PIND ; имя порта ввода, используемого для uLAN #define uL_ddr DDRD ; имя порта DDR, используемого для uLAN
;_____ ;таблица обьявленных имен - переназначение регистров РОН ; #ifndef disposit ; принята базовая модель: ; область ограниченного функционала ; .def mfr0 = r0 ; (математика и обмен с ПЗУ/самопрограммирование) ; .def mfr1 = r1 ; (математика и обмен с ПЗУ/самопрограммирование) .def s_sreg = r2 ; зеркало SREG(ограниченный функционал) ; .def sys_flag = r3 ; системные флаги(ограниченный функционал) ; .def = r4 ; (ограниченный функционал) ; .def = r5 ; (ограниченный функционал) ; .def = r6 ; (ограниченный функционал) ; .def = r7 ; (ограниченный функционал) ; ; .def = r8 ; (ограниченный функционал) ; .def = r9 ; (ограниченный функционал) ; .def = r10 ; (ограниченный функционал) ; .def = r11 ; (ограниченный функционал) ; .def = r12 ;(ограниченный функционал) ; .def = r13 ;(ограниченный функционал) ; .def = r14 ;(ограниченный функционал) ; .def = r15 ;(ограниченный функционал) ; ; область полного функционала .def tmp0 = r16 ; рабочий регистр(полный функционал) .def tmp1 = r17 ; рабочий регистр(полный функционал) .def tmp2 = r18 ; рабочий регистр(полный функционал) .def tmp3 = r19 ; рабочий регистр(полный функционал) .def tmp4 = r20 ; рабочий регистр(полный функционал) .def tmp5 = r21 ; рабочий регистр(полный функционал) .def tmp6 = r22 ; рабочий регистр(полный функционал) .def tmp7 = r23 ; рабочий регистр полный функционал) ; .def Bl = r24 ; "указатель базы"(полный функционал) .def Bh = r25 ; "указатель базы"(полный функционал) ; Xl = r26 ; адрес сегмента Х (полный функционал) ; Xh = r27 ; адрес сегмента Х (полный функционал) ; Yl = r28 ; адрес сегмента Y (полный функционал) ; Yh = r29 ; адрес сегмента Y (полный функционал) ; Zl = r30 ; адрес сегмента Z (полный функционал ПЗУ/самопрограммирование) ; Zh = r31 ; адрес сегмента Z (полный функционал ПЗУ/самопрограммирование) ; регистры Xh:Xl, Yh:Yl, Zh:Zl определены в дефайне изготовителя и в системе команд ; изменение их имени хотя и возможно, но нежелательно - ; возникает путаница с интегрированной абревиатурой системы команд ; в случае с "малой моделью" допускающей/достаточной для размещения ВСЕХ ; используемых ВСЕМИ подпрограммами регистров в области СОЗУ регистрового ; файла одновременно (без "подкачки" наборов параметров через ОЗУ) ; рекомендовано переназначение индивидуальных имен регистров ; согласно текущей задачи ; .dseg s_pad: .byte 16
#endif ;_____ ;таблица обьявленных имен - секция переназначения регистров ; #define data_mlan tmp0 ; РВХ данных обмена #define cntt_mlan tmp1 ; счетчик длины пакета #define cntb_mlan tmp2 ; счетчик бит приемника/передатчика байта #define cntp_mlan tmp3 ; счетчик задержки #define flag_mlan tmp4 ; оперативные флаги для m_flag #define remd_mlan tmp1 ; остаток в CRC контроле ;_____ ;таблица обьявленных имен - секция флагов пользователя ; .equ erkz_mlan = 0 ; флаг ошибки "КЗ линии mLAN" ; в области флагов ошибок .equ ernd_mlan = 1 ; флаг ошибки "линия mLAN не отвечает" ; в области флагов ошибок .equ ecrc_mlan = 2 ; флаг ошибки при проверке CRC кода пакета mLAN ; в области флагов ошибок ;_____ ;таблица обьявленных имен - секция определенных данных (ОЗУ) ; ; целевое именование проводится в программе обработки через: #define gradus_l s_pad ; младший байт текущей температуры #define gradus_h s_pad+1 ; старший байт текущей температуры #define th_us1 s_pad+2 ; уставка термостата максимальный порог ;/пользовательский байт #define tl_us2 s_pad+3 ; уставка термостата минимальный порог ;/пользовательский байт #define m_cfg s_pad+4 ; байт конфигурации датчика DS18B20 #define m_res0 s_pad+5 ; резерв, всегда 0xFF #define m_res1 s_pad+6 ; резерв, всегда 0x0C #define m_res2 s_pad+7 ; резерв, всегда 0x10 #define m_crc s_pad+8 ; контрольная сумма пакета #define m_flag s_pad+9 ; флаги результата обмена ; ;_____ ;таблица обьявленных имен - секция определенных данных (EEPROM) ; ; .eseg ; ; ;---------- ; local macros ; ; m_start_pak ; макрос запуска стекера пакетных блоков обмена с uLAN ; .macro m_start_pak cli push tmp0 ; сохранить РВХ данных обмена push tmp1 ; сохранить счетчик длины пакета rcall m_start .endm ; ; m_stop_pak ; макрос завершения стекера пакетных блоков обмена с uLAN ; .macro m_stop_pak rcall m_stop pop tmp1 ; восстановить РВХ данных обмена pop tmp0 ; восстановить счетчик длины пакета sei .endm ; ;---------- ;
.cseg
;---------- ; ; участок вызова функций драйвера обмена ; m_start: ; во внешней программе перед вызовом call m_start ; cli ставится при исполнении блока обмена ; - crc контроль защиту не требует pop tmp1 ; считать адрес возврата h pop tmp0 ; считать адрес возврата h push s_sreg in s_sreg,SREG ;push tmp0 ; РВХ данных обмена ;push tmp1 ; счетчик длины пакета push tmp2 ; счетчик бит приемника/передатчика байта push tmp3 ; счетчик задержки push tmp4 ; оперативные флаги для m_flag push Xl push Xh push tmp0 ; восстановить адрес возврата l push tmp1 ; восстановить адрес возврата h ret ; m_stop: pop tmp1 ; считать адрес возврата h pop tmp0 ; считать адрес возврата h pop Xh pop Xl pop tmp4 pop tmp3 pop tmp2 ;pop tmp1 ;pop tmp0 out SREG,s_sreg pop s_sreg ; во внешней программе перед вызовом call m_stop ; sei ставится в случае, если при вызове было выполнено cli push tmp0 ; восстановить адрес возврата l push tmp1 ; восстановить адрес возврата h ret ; ;---------- ; ; фрагмент системного init подготовки линий порта обмена ; по reset при подаче питания на МК по умолчанию ; uL_dat = вход с Z состоянием (внешняя подтяжка к 1) ; и ; uL_port.uL_dat = 0 - подготовлено к выдаче uL_dat=0 ; m_linap: cbi uL_ddr,uL_dat ; uL_dat = вход с Z состоянием (внешняя подтяжка к 1) cbi uL_port,uL_dat ; uL_port.uL_dat = 0 - подготовлено к выдаче uL_dat=0 ret
; ;---------- ; ; системные задержки протокола при тактовой в 1МГц ; 0,000001 S/одноцикловую команду ; m_t15: nop ; совместно с RCALL m_t15 обеспечивает задержку в 15uS nop nop nop m_t11: nop nop ; совместно с RCALL m_t10 обеспечивает задержку в 10uS nop nop ret ; при системной частоте 1 МГц ; m_t480: ldi cntt_mlan,32 ; 32*15=480 задержка ~480uS tl480: rcall m_t15 dec cntt_mlan brne tl480 ret ; ;---------- ; ; m_dttc - генератор импульса reset термодатчика и проверка ; импульса "присутствия" ; (начальная настройка линии обмена и резервирование ; данных уже предварительно выполнено) ; по выходу возвращает статус ошибок в регистре flag_mlan ; erkz_mlan=1 ошибка "КЗ линии mLAN" ; ernd_mlan=1 ошибка "линия mLAN не отвечает" ; или flag_mlan = 0 при благополучном завершении ; m_dttc: clr flag_mlan ; сброс флагов ошибок sbi uL_ddr,uL_dat ; uL_dat=0 rcall m_t480 cbi uL_ddr,uL_dat ; uL_dat=Z с подтяжкой к 1 ; контроль импульса присутствия через каждые 10 мкС ; с последующим ожиданием его отключения ведомым прибором ldi cntt_mlan,16 ; ~240uS ожидания l_dttc: rcall m_t15 sbis uL_pin,uL_dat ; продолжаем до исчерпания если uL_dat=1 rjmp quit_m0 ; обработка положительного ответа uL_dat=0 dec cntt_mlan brne l_dttc ldi flag_mlan,(1<<ernd_mlan) ; запись флага ошибки ; "датчик не отвечает" (uL_dat=1) ret ; выход по ошибке "датчик не отвечает" (uL_dat=1) quit_m0: ldi cntt_mlan,16 ; ~240uS ожидания l_dttc1: rcall m_t15 sbic uL_pin,uL_dat ; продолжаем до исчерпания если uL_dat=0 rjmp quit_m1 ; обработка положительного ответа uL_dat=1 dec cntt_mlan brne l_dttc1 ldi flag_mlan,(1<<erkz_mlan) ret ; выход по ошибке "КЗ линии mLAN" (uL_dat=0) quit_m1: ldi cntt_mlan,27 l_dttc2: rcall m_t15 ; защитная задержка ~405uS dec cntt_mlan brne l_dttc2 ret ; ; ;---------- ; ; приемник байта в стандарте сетей microLAN ; вызов call m_rxb ; по выходу принятый байт в регистре data_mlan ; uL_dat = вход Z с внешней подтяжкой к 1 ; m_rxb: ldi cntb_mlan,8 m_rxb_L: nop ; интервал между слотами в 2 uS sbi uL_ddr,uL_dat ; uL_dat=0 активирован запрос слота nop ; rcall m_t11 cbi uL_ddr,uL_dat ; через 12uS снимаем запрос слота 2tci nop ; uL_dat=1 nop ; nop ; задержка установки уровня rcall m_t11 sbic uL_pin,uL_dat ; 1tci no skip, 2tci sec ; 1tci sbis uL_pin,uL_dat ; 1tci no skip, 2tci clc ; 1tci чтение данных в середине слота (~30uS) rcall m_t15 rcall m_t11 ; дорабатываем 60uS ror data_mlan ; 1tci dec cntb_mlan ; 1tci brne m_rxb_L ; 1 false 2 true ret ; 4tci ; ;---------- ; ; передатчик байта в стандарте сетей microLAN ; перед вызовом передаваемый байт разместить ; в data_mlan ; вызов call m_txb ; по выходу ; uL_dat = вход Z с внешней подтяжкой к 1 ; m_txb: ldi cntb_mlan,8 m_txb_L: nop ; интервал между слотами в 2 uS sbi uL_ddr,uL_dat ; uL_dat=0 активирован запрос слота ror data_mlan ; 1tci интервал между слотами в 2 uS rcall m_t11 brcc m_txb_i ; 1tci/2tci обход при С=0 cbi uL_ddr,uL_dat ; 1tci иначе ставим 1 m_txb_i: nop nop rcall m_t15 rcall m_t15 rcall m_t11 cbi uL_ddr,uL_dat ; 1tci иначе ставим 1 dec cntb_mlan ; 1tci brne m_txb_L ; 1 false 2 true ret ; 4tci ; ; ;---------- ; ; модуль обработки CRC8 uLAN DALLAS ; и вариант CRC7 как частный случай ; блок данных предварительно размещается в s_pad ОЗУ ; исходные данные НЕ РАЗРУШАЮТСЯ! ; обрабатывается как проверка так и генерация CRC ; с подстановкой в конце дампа пакета ; возвращает флаг "ошибка CRC" =0 или =1(при ошибке) ; при генерации байт CRC подставляется ; в m_crc области s_pad ОЗУ ; crcg7: set ldi cntp_mlan,7 rjmp crcg crcg8: set ldi cntp_mlan,8 rjmp crcg crck7: ldi cntp_mlan,8 rjmp crck crck8: ldi cntp_mlan,9 crck: clt crcg: clr flag_mlan ldi Xl,low(s_pad) ldi Xh,high(s_pad) clr remd_mlan ; результат big_lp: ld tmp0,x+ ; читаем текущий байт данных в tmp0 push tmp0 ; и копируем его же в стек ldi cntb_mlan,8 ; счетчик бит =8 low_lp: eor tmp0,remd_mlan ; xor битов 0, результат в tmp0 ror tmp0 ; результат xor битов 0 накопителя результата ; и текущих данных передан в С brbc SREG_C,crcpt0 ; в зависимости от результата по биту 0 ; или уходим в завершение crcpt0 ldi tmp0,0x18 eor remd_mlan,tmp0 ; или ксорим второй узел crcpt0: ror remd_mlan ; результат сдвигаем вправо с учетом СY pop tmp0 ; загружам исходные данные ror tmp0 ; кольцевой сдвиг исходных данных, ; что поступило в старший бит безразлично push tmp0 ; отправляем текущий результат сдвига в стек ; и оставляем в tmp0 dec cntb_mlan ; счетчик бит -1 brne low_lp pop tmp0 ; корректор указателя стека dec cntp_mlan ; счетчик байт пакета -1 brne big_lp brtc crc_k ; если Т=0 - завершаем как тест clt ; сброс Т st x,remd_mlan ; запись результата в ячейку CRC s_pad ret crc_k: tst remd_mlan ; проверка результата breq crcpt1 ; jz - norma sbr flag_mlan,(1<<ecrc_mlan) ; иначе ecrc_mlan=1 "ошибка crc" crcpt1: ret ; ; ;---------- ; ; командный пакет запуска преобразования ; term_start: m_start_pak ; храним предыдущий контент в стеке rcall m_dttc tst flag_mlan ; при flag_mlan не равном 0 brne m_error ; перейти к обработчику ошибок ldi data_mlan,mk_scip_rom rcall m_txb ldi data_mlan,mk_conv_t rcall m_txb m_stop_pak ret ;
; ; ;---------- ; ; ***********!!!!!!!*********** ; ; определение #define red_error_proc ; есть внешнее - должно находится ОБЯЗАТЕЛЬНО ; ранее точки подключения файла, его исользующего ; при анализе ( выше по тексту, чем размещено ; .include "av_ulan.txt" ) ;
#warning "not defined EXTERN red_error_proc for uLan libr" ;#error "not defined EXTERN red_error_proc for uLan libr" ;#message "not defined red_error_proc for uLan"
m_error_s: rjmp m_error_s ; пока заблокировано для тест-отладки ; в рабочей программе тут устанавливается переход ; на немедленную обработку ошибки "датчик не отвечает" #endif
; после вывода сообщения "E 0-LAn" ; возврат до следующего запроса канала uLAN ; ( упрощенный вариант ) или переход к ; соответствующим абсолютным блокировкам системы ; по критичным параметрам
; ;---------- ; ; командный пакет чтения текущих данных блокнота ; по выходу данные в блокноте, флаг ecrc_mlan ; сохранен в m_flag области s_pad ; m_rd9: m_start_pak ; храним предыдущий контент в стеке ldi cntp_mlan,9 ; загружен счетчик байт пакета ldi Xl,low(s_pad) ldi Xh,high(s_pad) ; загружен указатель на начало блокнота rcall m_dttc tst flag_mlan ; при flag_mlan не равном 0 brne m_error ; перейти к обработчику ошибок ldi data_mlan,mk_scip_rom rcall m_txb ldi data_mlan,mk_rd_spad rcall m_txb m_rd9_L: rcall m_rxb st x+,data_mlan dec cntp_mlan brne m_rd9_L rcall crck8 st x,flag_mlan ; флаг ошибки СRC лежит в m_flag области s_pad m_stop_pak ret ;
oleg110592, все, вы были правы, разобрался, тольковсего лишь в одном мсте оказался этот затык: я после подачи импульса сброса на датчик сразу начинаю опрос линии - ожидаю нуль, но похоже после команды установки разряда на вход - уровень с нуля на единицу не успевает подняться, а я уже его опрашиваю, а потом единицу жду после окончания импульса ответа датчика, а получаю единицу перед ответом датчика, а датчик отвечает до 250 мкс ,да плюс время на готовность потому и нужна была большая задержка, в итоге или сделать там небольшую задержку, или сначала разряд перевести в 1, а потом уже переводить на прием.
...atmega8a к выводам РС0 и РС1 подключены по 1 датчику ds18b20,
Для atmega8(a) подключать AVcc к Vcc нужно.
Цитата:
AVCC is the supply voltage pin for the A/D Converter, Port C (3..0), and ADC (7..6). It should be externally connected to VCC, even if the ADC is not used... Note that Port C (5..4) use digital supply voltage, VCC.
для тех, кто в танке еще раз повторяю: для работы с ds18b20 вообще не требуется подавать питание на AVCC. достаточно внешней подтяжки к питанию резистором. лично у меня сделано именно так - для работы с ds18b20 на AVCC питание не подано. и прекрасно работает.
_________________ Мудрость приходит вместе с импотенцией... Когда на русском форуме переходят на Вы, в реальной жизни начинают бить морду.
Довольно рискованное "отступление", но оправдано если от AVCC питается только верхняя часть выходного каскада. Да и при небольшом номинале резистора возможна "паразитная подпитка" - мы полной схемы все равно не знаем. А вот "ключ на землю" в любом случае сработать может... Типичный прием для аврки с шиной ОК - записываем в port 0, а коммутацию делаем через DDR - на выход = 0, на вход = 1(через внешнюю подтяжку).
akl, я обычно питание везде подаю, тут только - ножку перепутал ,но все одно проблема была не в этом... BOB51, подтяжка есть , единицу подаю - переходом разряда на вход
вот именно. записываем 0 - вход - на выводе 1 через подтяжку. записываем 1 - выход - на выводе 0 или 1 через подтяжку, в зависимости от значения передаваемого бита.
_________________ Мудрость приходит вместе с импотенцией... Когда на русском форуме переходят на Вы, в реальной жизни начинают бить морду.
Вы не можете начинать темы Вы не можете отвечать на сообщения Вы не можете редактировать свои сообщения Вы не можете удалять свои сообщения Вы не можете добавлять вложения