MyTetra Share
Делитесь знаниями!
main.asm
Время создания: 05.12.2017 15:45
Раздел: Electronics - Microcontrollers - AVR8 - AVR ASM - ASM_PROJ - DS18B20 - DS18B20 v.1

.include "m8adef.inc"

;.include "m1281def.inc"



.include "macro.inc"


;INTERRUPT VECTORS

rjmp reset ;ïðåðûâàíèå îò RESET, ññûëàåìñÿ íà îáðàáîò÷èê ïðåðûâàíèÿ - initial

; rjmp 0 ;rjmp service_INT0 ;âíåøíåå ïðåðûâàíèå 0

; rjmp 0 ;rjmp service_INT1 ;âíåøíåå ïðåðûâàíèå 1

; rjmp 0 ;rjmp service_OC2 ;ñîâïàäåíèå TCNT2 è OCR2

; rjmp 0 ;rjmp service_OVF2 ;ïåðåïîëíåíèå TCNT2

; rjmp 0 ;rjmp service_ICP1 ;çàõâàò â ICP1

; rjmp 0 ;rjmp service_OC1A ;ñîâïàäåíèå TCNT1 è OCR1A

; rjmp 0 ;rjmp service_OC1B ;ñîâïàäåíèå TCNT1 è OCR1B

; rjmp 0 ;rjmp service_OVF1 ;ïåðåïîëíåíèå TCNT1

; rjmp 0 ;rjmp service_OVF0 ;ïåðåïîëíåíèå TCNT0

; rjmp 0 ;rjmp service_SPI ;ïðåðûâàíèå îò ìîäóëÿ SPI

; rjmp 0 ;rjmp service_URXC ;ïîëó÷åíèå áàéòà ïî USART

; rjmp 0 ;rjmp service_UDRE ;îïóñòîøåíèå UDR â USART

; rjmp 0 ;rjmp service_UTXC ;ïåðåäà÷à áàéòà ïî USART

; rjmp 0 ;rjmp service_ADCC ;ïðåðûâàíèå îò ÀÖÏ

; rjmp 0 ;rjmp service_ERDY ;çàâåðøåíèå çàïèñè â EEPROM

; rjmp 0 ;rjmp service_ACI ;ïðåðûâàíèå îò êîìïàðàòîðà

; rjmp 0 ;rjmp service_TWI ;ïðåðûâàíèå îò ìîäóëÿ TWI

; rjmp 0 ;rjmp service_SPMR ;çàâåðøåíèå âûïîëíåíèÿ spm




.include "memory.asm"


.cseg

.org 0x20


;STACK INITIALISATION

reset:

ldi R16,low(RAMEND)

out SPL,R16

ldi R17,high(RAMEND)

out SPH,R17


;DEFINES

.equ SENSOR_DDR = DDRD

.equ SENSOR_PORT = PORTD

.equ SENSOR_PIN = PIND

.equ SENSOR = 0


;Commands for temperature sensor:

.set SEN_NOID = 0xCC ; skip identification

.set SEN_CONVERT = 0x44 ; convert temperature to HEX

.set SEN_READ_DAT = 0xBE ; send all data to master


;PERIPHERY INITIALISATION

SBI SENSOR_DDR, SENSOR

CBI SENSOR_PORT,SENSOR


;MAIN PROGRAM

main:

; CALL sensor_slave_searching

; LDS R16,var_temp

; SBRC R16,0 ;skip next comm if bit 0 is cleared

; CALL sensor_read_byte

; CALL sensor_write_byte

CALL sensor_check



LDS R16, var_temperature

SBRC R16, 7 ; check for sign (1 - minus, 0 - plus)

RJMP convert_t_to_number

LDI R17, 0xF0

EOR R16, R17


convert_t_to_number:


rjmp main

;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, 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_check:

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

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


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 R17

ROR R16


LSR R17

ROR R16


LSR R17

ROR R16


LSR R17

ROR R16

SEI


STS var_temperature, R16 ; use only low part

// STS var_temperature+1, R16


POP R17

POP R16

RET


convert_HEX_to_DEC:

; IN:

; var - source HEX nuber

; OUT:

; R23 - hundreds

; R24 - decimals

; R25 - units

PUSH R16

PUSH R17

PUSH R18

PUSH R19


LDS R16, var_temperature ; source (dividend)

LDI R17, 100 ; divisor

CLR R18

CLR R19

CALL devide

MOV R23, R18 ; save result of division as hundreds

MOV R16, R19 ; copy remainder as next dividend

LDI R17, 10 ; new divisor

CLR R18

CLR R19

CALL devide

MOV R24, R18 ; save result (decimals)

MOV R25, R19 ; save remainder (units)


POP R19

POP R18

POP R17

POP R16

RET


devide:

;R16 - dividend

;R17 - divisor

;R18 - result

;R19 - remainder

devide_loop:

SUB R16, R17 ; dividend - divisor

BRMI devide_neg_result ; goto if result is negative

INC R18 ; if not - incr main result

RJMP devide_loop

devide_neg_result:

ADD R16, R17 ; back dividend + divisor

MOV R19, R16 ; save dividend as remainder

RET


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