|
Датчик DS18B20, Нужен совет |
|
|
2 страниц
1 2 >
|
 |
Ответов
(1 - 24)
|
Sep 14 2010, 23:41
|
Группа: Новичок
Сообщений: 9
Регистрация: 25-02-09
Пользователь №: 45 328

|
Цитата(Letis @ Sep 15 2010, 00:11)  У меня проблема следующего характера. К микроконтроллеру Mega8535 подключены 4 датчика DS18B20. Но я их не могу подключить на одну линию, так как нужно считывать адреса, а датчики розмещены в разных местах, ну в общем, этот вариант мне не подходит. Тогда я решил разместить датчики на одном порте на на разных линиях. Но когда дело дошло дело до программирования (Code Vision), у меня ничего не получается. Вот так я подключаю первый датчик #asm .equ __w1_port=0x12 ;PORTD .equ __w1_bit=0 #endasm Считываю те-ру и хочу сменить адрес шины: #asm .equ __w1_port=0x12 ;PORTD .equ __w1_bit=1 #endasm Но при компиляции выбивает ошибку. Посоветуйте, что делать.
Как повесить 4 датчика DS18B20 на разные ноги контроллера ? Так не пройдет без чтения кодов не обойтись.
|
|
|
|
|
Sep 15 2010, 10:35
|

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

|
Цитата(Letis @ Sep 15 2010, 12:42)  Например ? Например что? Поискать для вас ветку "исходники программ и библиотек"? Вот: http://electronix.ru/forum/index.php?showtopic=10934 Искать в ней за вас не буду.
--------------------
На любой вопрос даю любой ответ"Write code that is guaranteed to work, not code that doesn’t seem to break" ( C++ FAQ)
|
|
|
|
|
Sep 15 2010, 17:04
|
Группа: Участник
Сообщений: 14
Регистрация: 15-09-10
Пользователь №: 59 507

|
У меня такая проблема. Писал код "с нуля" на ассемблере, все согласно даташиту. В итоге датчик реагирует, но как то странно. При включении показывает температуру +85 С(0550h в первых двух считанных байтах, затем считывание прекращаю, подавая "ресет" ). Насколько я понял, так и должно быть, НО затем он начинает фиксировать изменения температуры относительно этого значения, как будто калибруется при подаче питания. И еще одна странность - младший бит байта 0 - всегда ноль, т.е. при нагреве (если коснуться датчика пальцами) температура начинает расти так - 0550h,0552h,0554h и т.д. Перепроверял все по нескольку раз, симулировал в Proteus - работает как надо, уже грешу на датчик. Может кто сталкивался?
|
|
|
|
|
Sep 15 2010, 17:22
|

Профессионал
    
Группа: Свой
Сообщений: 1 940
Регистрация: 16-12-07
Из: Москва
Пользователь №: 33 339

|
Цитата(zalg @ Sep 15 2010, 21:04)  При включении показывает температуру +85 С(0550h в первых двух считанных байтах, затем считывание прекращаю, подавая "ресет" ). Насколько я понял, так и должно быть, НО затем он начинает фиксировать изменения температуры относительно этого значения, как будто калибруется при подаче питания. И еще одна странность - младший бит байта 0 - всегда ноль, т.е. при нагреве (если коснуться датчика пальцами) температура начинает расти так - 0550h,0552h,0554h и т.д. Перепроверял все по нескольку раз, симулировал в Proteus - работает как надо, уже грешу на датчик. Может кто сталкивался? Считывание Вы остановили , а конвертацию запустили? И дайте код посмотреть.
--------------------
Закон Мерфи:
Чем тщательнее составлен проект, тем больше неразбериха, если что-то пошло не так
|
|
|
|
|
Sep 15 2010, 17:37
|
Группа: Участник
Сообщений: 14
Регистрация: 15-09-10
Пользователь №: 59 507

|
Опыт программирования у меня не большой, так что замечаниям по поводу оформления кода буду благодарен. CODE .include "m8535def.inc"
.equ clk = 0 .equ data = 1 .equ load = 7
.def hexL = r16 ; Младший байт шестнадцатиричного слова .def hexH = r17 ; Старший байт шестнадцатиричного слова .def hexHH = r18 ; Самый старший байт шестнадцатиричного слова .def BCD0 = r22 ; BCD- разряды 2 и 1 .def BCD1 = r23 ; BCD- разряды 4 и 3 .def BCD2 = r24 ; BCD- разряды 6 и 5 .def BCD3 = r25 ; BCD- разряды 8 и 7
.def cnt = r19 ; Счетчик .def tmp1 = r20 ; Рабочий регистр
;-------------------------------------------------------------- .ORG 0x0 ;?????? ?????? ?? RESET rjmp RESET ; Reset Handler rjmp EXT_INT0 ; IRQ0 Handler rjmp EXT_INT1 ; IRQ1 Handler rjmp TIM2_COMP ;TIM2_COMP Timer2 Compare Handler rjmp TIM2_OVF ; Timer2 Overflow Handler rjmp TIM1_CAPT ; Timer1 Capture Handler rjmp TIM1_COMPA ; Timer1 Compare A Handler rjmp TIM1_COMPB ; Timer1 Compare B Handler rjmp TIM1_OVF ; Timer1 Overflow Handler rjmp TIM0_OVF ; Timer0 Overflow Handler rjmp SPI_STC ; SPI Transfer Complete Handler rjmp USART_RXC ; USART RX Complete Handler rjmp USART_UDRE ; UDR Empty Handler rjmp USART_TXC ; USART TX Complete Handler rjmp ADC_ ; ADC Conversion Complete Handler rjmp EE_RDY ; EEPROM Ready Handler rjmp ANA_COMP ; Analog Comparator Handler rjmp TWSI ; Two-wire Serial Interface Handler rjmp EXT_INT2 ; IRQ2 Handler rjmp TIM0_COMP ; Timer0 Compare Handler rjmp SPM_RDY ; Store Program Memory Ready Handler
RESET: ldi r16,high(RAMEND) ; Main program start out SPH,r16 ; Set Stack Pointer to top of RAM ldi r16,low(RAMEND) out SPL,r16
Start:
rcall INIT_PORTS ;rcall INIT_UART ;rcall getc ;for test comunication - nullmodem ;rcall putc
;ldi r16, 0x80 ;out GICR, r16 ;out GIFR, r16
;ldi r18, 0x01 ;ldi r19, 0x03
main: ;ttest3: ;sbic PinD,2 ;rjmp ttest3 rcall Init rcall SkipROM rcall ConvertT rcall Init rcall SkipROM rcall ReadScratchpad ;ldi r27,0x17 ;ldi r26,0x15
;lsr r27 ;ror r26
mov r18,r27 mov r19,r27 andi r18,0x0f andi r19,0xf0
lsr r19 lsr r19 lsr r19 lsr r19
mov r16,r19 ldi r17,0x08 rcall CIFRA rcall CIFERBLAT
mov r16,r18 ldi r17,0x08 rcall CIFRA rcall CIFERBLAT
mov r20,r26 mov r21,r26 andi r20,0x0f andi r21,0xf0
lsr r21 lsr r21 lsr r21 lsr r21
mov r16,r19 ldi r17,0x08 rcall CIFRA rcall CIFERBLAT
mov r16,r18 ldi r17,0x08 rcall CIFRA rcall CIFERBLAT
ttest: rjmp ttest
;rcall DataOut
rjmp main
/*---------------------------Write Time Slots----------------------------*/
write0: in r16,DDRC ori r16,0x04; !!!?????????!! out DDRC, r16 cbi PortC,2 ldi r16, 0x23;70us rcall TmrDelay in r16,DDRC andi r16,0xfb out DDRC, r16; release line
rcall delay_15us
ret
write1: in r16,DDRC ori r16,0x04 out DDRC, r16 cbi PortC,2
ldi r16, 0x03; 6us rcall delay in r16,DDRC andi r16,0xfb out DDRC, r16; release line
ldi r16, 0x23;70us rcall TmrDelay ret
/*------------------------Read Time Slots-------------------------------*/ read: in r16,DDRC ori r16,0x04 out DDRC, r16 cbi PortC,2 ldi r16, 0x02; 4us rcall delay in r16,DDRC andi r16,0xfb out DDRC, r16; release line
ldi r16, 0x02; 4us rcall delay sbic PinC,2 ori r22,0x80 ldi r16, 0x30; 50us rcall TmrDelay
ret
read_1byte: ldi r21,0x08 ldi r22,0x00
loop_1byte: lsr r22 rcall read dec r21 cpi r21,0x00 brne loop_1byte ret /*------------------------------------------------------------------------*/
Init: in r16,DDRC ori r16,0x04; !!!?????????!! out DDRC, r16
ldi r16,0xf0;480us cbi PortC,2 rcall TmrDelay; Reset pulse
in r16,DDRC andi r16,0xfb; !!!?????????!! out DDRC, r16; release line
ldi r16,0x28;80us rcall TmrDelay
sbic PinC,2;Presence pulse rcall Error
ldi r16,0xc8;400us rcall TmrDelay
sbis PinC,2;check if the sensor has released line rcall Error
ret
Send: ldi r21,0x08 start1: ror r20 brcs wr rcall write0 dec r21 cpi r21, 0x00 breq end1 rjmp start1 wr: rcall write1 dec r21 cpi r21, 0x00 breq end1 rjmp start1 end1: ret
SkipROM:;CCh ldi r20,0xcc rcall Send ret
ReadScratchpad:;BEh ldi r20,0xBE rcall Send
reading:
rcall read_1byte mov r26,r22
rcall read_1byte mov r27,r22
rcall Init
ret
ConvertT:;44h ldi r20,0x44 rcall Send in r16,DDRB ori r16,0x08 out DDRB, r16 cbi PortB,3;switch LED
ldi r22,0x00 converting: rcall read cpi r22,0x00 breq converting
in r16,DDRB andi r16,0xf7 out DDRB, r16 cbi PortB,3;turn off LED ret
ConfTmr0:
ldi r17,0x02 out TIMSK, r17;Compare Match interrupt is enabled out OCR0,r16 sei
ldi r17,0x0a out TCCR0,r17;CTC Mode, T=2us ret
TmrDelay: subi r16,6 rcall ConfTmr0 ldi r18,0x00 loop9: cpi r18, 0xff brne loop9 cli
nop ;correction nop nop ret
Error: go: ldi r17,0x00 ldi r16, 0x08 out DDRB, r16 cbi PortB,3;switch LED rjmp go ret
delay: loop1: dec r16 cpi r16,0x00 nop brne loop1 ret
delay_15us: ldi r16, 0x06 loop_15us: dec r16 cpi r16,0x00 nop brne loop1 ret /*---------functions for debugging-----------------------------*/
switch_LED:
loop_LED: ldi r16, 0x08 out DDRB, r16 cbi PortB,3;switch LED rjmp loop_LED ret
CIFRA: cpi r16, 0x00 breq L0 cpi r16, 0x01 breq L1 cpi r16, 0x02 breq L2 cpi r16, 0x03 breq L3 cpi r16, 0x04 breq L4 cpi r16, 0x05 breq L5 cpi r16, 0x06 breq L6 cpi r16, 0x07 breq L7 cpi r16, 0x08 breq L8 cpi r16, 0x09 breq L9 cpi r16, 0x0A breq LA cpi r16, 0x0B breq LB cpi r16, 0x0C breq LC cpi r16, 0x0D breq L0D cpi r16, 0x0E breq LE cpi r16, 0x0F breq LF L0: ldi r16,0xC0 ret L1: ldi r16,0xF9 ret L2: ldi r16,0xA4 ret L3: ldi r16,0xB0 ret L4: ldi r16,0x99 ret L5: ldi r16,0x92 ret L6: ldi r16,0x82 ret L7: ldi r16,0xF8 ret L8: ldi r16,0x80 ret L9: ldi r16,0x90 ret LA: ldi r16,0x88 ret LB: ldi r16,0x83 ret LC: ldi r16,0xC6 ret L0D: ldi r16,0xA1 ret LE: ldi r16,0x86 ret LF: ldi r16,0x8E ret
CIFERBLAT: lsl r16 brcs SS1 cbi PortC, data cbi PortC, clk sbi PortC, clk rjmp End_SS SS1: sbi PortC, data cbi PortC, clk sbi PortC, clk End_SS: dec r17 cpi r17, 0x00 brne CIFERBLAT ret
HexBCD: ; xxxx (Hex) -> 0abcde (BCD) rcall Div10 ; hexH:hexL / 10, ??????? - ? tmp1 mov BCD0,tmp1 ; ????????? - ? hexH:hexL, tmp1 = ?????? 1 rcall Div10 ; ??????? = ?????? 2 swap tmp1 ; ?????? 2 – ? ??????? ???????? or BCD0,tmp1 ; ?????????? ??????? 2 ? 1 ? BCD0 rcall Div10 ; ??????? = ?????? 3 mov BCD1,tmp1 ; ? BCD1 rcall Div10 ; ??????? = ?????? 4 swap tmp1 ; ?????? 4 – ? ??????? ???????? or BCD1,tmp1 ; ?????????? ??????? 4 ? 3 ? BCD1 rcall Div10 ; ??????? = ?????? 5 mov BCD2,tmp1 ; ? BCD2 rcall Div10 ; ??????? = ?????? 6 swap tmp1 ; ?????? 6 – ? ??????? ???????? or BCD2,tmp1 ; ?????????? ??????? 6 ? 5 ? BCD2 rcall Div10 ; ??????? = ?????? 7 mov BCD3,tmp1 ; ? BCD3 rcall Div10 ; ??????? = ?????? 8 swap tmp1 ; ?????? 8 – ? ??????? ???????? or BCD3,tmp1 ; ?????????? ??????? 6 ? 5 ? BCD3 ret
Div10: ; ??????? hexHH:hexH:hexL ?? 10, ; ????????? – ? hexHH:hexH:hexL, ??????? - ? tmp1 clr tmp1 lsl hexL rol hexH rol hexHH; rol tmp1 ; ??????? ??????? ???? ???????? ?? 10 lsl hexL ; ????? ???? ? ?????????? rol hexH ; ?????? 0 rol hexHH rol tmp1 lsl hexL rol hexH rol hexHH rol tmp1 ldi cnt,21 ; ??????? ??? ?????????? 21 ????????s Loop10: lsl hexL ; ????? ???????? ????? ?? 1 ?????? rol hexH rol hexHH rol tmp1 ; ???????????? ? tmp1 subi tmp1,10 ; ????????: ???????????? > 10 ? brlo HB1 ; ???????, ???? ??? inc hexL ; ??????????? ??????? ??????? ?? 1 rjmp HB2 HB1: subi tmp1,-10 ; ????????? ???????? ???????? HB2: dec cnt ; ?????????????? ??????? ???????? brne Loop10 ; ???????, ???? ??? ?? ??? ??????? ret
DataOut: lsl r27 lsl r27 lsl r27 lsl r27 lsl r27 lsr r26 lsr r26 lsr r26 or r26,r27 mov r16,r26 lsr r16 ldi r17,0x00 ldi r18,0x00 rcall HexBCD ldi r16,0x00 ldi r17,0x08 rcall CIFRA rcall CIFERBLAT
mov r16,r23 ldi r17,0x08 rcall CIFRA rcall CIFERBLAT mov r18,r22 mov r19,r22 andi r18,0x0f andi r19,0xf0 lsr r19 lsr r19 lsr r19 lsr r19 mov r16,r19 ldi r17,0x08 rcall CIFRA rcall CIFERBLAT
mov r16,r18 ldi r17,0x08 rcall CIFRA rcall CIFERBLAT
;ttest: ;rjmp ttest ret /*-------------------------------------------------------------*/
INIT_UART: ldi r16,00 out UBRRH,r16 ldi r16,25 out UBRRL,r16 ldi r16,24 ; UART for TX and RX out UCSRB,r16 ldi r16,0x86 out UCSRC,r16 ret
getc: sbis UCSRA,RXC rjmp getc in r16,UDR ret putc: sbis UCSRA,UDRE rjmp putc out UDR,r16 ret
INIT_PORTS: ldi r16, 0x00 out DDRA, r16 ;??? ?????
ldi r16, 0x00 out DDRB, r16
ldi r16, 0x03 out DDRC, r16
ldi r16, 0x10 ;??? LCD ???????, ??? LED ???????? ?? 0, 2->TXD out DDRD, r16 ret
EXT_INT0: ; IRQ0 Handler+-
reti
EXT_INT1: ; IRQ1 Handler reti main2: reti TIM2_COMP: reti ; Timer2 Compare Handler TIM2_OVF: reti ; Timer2 Overflow Handler TIM1_CAPT: reti ; Timer1 Capture Handler TIM1_COMPA: reti ; Timer1 Compare A Handler TIM1_COMPB: reti ; Timer1 Compare B Handler TIM1_OVF: reti ; Timer1 Overflow Handler TIM0_OVF: reti; Timer0 Overflow Handler SPI_STC: reti ; SPI Transfer Complete Handler USART_RXC: reti ; USART RX Complete Handler USART_UDRE: reti ; UDR Empty Handler USART_TXC: reti ; USART TX Complete Handler
ADC_: reti
EE_RDY: reti ; EEPROM Ready Handler ANA_COMP: reti ; Analog Comparator Handler TWSI: reti ; Two-wire Serial Interface Handler EXT_INT2: reti ; IRQ2 Handler TIM0_COMP: ldi r17,0x00 out TCCR0,r17 ldi r17,0x00 out TIMSK, r17 ldi r17,0x00 out TCNT0,r17;reset timer
ldi r18, 0xff
reti ; Timer0 Compare Handler SPM_RDY: reti ; Store Program Memory Ready Handler
|
|
|
|
|
Sep 16 2010, 03:04
|
Местный
  
Группа: Участник
Сообщений: 298
Регистрация: 26-01-09
Из: Пермь
Пользователь №: 43 940

|
to zalg Цитата(zalg @ Sep 15 2010, 23:04)  У меня такая проблема. Писал код "с нуля" на ассемблере, все согласно даташиту. В итоге датчик реагирует, но как то странно. При включении показывает температуру +85 С(0550h в первых двух считанных байтах, затем считывание прекращаю, подавая "ресет" ). Насколько я понял, так и должно быть, НО затем он начинает фиксировать изменения температуры относительно этого значения, как будто калибруется при подаче питания. И еще одна странность - младший бит байта 0 - всегда ноль, т.е. при нагреве (если коснуться датчика пальцами) температура начинает расти так - 0550h,0552h,0554h и т.д. Перепроверял все по нескольку раз, симулировал в Proteus - работает как надо, уже грешу на датчик. Может кто сталкивался? 1. При чтении значения (тем более при первом) необходимо дождаться завершения измерения температуры, но перед этим необходимо подать команду на старт 2. Скажите какой датчик, может у него точность измерения температуры по умолчанию задана с дискретом в один градус? 3. Лучше сделать новый топик! To Letis. Пишу с использованием WinAVR (на AVR-асме не пишу более 5 лет) В одной проге было два ds18s20 на одном порту Вот моя реализация. В вашем случае достаточно переделать макросы onew_input, onew_out_hi, onew_out_lo под большее количество датчиков В ds18s20.h Код #define DS18S_PORT PORTE #define DS18S_DDR DDRE #define DS18S_PIN PINE #define PIN_DS18S_1WR (_BV(2)) #define PIN_DS18S_1RD (_BV(3)) #define PIN_DS18S_2WR (_BV(4)) #define PIN_DS18S_2RD (_BV(5))
#define onew_input(par) (DS18S_PIN & (par ? PIN_DS18S_2RD : PIN_DS18S_1RD)) #define onew_out_hi(par) DS18S_PORT &= ~(par ? PIN_DS18S_2WR : PIN_DS18S_1WR) #define onew_out_lo(par) DS18S_PORT |= (par ? PIN_DS18S_2WR : PIN_DS18S_1WR) В ds18s20.c Код //***************************************************************************** // Layer 1 - Transmit/Receive Bit void onew_set_lo(byte ch) { byte s = SREG; cli(); onew_out_lo (ch); _delay_us (65); onew_out_hi (ch); _delay_us (10); //5 SREG = s; } //============================================================================= void onew_set_hi(byte ch) { byte s = SREG; cli(); onew_out_lo (ch); _delay_us (7); // onew_out_hi (ch); _delay_us (70); // 65 SREG = s; } //============================================================================= byte onew_get_bit(byte ch) { byte t = 0; byte s = SREG; cli(); onew_out_lo (ch); _delay_us (2); onew_out_hi (ch); _delay_us (12); //11 if(onew_input(ch)) t=1; SREG = s; _delay_us (60); //45 return t; } //============================================================================= byte onew_reset(byte ch) { byte t = 0; byte s = SREG; cli(); onew_out_lo (ch); _delay_us (480); onew_out_hi (ch); _delay_us (65); if(!onew_input(ch)) t=1; sei(); SREG = s; _delay_us (415); return t; } //*****************************************************************************
Сообщение отредактировал alexeyv - Sep 16 2010, 03:06
|
|
|
|
|
Sep 16 2010, 08:04
|
Участник

Группа: Участник
Сообщений: 18
Регистрация: 19-11-08
Из: Moscow region
Пользователь №: 41 766

|
to zalg: Если младший бит "0", может всё же проверить кофигурационную ячейку разрешения датчика
|
|
|
|
|
Sep 16 2010, 09:20
|
Частый гость
 
Группа: Участник
Сообщений: 124
Регистрация: 10-07-07
Пользователь №: 29 027

|
Цитата и сам не один вариант написал для обмена 1-wire, в том числе и для "многопортового" подключения нескольких датчиков... если надо - поищу исходники - но портировать в CVAVR не буду - это уже самостоятельно вы... Виложите пожалуста код
|
|
|
|
|
Sep 16 2010, 11:42
|

Профессионал
    
Группа: Свой
Сообщений: 1 143
Регистрация: 30-09-08
Из: Новочеркасск
Пользователь №: 40 581

|
Цитата(Letis @ Sep 16 2010, 13:20)  Виложите пожалуста код ну как бы вот... комментариев много - разберетесь, надеюсь.
Прикрепленные файлы
MyLib.rar ( 7.79 килобайт )
Кол-во скачиваний: 72
--------------------
Я бы взял частями... но мне надо сразу.
|
|
|
|
|
Sep 17 2010, 09:56
|
    
Группа: Свой
Сообщений: 1 928
Регистрация: 11-07-06
Пользователь №: 18 731

|
Цитата(Letis @ Sep 17 2010, 01:18)  Код несколько не понятен в силу того что пишу в Code Vision. І вот первый вопрос. /// УКАЗАТЕЛЬ НА ПОРТ ВВОДА-ВЫВОДА typedef volatile uint8_t* io_ptr;
ошибка: declaration syntax error. Посмотрите в мануале Code Vision, понимает ли он uint8_t. Если не понимает, то или typedef unsigned char uint8_t; или замените все uint8_t на unsigned char.
|
|
|
|
|
Sep 17 2010, 17:59
|

Местный
  
Группа: Участник
Сообщений: 318
Регистрация: 21-07-06
Из: Минск
Пользователь №: 18 986

|
Для нескольких термометров делал так: Код //---------------------------------------------------------------------------- //--------------------------- Цифровые датчики: ------------------------------ //----------------------------------------------------------------------------
//Используются термометры DS18B20 (S20), которые подключены к портам OWPn. //Считывание и повторный запуск преобразования производится //в момент считывание таходатчика того же канала. //Считываются только два байта температуры, CRC не проверяется. //Суммарное время опроса всех термометров должно быть больше //времени преобразования, т.е. длительность интервала счета тахометра //не должна быть меньше 750 мс / CHANNELS. //Считанное значение температуры заносится в массив Temp[], //температура представлена в десятых долях градуса. //Диапазон возможных температур составляет от TEMP_MIN до TEMP_MAX //градусов. При отсутствии термометра показания равны TEMP_MIN.
//------------------------------- Константы: ---------------------------------
#define OWP0 (1 << PC0) //порт цифрового термометра 0 #define OWP1 (1 << PC1) //порт цифрового термометра 1 #define OWP2 (1 << PC2) //порт цифрового термометра 2 #define OWP3 (1 << PC3) //порт цифрового термометра 3 #define OWP4 (1 << PC4) //порт цифрового термометра 4 #define OWP5 (1 << PC5) //порт цифрового термометра 5 //Направление: #define I_DDRC (0) //Подтягивающие резисторы / начальное состояние: #define I_PORTC (0) //Макроопределения для работы с портами: #define Port_OWP_0(m) (DDRC |= m) #define Port_OWP_Z(m) (DDRC &= ~m) #define Pin_OWP(m) (PINC & m)
//Маски термометров: const __flash char Masks[CHANNELS] = {OWP0, OWP1, OWP2, OWP3, OWP4, OWP5};
//------------------------------- Переменные: --------------------------------
static int Temp[CHANNELS]; //текущая температура static bool Present[CHANNELS]; //флаги присутствия термометров
//---------------------------- Прототипы функций: ----------------------------
void Start(char n); //старт термометра void Read(char n); //чиение термометра void TReset(char n); //генерация импульса сброса char TByte(char n, char dat); //запись/чтение байта bool TBit(char n, bool b); //запись/чтение бита void Do_Crc(char b, char *crc); //вычисление CRC
//------------------ Инициализация измерителя температуры: -------------------
void Therm_Init(void) { ACSR = (1<<ACD); //запрещение аналогового компаратора for(char i = 0; i < CHANNELS; i++) { Temp[i] = TEMP_MIN; //инициализация температуры Start(i); //старт всех термометров } }
//------------------------ Измерение температуры: ----------------------------
void Therm_Exe(char n) { Read(n); //чтение термометра - самое первое измерение Start(n); //старт термометра }
//-------------------------- Старт термометра: -------------------------------
void Start(char n) { TReset(n); //импульс сброса if(Present[n]) { TByte(n, 0xCC); //skip ROM TByte(n, 0x44); //convert T } }
//------------------------- Чтение термометра: -------------------------------
void Read(char n) { if(Present[n]) { TReset(n); //импульс сброса if(Present[n]) { TByte(n, 0xCC); //skip ROM TByte(n, 0xBE); //read scratchpad #ifdef DS18B20 char l = TByte(n, 0xFF); //чтение младшего байта char h = TByte(n, 0xFF); //чтение старшего байта int t = WORD(h, l); //температура с дискретностью 0.0625°C t = (t * 10) / 16; //температура с дискретностью 0.1°C #else char Data[9]; //данные термометра char Crc = 0; //инициализация CRC for(char i = 0; i < 9; i++) { char b = TByte(n, 0xFF); //чтение данных Do_Crc(b, &Crc); //обновление CRC Data[i] = b; //сохранение данных } int t = TEMP_MIN; if(!Crc) { t = WORD(Data[1], Data[0]) / 2; t = (t * 20 - 5 + (int)(Data[7] - Data[6]) * 20 / Data[7]) / 2; } #endif Temp[n] = t; return; } } Temp[n] = TEMP_MIN; //термометр отсутствует return; }
//--------------------- Генерация импульса сброса: ---------------------------
void TReset(char n) { char m = Masks[n]; char si; Present[n] = 0; //сброс флага присутствия термометра Port_OWP_0(m); //OWP <- 0 Delay_us(500); //delay 500 uS si = __save_interrupt(); __disable_interrupt(); //запрещение прерываний Port_OWP_Z(m); //OWP <- 1 Delay_us(14); //delay 14 uS if(Pin_OWP(m)) //если OWP = 0, то ошибка { Delay_us(52); //delay 52 uS if(!Pin_OWP(m)) //если OWP = 1, то ошибка { __restore_interrupt(si); //восстанавление прерываний Delay_us(250); //delay 250 uS if(Pin_OWP(m)) //если OWP = 0, то ошибка { Present[n] = 1; //если ошибок нет, термометр присутствует } } } __restore_interrupt(si); //восстанавление прерываний в случае ошибки }
//-------------- Запись/чтение байта по однопроводной шине: ------------------
char TByte(char n, char dat) { char res; char m = Masks[n]; for(char i = 0; i < 8; i++) { res = res >> 1; if(TBit(m, dat & 1)) res |= 0x80; else res &= ~0x80; dat = dat >> 1; } return(res); }
//--------------- Запись/чтение бита по однопроводной шине: ------------------
bool TBit(char m, bool b) { char si; si = __save_interrupt(); __disable_interrupt(); //запрещение прерываний Port_OWP_0(m); //OWP <- 0 Delay_us(2); //delay 2 uS if(b) Port_OWP_Z(m); //bit = 1, OWP <- 1 Delay_us(13); //delay 13 uS bool owp = Pin_OWP(m); //чтение порта Delay_us(45); //delay 45 uS Port_OWP_Z(m); //OWP <- 1 __restore_interrupt(si); //восстанавление прерываний Delay_us(2); //delay 2 uS return(owp); }
//--------------------- Вычисление контрольной суммы: ------------------------
void Do_Crc(char b, char *crc) { for(char i = 0; i < 8; b = b >> 1, i++) if((b ^ *crc) & 1) *crc = ((*crc ^ 0x18) >> 1) | 0x80; else *crc = (*crc >> 1) & ~0x80; }
--------------------
|
|
|
|
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|