这些小活动你都参加了吗?快来围观一下吧!>>
电子产品世界 » 论坛首页 » 综合技术 » 基础知识 » mega8,I2C 高手指点一下mega8的I2C,不胜感激

共4条 1/1 1 跳转至

mega8,I2C 高手指点一下mega8的I2C,不胜感激

院士
2006-09-17 18:14:16     打赏
mega8,I2C 高手指点一下mega8的I2C,不胜感激



关键词: mega8     高手     指点     一下     不胜     感激    

院士
2006-12-22 22:43:00     打赏
2楼
问 为什么I2C置标志置位进不了中断,定时器,外中断都可以,是我弄错了,还是怎么回事,烦请高手指点,以及其注意事项,谢谢
1: slaver or master? 2: 都是这样啊    ldi    temp,0x20        ;设置波特率
    out      TWBR,temp
    ldi      temp,0x00
    out    TWSR,temp
    
主机,我用查询方式    
    
ldi r16, (1<<TWINT)|(1<<TWSTA)|(1<<TWEN)
out TWCR, r16    
wait1:
in r16,TWCR
sbrs r16,TWINT
rjmp wait1    
in r16,TWSR
andi r16, 0xF8
cpi r16, 0x08
brne ERROR    
ldi r16, 0x02
out TWDR, r16
ldi r16, (1<<TWINT) | (1<<TWEN)
out TWCR, r16    
wait2:
in r16,TWCR
sbrs r16,TWINT
rjmp wait2    
in r16,TWSR
andi r16, 0xF8
cpi r16, 0x18
brne ERROR    
ldi r16, 0xff
out TWDR, r16
ldi r16, (1<<TWINT) | (1<<TWEN)
out TWCR, r16    
wait3:
in r16,TWCR
sbrs r16,TWINT
rjmp wait3    
in r16,TWSR
andi r16, 0xF8
cpi r16, 0x28
brne ERROR    
ldi r16, (1<<TWINT)|(1<<TWEN)|(1<<TWSTO)
out TWCR, r16    
    
error:    rjmp    error    



                    从机中断


ldi    temp,SLA        ;从机地址
    out    TWAR,temp
    ldi    temp,(1<<TWEN)|(1<<TWIE)|(TWEA);开I2中断
    out    TWCR,temp
    sei
wait1:    sbrs    bvalid,0
    rjmp    wait1
    clr    bvalid
tt:    rjmp    tt

I2int:              cbi    PORTB,0
kk:              rjmp    kk
    in    temp,TWSR        ;检测TWI状态寄存器TWSR,屏蔽预分频位
    andi    temp,0xf8
    cpi    temp,0x60        ;如果不是SLA+W转移
    brne    end
    ldi    temp,(1<<TWINT)|(1<<TWEA)
    out    TWCR,temp
wait2:    in    temp,TWCR
    sbrs    temp,TWINT
    rjmp    wait2            ;等待TWINT置位
    in    temp,TWSR
    andi    temp,0xf8
    cpi    temp,0x88        ;如果不是SLA+W寻址,DATA已经收到,NACK已经发出,转移
    brne    end
    in    MOrder,TWDR        ;读出主机命令
    clr    temp
    out    TWCR,temp
    ldi    temp,Time1_scaler    ;开定时器
    out    TCCR1B,temp
    ldi    temp,(1<<TWINT)|(1<<TWEA)|(1<<TWEN);转入被控初始状态,进行本机SLA匹配
    out    TWCR,temp  
wait3:    in    temp,TWCR
    sbrs    temp,TWINT
    rjmp    wait3
    in    temp,TWSR
    andi    temp,0xf8
    cpi    temp,0xa8        ;收到本机SLA+R,ACK已经发出
    brne    end
    out    TWDR,MOrder        ;发送刚刚受到的命令
    ldi    temp,(1<<TWINT)|(1<<TWEN);发送最后一个DATA,接收NACK信号
    out    TWCR,temp
wait4:    in    temp,TWCR
    sbrs    temp,TWINT
    rjmp    wait4
    in    temp,TWSR
    andi    temp,0xf8
    cpi    temp,0xc0        ;如果不是DATA已经发出,受到NACK信号,转移
    brne    end
    ldi    temp,(1<<TWINT)|(1<<TWEA);转入被控初始状态,进行本机SLA匹配
    out    TWCR,temp
    call    delay
wait5:    sbic    PINB,OK            ;等待主机应答信号
    rjmp    wait5
    cbi    PORTB,Answer        ;应答主机
    call    delay
    sbi    PORTB,Answer
    sbr    bvalid,0x01        
end:    clr    temp
    out    TWCR,temp
    reti

开始我主机也是用的中断,不行,我又改为查询方式
还是不行,资料上都说写1清TWINT,但是我用软件
仿真是清不掉的,怎么回事??
3: 这是我从程序中拷出来的,实际中肯定能用    ; *** Init I2C ***
    outi    twbr,(ck-16*sclk)/(2*sclk)    ; i2c clock


.equ    START        = 0x8
.equ    MT_SLA_ACK    = 0x18
.equ    MT_DATA_ACK    = 0x28
.equ    MR_SLA_ACK    = 0x40
.equ    MR_DATA_ACK    = 0x50
.equ    MR_DATA_NACK    = 0x58
;************************************
;    i2c write, write a string
;    entry: iicadd, iicnumber-- numbers to be write, X-- data pointer
;    exit: c=0 ok; c=1 failed
;***********************************
i2cwr:
    outi    TWCR,(1<<TWINT)|(1<<TWSTA)|(1<<TWEN)    ; i2c start
    in    r16,TWCR
    sbrs    r16,TWINT
    rjmp    pc-2        ; waite
    in    r16,TWSR
    andi    r16,0xf8    ; mask prescale bits
    cpi    r16,START    ; if start?
    brne    error    
    
    out    TWDR,iicadd    ; write i2c device address
    sts    lastadd,iicadd
    cbi    TWDR,0        ; i2c write
    outi    TWCR,(1<<TWINT)|(1<<TWEN)    ;
    in    r16,TWCR
    sbrs    r16,TWINT
    rjmp    pc-2        ; waite
    in    r16,TWSR
    andi    r16,0xf8    ; mask prescale bits
    cpi    r16,MT_SLA_ACK    ; if address ack?
    brne    error

i2cwr_lp:    
    ld    r16,x+        ; get data
    out    TWDR,r16
    outi    TWCR,(1<<TWINT)|(1<<TWEN)    ;
    in    r16,TWCR
    sbrs    r16,TWINT
    rjmp    pc-2        ; waite
    in    r16,TWSR
    andi    r16,0xf8    ; mask prescale bits
    cpi    r16,MT_DATA_ACK    ; if data ack?
    brne    error
    dec    iicnumber
    brne    i2cwr_lp
            
    outi    TWCR,(1<<TWINT)|(1<<TWSTO)|(1<<TWEN)    ; i2c stop
    clc
    ret
    
    
error:    sec
    ret    
    
;*********************************************
;    i2c read, only read one byte
;    entry: iicadd
;    exit: r16--data, c=0 ok; c=1 failed
;*********************************************    
i2crd:
    outi    TWCR,(1<<TWINT)|(1<<TWSTA)|(1<<TWEN)    ; i2c start
    in    r16,TWCR
    sbrs    r16,TWINT
    rjmp    pc-2        ; waite
    in    r16,TWSR
    andi    r16,0xf8    ; mask prescale bits
    cpi    r16,START    ; if start?
    brne    error    
    
    out    TWDR,iicadd    ; write i2c device address
    sbi    TWDR,0        ; i2c read
    outi    TWCR,(1<<TWINT)|(1<<TWEN)    ;
    in    r16,TWCR
    sbrs    r16,TWINT
    rjmp    pc-2        ; waite
    in    r16,TWSR
    andi    r16,0xf8    ; mask prescale bits
    cpi    r16,MR_SLA_ACK    ; if address ack?
    brne    error

    outi    TWCR,(1<<TWINT)|(1<<TWEN)    ;
    in    r16,TWCR
    sbrs    r16,TWINT
    rjmp    pc-2        ; waite
    in    r16,TWSR
    andi    r16,0xf8    ; mask prescale bits
    cpi    r16,MR_DATA_NACK ; if final data?
    brne    error    
    in    r16,TWDR

    push    r16
    outi    TWCR,(1<<TWINT)|(1<<TWSTO)|(1<<TWEN)    ; i2c stop
    pop    r16
    clc
    ret

4: 补充一下OUTI的宏定义:; Output immediate
;
;    outi    port,var

.macro    outi
    ldi    r16,@1
    out    @0,r16
.endm

5: 多谢指点,问题已经搞定

高工
2023-02-19 22:57:18     打赏
3楼

学习


专家
2023-02-19 23:07:19     打赏
4楼

学习


共4条 1/1 1 跳转至

回复

匿名不能发帖!请先 [ 登陆 注册 ]