?? avr-m8+isl1208.asm
字號:
.include "m8def.inc";M8@4MHs
;用于AVR的M8控制時鐘IC--ISL1208的設置時間
.def eedwr =r21 ;寫入數據
.def arl =r22 ;讀出低位地址
.def arh =r23 ;讀出高位地址
.DEF TEMP =R16
.def data=r20 ;數據寄存
.def sub_addr=r19 ;片內子地址
.def status=r18 ;校驗特征字
.EQU A1=0X0200
;************************************************
.ORG $0000
RJMP RESET
.ORG $0001
RJMP INTO
.ORG $0002
RJMP INTI
;*********************測試程序*****************************
.ORG $0020
reset:
ldi r16,low(ramend) ;設置堆棧
out spl,r16
ldi r16,high(ramend)
out sph,r16
ldi r16,0x7f ;初始化portc,設置為輸出,帶上拉
out portc,r16
ldi r16,0xff
out ddrc,r16
LDI TEMP,0B11110011
OUT DDRD,TEMP ;設D口方向寄存器為輸出,INT為輸入
LDI TEMP,0B00001100
OUT PORTD,TEMP ;INT0為0
rcall DELAYA
sbi portd,4 ;led
rcall DELAYA
cbi portd,4 ;使led0亮,測試用。表示即將寫數據
ldi r16,0x0a ;配置twi的比特率4M/16+2*10=110kps
out twbr,r16
LDI TEMP,0X00 ;INT為低電平時產生中斷請求
OUT MCUCR,TEMP
LDI TEMP,0XC0 ;允許INT中斷
OUT GIMSK,TEMP
SEI ;開中斷
STAR: ldi sub_addr,0x07 ;置子地址
ldi data,0x90 ;置數據=SR
rcall i2c_write ;寫入一字節
rcall delay ;延時,等待寫周期的完成
inc sub_addr ;子地址加一
ldi data,0xe0 ;置數據=INT
rcall i2c_write ;寫入一字節
rcall delay ;延時,等待寫周期的完成
ldi sub_addr,0x0d
ldi data,0x95 ;置數據=
rcall i2c_write ;寫入一字節
rcall delay ;延時,等待寫周期的完成
inc sub_addr ;子地址加一
ldi data,0xa1 ;置數據=
rcall i2c_write ;寫入一字節
rcall delay ;延時,等待寫周期的完成
ldi sub_addr,0x12
ldi data,0x12 ;置數據=密碼A
rcall i2c_write ;寫入一字節
rcall delay ;延時,等待寫周期的完成
inc sub_addr ;子地址加一
ldi data,0x34 ;置數據=密碼B
rcall i2c_write ;寫入一字節
rcall delay ;延時,等待寫周期的完成
ldi sub_addr,0x0a ;置子地址
ldi data,0x09 ;置數據=ATR 電容大時間慢
rcall i2c_write ;寫入一字節
rcall delay ;延時,等待寫周期的完成
inc sub_addr ;子地址加一
ldi data,0x00 ;置數據=DTR
rcall i2c_write ;寫入一字節
rcall delay ;延時,等待寫周期的完成
sbi portd,4 ;led
RCALL DELAYA
cbi portd,4
RCALL DELAYA ;調用延時子程序
RJMP STAR ;循環
INTO: CLI
IN R19,SREG
LDI TEMP,0X00 ;禁止INT0中斷
OUT GIMSK,TEMP
ldi arh,0x00 ;寫入高位地址
ldi arl,0x10 ;寫入低位地址
ldi sub_addr,0x00 ;置子地址為0x00
rcall i2c_read ;讀出一字節
rcall delay ;延時,等待寫周期的完成
mov eedwr,data ;讀數據=秒
rcall eewrite
inc arl
inc sub_addr ;子地址加一
rcall i2c_read ;讀出一字節
rcall delay ;延時,等待寫周期的完成
mov eedwr,data ;讀數據=秒
rcall eewrite
inc arl
inc sub_addr ;子地址加一
rcall i2c_read ;讀出一字節
rcall delay ;延時,等待寫周期的完成
mov eedwr,data ;讀數據=秒
rcall eewrite
inc arl
inc sub_addr ;子地址加一
rcall i2c_read ;讀出一字節
rcall delay ;延時,等待寫周期的完成
mov eedwr,data ;讀數據=秒
rcall eewrite
inc arl
inc sub_addr ;子地址加一
rcall i2c_read ;讀出一字節
rcall delay ;延時,等待寫周期的完成
mov eedwr,data ;讀數據=秒
rcall eewrite
inc arl
inc sub_addr ;子地址加一
rcall i2c_read ;讀出一字節
rcall delay ;延時,等待寫周期的完成
mov eedwr,data ;讀數據=秒
rcall eewrite
inc arl
inc sub_addr ;子地址加一
rcall i2c_read ;讀出一字節
rcall delay ;延時,等待寫周期的完成
mov eedwr,data ;讀數據=秒
rcall eewrite
inc arl
inc sub_addr ;子地址加一
rcall i2c_read ;讀出一字節
rcall delay ;延時,等待寫周期的完成
mov eedwr,data ;讀數據=SR
rcall eewrite
inc arl
inc sub_addr ;子地址加一
rcall i2c_read ;讀出一字節
rcall delay ;延時,等待寫周期的完成
mov eedwr,data ;讀數據=INT
rcall eewrite
inc arl
ldi sub_addr,0x07 ;置子地址為0x00
rcall i2c_read ;讀出一字節
rcall delay ;延時,等待寫周期的完成
mov eedwr,data ;讀數據=秒
rcall eewrite
inc arl
inc sub_addr ;子地址加一
rcall i2c_read ;讀出一字節
rcall delay ;延時,等待寫周期的完成
mov eedwr,data ;讀數據=秒
rcall eewrite
sbi portd,5 ;led
RCALL DELAYB
cbi portd,5
RCALL DELAYB ;調用延時子程序
sbi portd,2 ;INT0=1
OUT SREG,R19
LDI TEMP,0XC0 ;允許INT0中斷
OUT GIMSK,TEMP
RETI
INTI:
CLI
IN R19,SREG
LDI TEMP,0X00 ;禁止INT0中斷
OUT GIMSK,TEMP
ldi sub_addr,0x00 ;置子地址為0x00
ldi data,0 ;置數據=秒
rcall i2c_write ;寫入一字節
rcall delay ;延時,等待寫周期的完成
inc sub_addr ;子地址加一
ldi data,0x38 ;置數據=分
rcall i2c_write ;寫入一字節
rcall delay ;延時,等待寫周期的完成
inc sub_addr ;子地址加一
ldi data,0x81 ;置數據=24小時 0+80
rcall i2c_write ;寫入一字節
rcall delay ;延時,等待寫周期的完成
inc sub_addr ;子地址加一
ldi data,0x08 ;置數據=日
rcall i2c_write ;寫入一字節
rcall delay ;延時,等待寫周期的完成
inc sub_addr ;子地址加一
ldi data,0x01 ;置數據=月
rcall i2c_write ;寫入一字節
rcall delay ;延時,等待寫周期的完成
inc sub_addr ;子地址加一
ldi data,0x06 ;置數據=年
rcall i2c_write ;寫入一字節
rcall delay ;延時,等待寫周期的完成
inc sub_addr ;子地址加一
ldi data,0x00 ;置數據=星期
rcall i2c_write ;寫入一字節
rcall delay ;延時,等待寫周期的完成
sbi portd,5 ;led
RCALL DELAYB
cbi portd,5
RCALL DELAYB ;調用延時子程序
sbi portd,3 ;INT0=1
OUT SREG,R19
LDI TEMP,0XC0 ;允許INT0中斷
OUT GIMSK,TEMP
RETI
;*************I2C寫子程序*******************
i2c_write:
ldi status,0x08
rcall start ;start
ldi r17,0b11011110
ldi status,0x18
rcall tx_data ;device address
mov r17,sub_addr
ldi status,0x28
rcall tx_data ;sub_address
mov r17,data
rcall tx_data ;data to be written
rcall stop ;stop
ret
;*************I2c讀子程序*******************
i2c_read:
ldi status,0x08
rcall start ;start
ldi r17,0b11011110
ldi status,0x18
rcall tx_data ;device address
mov r17,sub_addr
ldi status,0x28
rcall tx_data ;sub_address
ldi status,0x10
rcall start ;repeat start
ldi status,0x40
ldi r17,0b11011111
rcall tx_data ;sla+r
rcall rx_data ;read one byte
rcall stop ;stop
ldi r16,(0<<twen);close twi
out twcr,r16
ret
;*************I2C_START***********************
start: ;發出START 信號
ldi r16,(1<<twint)|(1<<twsta)|(1<<twen)
out twcr,r16
nop
nop
wait1: nop ;等待TWINT 置位, TWINT 置位表示START 信號已發出
in r16,twcr
sbrs r16,twint
rjmp wait1
in r16,twsr ;檢驗TWI 狀態寄存器,屏蔽預分頻
andi r16,0xf8 ;位,如果狀態字不是START 轉出錯處理
cp r16,status ;start?
brne error1
ret
;*************I2C發送************************
tx_data: ;將SLA_W 載入TWDR 寄存器,TWINT 位清零,啟動發送地址
out twdr,r17
nop
nop
ldi r16,(1<<twint)|(1<<twen)
out twcr,r16
nop
nop
wait3: nop ;等待TWINT 置位, TWINT 置位表示總線命令SLA+W 已發出,及收到應答信號ACK/NACK
in r16,twcr
sbrs r16,twint
rjmp wait3
in r16,twsr ;檢驗TWI 狀態寄存器,屏蔽預分頻位,如果狀態字不是MT_SLA_ACK 轉出錯處理
andi r16,0xf8
cp r16,status
brne error2
ret
;*************I2C接收*******************
rx_data:
ldi r16, (1<<twint) | (1<<twen)
out twcr, r16
nop
nop
wait4: in r16, twcr
sbrs r16, twint
rjmp wait4
in r16, twsr
andi r16,0xf8
cpi r16, 0x58 ; mr_data_nack
brne error2
in data, twdr
ret
;**************I2C_STOP***********************
stop:
ldi r16,(1<<twint)|(1<<twen)|(1<<twsto)
out twcr,r16
nop
nop
ret
;***************校驗應答出錯*****************
error1: nop
error2:
sbi portd,7 ;led
rcall DELAYB
cbi portd,7 ;置led3亮,表示應答出錯
rcall DELAYB
sbi portd,7 ;led
rcall DELAYB
cbi portd,7 ;置led3亮,表示應答出錯
ret
;****************寫入EEPROM**********************
eewrite:;寫入
sbic eecr,eewe ;等待EEWE=0
rjmp eewrite
out eearl,arl
out eearh,arh
out eedr,eedwr
sbi eecr,eemwe
sbi eecr,eewe
ret
;@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
DELAYA: ;RET TIME1S @ 4MHZ延時子程序
LDI R29,21 ;延時子程序
LDI R28,100
DELAY2: DEC R27 ;復位后R30=0X00
BRNE DELAY2 ;R30不為0轉,為0按順序執行
DEC R28 ;復位后R31=0X00
BRNE DELAY2 ;R30不為0轉,為0按順序執行
DEC R29 ;復位后R29=0X00
WDR
BRNE DELAY2 ;R29不為0轉,為0按順序執行
RET ;子程序返回
DELAYB: ;RET ;TIME0.5S @ 4MHZ延時子程序
LDI R26,11 ;延時子程序
LDI R25,37
DELAY3: DEC R24 ;復位后R30=0X00
BRNE DELAY3 ;R30不為0轉,為0按順序執行
DEC R25 ;復位后R31=0X00
BRNE DELAY3 ;R30不為0轉,為0按順序執行
DEC R26 ;復位后R29=0X00
WDR
BRNE DELAY3 ;R29不為0轉,為0按順序執行
RET
DELAY: ;RET ;TIME 5mS @ 4MHZ延時子程序
LDI R25,26
DELAY5: DEC R24 ;復位后R30=0X00
BRNE DELAY5 ;R30不為0轉,為0按順序執行
DEC R25 ;復位后R31=0X00
BRNE DELAY5 ;R30不為0轉,為0按順序執行
WDR
RET
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -