MyTetra Share
Делитесь знаниями!
sensor_ds18b20.asm
Время создания: 08.12.2017 21:41
Раздел: Electronics - Microcontrollers - AVR8 - AVR ASM - ASM_PROJ - DS18B20 - DS18B20 v.4

#ifndef SENSOR_DS18B20_ASM

#define SENSOR_DS18B20_ASM


;looking for one slave on I2C wire

sensor_slave_searching:

PUSH R16

IN R16, SREG

PUSH R16


CLI


SBI SENSOR_DDR, SENSOR ; UP wire

mDelay_us 255

mDelay_us 235

CBI SENSOR_DDR, SENSOR ; DOWN wire

mDelay_us 65

IN R16, SENSOR_PIN ; reading 1st bit

ANDI R16, SENSOR_MASK ; 0x01 - remove all bits except first

STS var_temp, R16

mDelay_us 255

mDelay_us 165


SEI


POP R16

OUT SREG, R16

POP R16

RET



;invert bit's order and store it as one reveived byte

;result will be stored in var_temp

sensor_read_byte:

PUSH R16

PUSH R17

PUSH R18 ; received bit


CLR R16 ; cycle counter (bit number)

CLR R17 ; result


read_byte_loop:

CPI R16,8 ;

BREQ read_byte_loop_end ; leave loop if r16 == 8

CALL sensor_read_bit ; I2C - receive bit

LDS R18,var_temp ; load bit from SRAM

//---------------- atomic operation

CLI

ROR R18 ; move (right shift) received bit to C in SREG

ROR R17 ; take bit from C (right shift) and push it in R17

SEI

//---------------- END of atomic operation

INC R16

RJMP read_byte_loop


read_byte_loop_end:

STS var_temp,R17


POP R18

POP R17

POP R16

RET


;read bit and push it in var_temp

sensor_read_bit:

PUSH R16

IN R16,SREG

PUSH R16


CLI


SBI SENSOR_DDR, SENSOR ; UP wire

mDelay_us 2

CBI SENSOR_DDR, SENSOR ; DOWN wire

mDelay_us 13

IN R16, SENSOR_PIN ; reading 1st bit

ANDI R16, 0x01 ; 1 - device answered

STS var_temp, R16

mDelay_us 45


SEI


POP R16

OUT SREG,R16

POP R16

RET



sensor_write_byte:

PUSH R16 ; cycle counter

PUSH R17 ; byte

PUSH R18 ; bit


CLR R16

LDS R17,var_temp ; laod byte for sending


write_byte_loop:

CPI R16,8

BREQ write_byte_loop_end ; leave loop if r16 == 8

MOV R18,R17 ; copy byte

LSR R17 ; shift remaining bits

CALL sensor_write_bit ; function works with R18

INC R16 ; inc counter

RJMP write_byte_loop

write_byte_loop_end:


POP R18

POP R17

POP R16

RET


// IN: R18 = bit

sensor_write_bit:

PUSH R16

IN R16,SREG

PUSH R16


CLI


SBI SENSOR_DDR, SENSOR ; UP wire

mDelay_us 2

;LDS R16,var_temp ; load bit

SBRC R18,0 ; skip next if bit 0 is cleared

CBI SENSOR_DDR, SENSOR ; DOWN wire

mDelay_us 60

CBI SENSOR_DDR, SENSOR ; DOWN wire


SEI


POP R16

OUT SREG,R16

POP R16

RET


sensor_get_data:

PUSH R16 ; temp

PUSH R17 ; temperature LOW

PUSH R18 ; temperature HIGH


CALL sensor_slave_searching ; trying to find our sensor

LDS R16, var_temp ; load the result


SBRS R16, 1 ; if any device is found...

RJMP sensor_check_end ; ...skip it

// CPI R16, 0x01

// BRNE sensor_check_end


LDI R16, SEN_NOID ; send command

STS var_temp, R16

CALL sensor_write_byte


LDI R16, SEN_CONVERT ; send command

STS var_temp, R16

CALL sensor_write_byte


mDelay_us 255

mDelay_us 255

mDelay_us 240

CALL sensor_slave_searching


LDI R16, SEN_NOID ; send command

STS var_temp, R16

CALL sensor_write_byte


LDI R16, SEN_READ_DAT ; send command

STS var_temp, R16

CALL sensor_write_byte


CALL sensor_read_byte

LDS R17, var_temp ; save low part

CALL sensor_read_byte

LDS R18, var_temp ; save high part


//-------------------------

// STS var_temperature, R18

// STS var_temperature+1, R17

//-------------------------

CALL sensor_convert_temperature


sensor_check_end:

POP R18

POP R17

POP R16

RET



sensor_convert_temperature:

// PUSH R16 ; temperature LOW

// PUSH R17 ; temperature HIGH


// LDS R17, var_temperature

// LDS R16, var_temperature+1


CLI

LSR R18

ROR R17


LSR R18

ROR R17


LSR R18

ROR R17


LSR R18

ROR R17

SEI


STS var_temperature, R17 ; use only low part

// STS var_temperature+1, R16


// POP R17

// POP R16

RET



#endif


Так же в этом разделе:
 
MyTetra Share v.0.53
Яндекс индекс цитирования