;*******************************************************
;Chip Model: MEGA8
;Assembler header file
.INCLUDE "m8def.inc" ;tells the AVR assembler to add the contents of a file to our program
;*******************************************************
.ORG 0 ;indicates the beginning of the address of our code; puts our code at the beginning of flash memory
LDI R21,HIGH(RAMEND) ;set up stack
OUT SPH,R21
LDI R21,LOW(RAMEND)
OUT SPL,R21
RCALL I2C_INIT ;initialize the I2C module
RCALL I2C_START ;transmit a START condition
LDI R21, 0b11010000 ;SLA (1001101) + W(0)
RCALL I2C_SEND ;transmit R21 to I2C bus
LDI R21, 0x07 ;set register pointer to 07
RCALL I2C_SEND ;to access the control register
LDI R21, 0x00 ;set control register = 0
RCALL I2C_SEND ;transmit R21 to I2C bus
RCALL I2C_STOP ;transmit a STOP condition
RCALL DELAY
RCALL I2C_START ;transmit a START condition
LDI R21, 0b11010000 ;SLA (1001101) + W(0)
RCALL I2C_SEND ;transmit R21 to I2C bus
LDI R21, 0x00 ;set register pointer to 0
RCALL I2C_SEND ;transmit R21 to I2C bus
LDI R21, 0x55 ;set seconds to 0x55 = 55 BCD
RCALL I2C_SEND ;transmit R21 to I2C bus
LDI R21, 0x58 ;set minutes to 0x58 = 58 BCD
RCALL I2C_SEND ;transmit R21 to I2C bus
LDI R21, 0x16 ;hour = 16 in 24 hours mode
RCALL I2C_SEND ;transmit R21 to I2C bus
RCALL I2C_STOP ;transmit a STOP condition
SBI DDRB, 5 ;makes PORTB.5 an output port by setting DDRB.5:=1
BACK:
SBI PORTB, 5 ;turns on PB5; PB5:=1
RCALL DELAY2 ;time delay, calls the DELAY subroutine
CBI PORTB, 5 ;turns off PB5; PB5:=0
RCALL DELAY2 ;time delay, calls the DELAY subroutine
RJMP BACK ;jumps to BACK, keeps doing it forever (an infinite loop)
;*********************************************************
I2C_INIT:
LDI R21, 0
STS TWSR,R21 ;set prescaler bits to zero
LDI R21, 152 ;move 152 into R21
STS TWBR,R21 ;set clock freq. to 50k (16 MHz XTAL)
LDI R21, (1 << TWEN) ;move 0x04 into R21
STS TWCR,R21 ;enable the TWI
RET
;*********************************************************
I2C_START:
LDI R21, (1 << TWINT)|(1 << TWSTA)|(1 << TWEN)
STS TWCR,R21 ;transmit a START condition
WAIT1:
LDS R21, TWCR ;read control register into R21
SBRS R21, TWINT ;skip next line if TWINT is 1
RJMP WAIT1 ;jump to WAIT1 if TWINT is 1
RET
;***************************************************
I2C_SEND:
STS TWDR, R21 ;move SLA+W into TWDR
LDI R21, (1 << TWINT)|(1 << TWEN)
STS TWCR, R21 ;configure TWCR to send TWDR
W2: LDS R21, TWCR ;read control register into R21
SBRS R21, TWINT ;skip next instruction if TWINT is 1
RJMP W2 ;jump to W2 if TWINT is 0
RET
;***************************************************
I2C_STOP:
LDI R21, (1 << TWINT)|(1 << TWSTO)|(1 << TWEN)
STS TWCR, R21 ;transmit STOP condition
RET
;***************************************************
DELAY:
LDI R22, 0xFF
A1: DEC R22
NOP
BRNE A1
RET
;***************************************************
DELAY2:
LDI R20, 100 ;loads R20 with the value 100 in dec
L0: LDI R21, 250 ;loads R21 with the value 250 in dec
L1: LDI R22, 250 ;loads R22 with the value 250 in dec
L2:
NOP ;does nothing (1 Instruction cycle)
NOP ;does nothing (1 Instruction cycle)
DEC R22 ;decrements R22 by one, assign Z:=1 if R22==0 (1 Instruction cycle)
BRNE L2 ;tests the zero flag (Z), branch to L2 if Z==0 (2 Instruction cycles)
DEC R21 ;decrements R21 by one, assign Z:=1 if R21==0
BRNE L1 ;tests the zero flag (Z), branch to L1 if Z==0
DEC R20 ;decrements R20 by one, assign Z:=1 if R20==0
BRNE L0 ;tests the zero flag (Z), branch to L0 if Z==0
RET ;returns to caller (the end of the DELAY subroutine)