📄 iic接口读写.s
字号:
.module IIC接口读写.c
.area text(rom, con, rel)
.dbfile E:\xiaozhiyong2009\设计资料\项目设计\ICCAVR_mega8_C\ICCAVR_mega8_IIC接口读写\IIC接口读写.c
.dbfunc e port_init _port_init fV
.even
_port_init::
.dbline -1
.dbline 9
; //ICC-AVR application builder : 2009-3-12 17:05:04
; // Target : M8
; // Crystal: 8.0000Mhz
;
; #include <iom8v.h>
; #include <macros.h>
;
; void port_init(void)
; {
.dbline 10
; PORTB = 0x00;
clr R2
out 0x18,R2
.dbline 11
; DDRB = 0x00;
out 0x17,R2
.dbline 12
; PORTC = 0x00; //m103 output only
out 0x15,R2
.dbline 13
; DDRC = 0x00;
out 0x14,R2
.dbline 14
; PORTD = 0x00;
out 0x12,R2
.dbline 15
; DDRD = 0x00;
out 0x11,R2
.dbline -2
L1:
.dbline 0 ; func end
ret
.dbend
.dbfunc e init_devices _init_devices fV
.even
_init_devices::
.dbline -1
.dbline 20
; }
;
; //call this routine to initialize all peripherals
; void init_devices(void)
; {
.dbline 22
; //stop errant interrupts until set up
; CLI(); //disable all interrupts
cli
.dbline 23
; port_init();
rcall _port_init
.dbline 25
;
; MCUCR = 0x00;
clr R2
out 0x35,R2
.dbline 26
; GICR = 0x00;
out 0x3b,R2
.dbline 27
; TIMSK = 0x00; //timer interrupt sources
out 0x39,R2
.dbline 28
; SEI(); //re-enable interrupts
sei
.dbline -2
L2:
.dbline 0 ; func end
ret
.dbend
.dbfunc e delay_ms _delay_ms fV
; i -> R20,R21
; time -> R16,R17
.even
_delay_ms::
st -y,R20
st -y,R21
.dbline -1
.dbline 66
; //all peripherals are now initialized
; }
;
; /*************************************************************************
; 用 途:iic发送接收
; Taget :mega8
; crystal :8M
; 介 绍:PC4-SDA
; PC5-SCK/SCL
; //***********************************************************************
; I2C 状态定义
; MT 主方式传输 MR 主方式接受
; ***************************/
; #define START 0x08
; #define RE_START 0x10
; #define MT_SLA_ACK 0x18
; #define MT_SLA_NOACK 0x20
; #define MT_DATA_ACK 0x28
; #define MT_DATA_NOACK 0x30
;
; #define MR_SLA_ACK 0x40
; #define MR_SLA_NOACK 0x48
; #define MR_DATA_ACK 0x50
; #define MR_DATA_NOACK 0x58
;
; #define RD_DEVICE_ADDR 0xA1 //前4位器件固定,后三位看连线,最后1位是读写指令位
; #define WD_DEVICE_ADDR 0xA0
; #define Start() (TWCR=(1<<TWINT)|(1<<TWSTA)|(1<<TWEN)) //启动I2C
; #define Stop() (TWCR=(1<<TWINT)|(1<<TWSTO)|(1<<TWEN)) //停止I2C
; #define Wait() {while(!(TWCR&(1<<TWINT)));} //等待中断发生
; #define TestAck() (TWSR&0xf8) //观察返回状态
; #define SetAck (TWCR|=(1<<TWEA)) //做出ACK应答
; #define SetNoAck (TWCR&=~(1<<TWEA)) //做出Not Ack应答
; #define Twi() (TWCR=(1<<TWINT)|(1<<TWEN)) //启动I2C
; #define Write8Bit(x) {TWDR=(x);TWCR=(1<<TWINT)|(1<<TWEN);} //写数据到TWDR
; /*延时子程序*/
; void delay_ms(int time)
; {
.dbline 68
; int i;
; for(;time>0;time--)
rjmp L7
L4:
.dbline 69
; for(i=0;i<1000;i++);
clr R20
clr R21
L8:
.dbline 69
L9:
.dbline 69
subi R20,255 ; offset = 1
sbci R21,255
.dbline 69
cpi R20,232
ldi R30,3
cpc R21,R30
brlt L8
X0:
L5:
.dbline 68
subi R16,1
sbci R17,0
L7:
.dbline 68
clr R2
clr R3
cp R2,R16
cpc R3,R17
brlt L4
X1:
.dbline -2
L3:
.dbline 0 ; func end
ld R21,y+
ld R20,y+
ret
.dbsym r i 20 I
.dbsym r time 16 I
.dbend
.dbfunc e iic_init _iic_init fV
.even
_iic_init::
.dbline -1
.dbline 73
; }
; //初始化
; void iic_init()
; {
.dbline 74
; TWBR= 0x20; //设置波特率
ldi R24,32
out 0x0,R24
.dbline 75
; TWSR= 0x00; //设置预分频比
clr R2
out 0x1,R2
.dbline 76
; TWCR= 0x44; //使能应答,使能TWI
ldi R24,68
out 0x36,R24
.dbline 77
; DDRC|=(1<<PC4)|(1<<PC5);
in R24,0x14
ori R24,48
out 0x14,R24
.dbline 78
; PORTC|=(1<<PC4)|(1<<PC5);
in R24,0x15
ori R24,48
out 0x15,R24
.dbline -2
L12:
.dbline 0 ; func end
ret
.dbend
.dbfunc e iic_write _iic_write fc
; RegAddress -> R12
; Wdata -> R10
.even
_iic_write::
st -y,R10
st -y,R12
mov R12,R18
mov R10,R16
.dbline -1
.dbline 86
; }
; /*********************************************
; I2C总线写一个字节
; 返回0:写成功
; 返回1:写失败
; **********************************************/
; unsigned char iic_write(unsigned char Wdata,unsigned char RegAddress)
; {
.dbline 87
; Start(); //I2C启动
ldi R24,164
out 0x36,R24
.dbline 88
; Wait();
L14:
.dbline 88
L15:
.dbline 88
in R2,0x36
sbrs R2,7
rjmp L14
X2:
.dbline 88
.dbline 88
.dbline 89
; if(TestAck()!=START)
in R24,0x1
andi R24,248
cpi R24,8
breq L17
X3:
.dbline 90
; return 1; //ACK
ldi R16,1
rjmp L13
L17:
.dbline 92
;
; Write8Bit(WD_DEVICE_ADDR); //写I2C从器件地址和写方式
.dbline 92
ldi R24,160
out 0x3,R24
.dbline 92
ldi R24,132
out 0x36,R24
.dbline 92
.dbline 92
.dbline 93
; Wait();
L19:
.dbline 93
L20:
.dbline 93
in R2,0x36
sbrs R2,7
rjmp L19
X4:
.dbline 93
.dbline 93
.dbline 94
; if(TestAck()!=MT_SLA_ACK)
in R24,0x1
andi R24,248
cpi R24,24
breq L22
X5:
.dbline 95
; return 1; //ACK
ldi R16,1
rjmp L13
L22:
.dbline 97
;
; Write8Bit(RegAddress); //写器件相应寄存器地址
.dbline 97
out 0x3,R12
.dbline 97
ldi R24,132
out 0x36,R24
.dbline 97
.dbline 97
.dbline 98
; Wait();
L24:
.dbline 98
L25:
.dbline 98
in R2,0x36
sbrs R2,7
rjmp L24
X6:
.dbline 98
.dbline 98
.dbline 99
; if(TestAck()!=MT_DATA_ACK)
in R24,0x1
andi R24,248
cpi R24,40
breq L27
X7:
.dbline 100
; return 1; //ACK
ldi R16,1
rjmp L13
L27:
.dbline 102
;
; Write8Bit(Wdata); //写数据到器件相应寄存器
.dbline 102
out 0x3,R10
.dbline 102
ldi R24,132
out 0x36,R24
.dbline 102
.dbline 102
.dbline 103
; Wait();
L29:
.dbline 103
L30:
.dbline 103
in R2,0x36
sbrs R2,7
rjmp L29
X8:
.dbline 103
.dbline 103
.dbline 104
; if(TestAck()!=MT_DATA_ACK)
in R24,0x1
andi R24,248
cpi R24,40
breq L32
X9:
.dbline 105
; return 1; //ACK
ldi R16,1
rjmp L13
L32:
.dbline 107
;
; Stop(); //I2C停止
ldi R24,148
out 0x36,R24
.dbline 108
; delay_ms(100); //延时
ldi R16,100
ldi R17,0
rcall _delay_ms
.dbline 109
; return 0;
clr R16
.dbline -2
L13:
.dbline 0 ; func end
ld R12,y+
ld R10,y+
ret
.dbsym r RegAddress 12 c
.dbsym r Wdata 10 c
.dbend
.dbfunc e iic_read _iic_read fc
; temp -> R10
; RegAddress -> R16,R17
.even
_iic_read::
st -y,R10
.dbline -1
.dbline 118
; }
;
; /*********************************************
; I2C总线读一个字节
; 返回非0:读成功
; 返回0:读失败
; **********************************************/
; unsigned char iic_read(unsigned RegAddress)
; {
.dbline 120
; unsigned char temp;
; Start();//I2C启动
ldi R24,164
out 0x36,R24
.dbline 121
; Wait();
L35:
.dbline 121
L36:
.dbline 121
in R2,0x36
sbrs R2,7
rjmp L35
X10:
.dbline 121
.dbline 121
.dbline 122
; if (TestAck()!=START)
in R24,0x1
andi R24,248
cpi R24,8
breq L38
X11:
.dbline 123
; return 1; //ACK
ldi R16,1
rjmp L34
L38:
.dbline 125
;
; Write8Bit(WD_DEVICE_ADDR); //写I2C从器件地址和写方式
.dbline 125
ldi R24,160
out 0x3,R24
.dbline 125
ldi R24,132
out 0x36,R24
.dbline 125
.dbline 125
.dbline 126
; Wait();
L40:
.dbline 126
L41:
.dbline 126
in R2,0x36
sbrs R2,7
rjmp L40
X12:
.dbline 126
.dbline 126
.dbline 127
; if (TestAck()!=MT_SLA_ACK)
in R24,0x1
andi R24,248
cpi R24,24
breq L43
X13:
.dbline 128
; return 1; //ACK
ldi R16,1
rjmp L34
L43:
.dbline 130
;
; Write8Bit(RegAddress); //写器件相应寄存器地址
.dbline 130
out 0x3,R16
.dbline 130
ldi R24,132
out 0x36,R24
.dbline 130
.dbline 130
.dbline 131
; Wait();
L45:
.dbline 131
L46:
.dbline 131
in R2,0x36
sbrs R2,7
rjmp L45
X14:
.dbline 131
.dbline 131
.dbline 132
; if (TestAck()!=MT_DATA_ACK)
in R24,0x1
andi R24,248
cpi R24,40
breq L48
X15:
.dbline 133
; return 1;
ldi R16,1
rjmp L34
L48:
.dbline 135
;
; Start(); //I2C重新启动
ldi R24,164
out 0x36,R24
.dbline 136
; Wait();
L50:
.dbline 136
L51:
.dbline 136
in R2,0x36
sbrs R2,7
rjmp L50
X16:
.dbline 136
.dbline 136
.dbline 137
; if (TestAck()!=RE_START)
in R24,0x1
andi R24,248
cpi R24,16
breq L53
X17:
.dbline 138
; return 1;
ldi R16,1
rjmp L34
L53:
.dbline 140
;
; Write8Bit(RD_DEVICE_ADDR); //写I2C从器件地址和读方式
.dbline 140
ldi R24,161
out 0x3,R24
.dbline 140
ldi R24,132
out 0x36,R24
.dbline 140
.dbline 140
.dbline 141
; Wait();
L55:
.dbline 141
L56:
.dbline 141
in R2,0x36
sbrs R2,7
rjmp L55
X18:
.dbline 141
.dbline 141
.dbline 142
; if(TestAck()!=MR_SLA_ACK)
in R24,0x1
andi R24,248
cpi R24,64
breq L58
X19:
.dbline 143
; return 1; //ACK
ldi R16,1
rjmp L34
L58:
.dbline 145
;
; Twi(); //启动主I2C读方式
ldi R24,132
out 0x36,R24
.dbline 146
; Wait();
L60:
.dbline 146
L61:
.dbline 146
in R2,0x36
sbrs R2,7
rjmp L60
X20:
.dbline 146
.dbline 146
.dbline 147
; if(TestAck()!=MR_DATA_NOACK)
in R24,0x1
andi R24,248
cpi R24,88
breq L63
X21:
.dbline 148
; return 1; //ACK
ldi R16,1
rjmp L34
L63:
.dbline 150
;
; temp=TWDR; //读取I2C接收数据
in R10,0x3
.dbline 151
; Stop(); //I2C停止
ldi R24,148
out 0x36,R24
.dbline 152
; return temp;
mov R16,R10
.dbline -2
L34:
.dbline 0 ; func end
ld R10,y+
ret
.dbsym r temp 10 c
.dbsym r RegAddress 16 i
.dbend
.dbfunc e main _main fV
; i -> R20
; j -> R20
.even
_main::
.dbline -1
.dbline 156
; }
; //****************************************************************************
; void main()
; {
.dbline 158
; unsigned char i,j;
; port_init();
rcall _port_init
.dbline 159
; init_devices();
rcall _init_devices
.dbline 161
;
; iic_init();
rcall _iic_init
.dbline 163
;
; i=iic_write(0xaa,0X10);//在0X10地址写入数据0XAA
ldi R18,16
ldi R16,170
rcall _iic_write
mov R20,R16
.dbline 164
; if (i==1)
cpi R16,1
brne L66
X22:
.dbline 165
; PORTB=0x1;//若写入失败(i=1),B口0x01;若写入成功,B口输出0X02
ldi R24,1
out 0x18,R24
rjmp L67
L66:
.dbline 167
; else
; PORTB=0x2;
ldi R24,2
out 0x18,R24
L67:
.dbline 168
; j=iic_read(0X10);//读出0x10地址的数据
ldi R16,16
ldi R17,0
rcall _iic_read
mov R20,R16
.dbline 169
; if(j==1)
cpi R16,1
brne L68
X23:
.dbline 170
; PORTD=0xff; //若读出失败(j=1),D口全灭;若读出成功,D口输出0XAA
ldi R24,255
out 0x12,R24
rjmp L71
L68:
.dbline 172
; else
; PORTD=j;
out 0x12,R20
L70:
.dbline 174
; while(1)
; {
.dbline 175
; ;
.dbline 176
; }
L71:
.dbline 173
rjmp L70
X24:
.dbline -2
L65:
.dbline 0 ; func end
ret
.dbsym r i 20 c
.dbsym r j 20 c
.dbend
; }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -