📄 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 + -