📄 iic接口读写.lst
字号:
__text_start:
__start:
13 E5CF LDI R28,0x5F
14 E0D4 LDI R29,4
15 BFCD OUT 0x3D,R28
16 BFDE OUT 0x3E,R29
17 51CE SUBI R28,0x1E
18 40D0 SBCI R29,0
19 EA0A LDI R16,0xAA
1A 8308 STD Y+0,R16
1B 2400 CLR R0
1C E6E0 LDI R30,0x60
1D E0F0 LDI R31,0
1E E010 LDI R17,0
1F 36E0 CPI R30,0x60
20 07F1 CPC R31,R17
21 F011 BEQ 0x0024
22 9201 ST R0,Z+
23 CFFB RJMP 0x001F
24 8300 STD Z+0,R16
25 E2E6 LDI R30,0x26
26 E0F0 LDI R31,0
27 E6A0 LDI R26,0x60
28 E0B0 LDI R27,0
29 E010 LDI R17,0
2A E000 LDI R16,0
2B BF0B OUT 0x3B,R16
2C 32E6 CPI R30,0x26
2D 07F1 CPC R31,R17
2E F021 BEQ 0x0033
2F 95C8 LPM
30 9631 ADIW R30,1
31 920D ST R0,X+
32 CFF9 RJMP 0x002C
33 D0BE RCALL _main
_exit:
34 CFFF RJMP _exit
FILE: E:\xiaozhiyong2009\设计资料\项目设计\ICCAVR_mega8_C\ICCAVR_mega8_IIC接口读写\IIC接口读写.c
(0001) //ICC-AVR application builder : 2009-3-12 17:05:04
(0002) // Target : M8
(0003) // Crystal: 8.0000Mhz
(0004)
(0005) #include <iom8v.h>
(0006) #include <macros.h>
(0007)
(0008) void port_init(void)
(0009) {
(0010) PORTB = 0x00;
_port_init:
35 2422 CLR R2
36 BA28 OUT 0x18,R2
(0011) DDRB = 0x00;
37 BA27 OUT 0x17,R2
(0012) PORTC = 0x00; //m103 output only
38 BA25 OUT 0x15,R2
(0013) DDRC = 0x00;
39 BA24 OUT 0x14,R2
(0014) PORTD = 0x00;
3A BA22 OUT 0x12,R2
(0015) DDRD = 0x00;
3B BA21 OUT 0x11,R2
3C 9508 RET
(0016) }
(0017)
(0018) //call this routine to initialize all peripherals
(0019) void init_devices(void)
(0020) {
(0021) //stop errant interrupts until set up
(0022) CLI(); //disable all interrupts
_init_devices:
3D 94F8 BCLR 7
(0023) port_init();
3E DFF6 RCALL _port_init
(0024)
(0025) MCUCR = 0x00;
3F 2422 CLR R2
40 BE25 OUT 0x35,R2
(0026) GICR = 0x00;
41 BE2B OUT 0x3B,R2
(0027) TIMSK = 0x00; //timer interrupt sources
42 BE29 OUT 0x39,R2
(0028) SEI(); //re-enable interrupts
43 9478 BSET 7
44 9508 RET
_delay_ms:
i --> R20
time --> R16
45 934A ST R20,-Y
46 935A ST R21,-Y
(0029) //all peripherals are now initialized
(0030) }
(0031)
(0032) /*************************************************************************
(0033) 用 途:iic发送接收
(0034) Taget :mega8
(0035) crystal :8M
(0036) 介 绍:PC4-SDA
(0037) PC5-SCK/SCL
(0038) //***********************************************************************
(0039) I2C 状态定义
(0040) MT 主方式传输 MR 主方式接受
(0041) ***************************/
(0042) #define START 0x08
(0043) #define RE_START 0x10
(0044) #define MT_SLA_ACK 0x18
(0045) #define MT_SLA_NOACK 0x20
(0046) #define MT_DATA_ACK 0x28
(0047) #define MT_DATA_NOACK 0x30
(0048)
(0049) #define MR_SLA_ACK 0x40
(0050) #define MR_SLA_NOACK 0x48
(0051) #define MR_DATA_ACK 0x50
(0052) #define MR_DATA_NOACK 0x58
(0053)
(0054) #define RD_DEVICE_ADDR 0xA1 //前4位器件固定,后三位看连线,最后1位是读写指令位
(0055) #define WD_DEVICE_ADDR 0xA0
(0056) #define Start() (TWCR=(1<<TWINT)|(1<<TWSTA)|(1<<TWEN)) //启动I2C
(0057) #define Stop() (TWCR=(1<<TWINT)|(1<<TWSTO)|(1<<TWEN)) //停止I2C
(0058) #define Wait() {while(!(TWCR&(1<<TWINT)));} //等待中断发生
(0059) #define TestAck() (TWSR&0xf8) //观察返回状态
(0060) #define SetAck (TWCR|=(1<<TWEA)) //做出ACK应答
(0061) #define SetNoAck (TWCR&=~(1<<TWEA)) //做出Not Ack应答
(0062) #define Twi() (TWCR=(1<<TWINT)|(1<<TWEN)) //启动I2C
(0063) #define Write8Bit(x) {TWDR=(x);TWCR=(1<<TWINT)|(1<<TWEN);} //写数据到TWDR
(0064) /*延时子程序*/
(0065) void delay_ms(int time)
(0066) {
(0067) int i;
(0068) for(;time>0;time--)
47 C00A RJMP 0x0052
(0069) for(i=0;i<1000;i++);
48 2744 CLR R20
49 2755 CLR R21
4A 5F4F SUBI R20,0xFF
4B 4F5F SBCI R21,0xFF
4C 3E48 CPI R20,0xE8
4D E0E3 LDI R30,3
4E 075E CPC R21,R30
4F F3D4 BLT 0x004A
50 5001 SUBI R16,1
51 4010 SBCI R17,0
52 2422 CLR R2
53 2433 CLR R3
54 1620 CP R2,R16
55 0631 CPC R3,R17
56 F38C BLT 0x0048
57 9159 LD R21,Y+
58 9149 LD R20,Y+
59 9508 RET
(0070) }
(0071) //初始化
(0072) void iic_init()
(0073) {
(0074) TWBR= 0x20; //设置波特率
_iic_init:
5A E280 LDI R24,0x20
5B B980 OUT 0x00,R24
(0075) TWSR= 0x00; //设置预分频比
5C 2422 CLR R2
5D B821 OUT 0x01,R2
(0076) TWCR= 0x44; //使能应答,使能TWI
5E E484 LDI R24,0x44
5F BF86 OUT 0x36,R24
(0077) DDRC|=(1<<PC4)|(1<<PC5);
60 B384 IN R24,0x14
61 6380 ORI R24,0x30
62 BB84 OUT 0x14,R24
(0078) PORTC|=(1<<PC4)|(1<<PC5);
63 B385 IN R24,0x15
64 6380 ORI R24,0x30
65 BB85 OUT 0x15,R24
66 9508 RET
_iic_write:
RegAddress --> R12
Wdata --> R10
67 92AA ST R10,-Y
68 92CA ST R12,-Y
69 2EC2 MOV R12,R18
6A 2EA0 MOV R10,R16
(0079) }
(0080) /*********************************************
(0081) I2C总线写一个字节
(0082) 返回0:写成功
(0083) 返回1:写失败
(0084) **********************************************/
(0085) unsigned char iic_write(unsigned char Wdata,unsigned char RegAddress)
(0086) {
(0087) Start(); //I2C启动
6B EA84 LDI R24,0xA4
6C BF86 OUT 0x36,R24
(0088) Wait();
6D B626 IN R2,0x36
6E FE27 SBRS R2,7
6F CFFD RJMP 0x006D
(0089) if(TestAck()!=START)
70 B181 IN R24,0x01
71 7F88 ANDI R24,0xF8
72 3088 CPI R24,0x8
73 F011 BEQ 0x0076
(0090) return 1; //ACK
74 E001 LDI R16,1
75 C02B RJMP 0x00A1
(0091)
(0092) Write8Bit(WD_DEVICE_ADDR); //写I2C从器件地址和写方式
76 EA80 LDI R24,0xA0
77 B983 OUT 0x03,R24
78 E884 LDI R24,0x84
79 BF86 OUT 0x36,R24
(0093) Wait();
7A B626 IN R2,0x36
7B FE27 SBRS R2,7
7C CFFD RJMP 0x007A
(0094) if(TestAck()!=MT_SLA_ACK)
7D B181 IN R24,0x01
7E 7F88 ANDI R24,0xF8
7F 3188 CPI R24,0x18
80 F011 BEQ 0x0083
(0095) return 1; //ACK
81 E001 LDI R16,1
82 C01E RJMP 0x00A1
(0096)
(0097) Write8Bit(RegAddress); //写器件相应寄存器地址
83 B8C3 OUT 0x03,R12
84 E884 LDI R24,0x84
85 BF86 OUT 0x36,R24
(0098) Wait();
86 B626 IN R2,0x36
87 FE27 SBRS R2,7
88 CFFD RJMP 0x0086
(0099) if(TestAck()!=MT_DATA_ACK)
89 B181 IN R24,0x01
8A 7F88 ANDI R24,0xF8
8B 3288 CPI R24,0x28
8C F011 BEQ 0x008F
(0100) return 1; //ACK
8D E001 LDI R16,1
8E C012 RJMP 0x00A1
(0101)
(0102) Write8Bit(Wdata); //写数据到器件相应寄存器
8F B8A3 OUT 0x03,R10
90 E884 LDI R24,0x84
91 BF86 OUT 0x36,R24
(0103) Wait();
92 B626 IN R2,0x36
93 FE27 SBRS R2,7
94 CFFD RJMP 0x0092
(0104) if(TestAck()!=MT_DATA_ACK)
95 B181 IN R24,0x01
96 7F88 ANDI R24,0xF8
97 3288 CPI R24,0x28
98 F011 BEQ 0x009B
(0105) return 1; //ACK
99 E001 LDI R16,1
9A C006 RJMP 0x00A1
(0106)
(0107) Stop(); //I2C停止
9B E984 LDI R24,0x94
9C BF86 OUT 0x36,R24
(0108) delay_ms(100); //延时
9D E604 LDI R16,0x64
9E E010 LDI R17,0
9F DFA5 RCALL _delay_ms
(0109) return 0;
A0 2700 CLR R16
A1 90C9 LD R12,Y+
A2 90A9 LD R10,Y+
A3 9508 RET
_iic_read:
temp --> R10
RegAddress --> R16
A4 92AA ST R10,-Y
(0110) }
(0111)
(0112) /*********************************************
(0113) I2C总线读一个字节
(0114) 返回非0:读成功
(0115) 返回0:读失败
(0116) **********************************************/
(0117) unsigned char iic_read(unsigned RegAddress)
(0118) {
(0119) unsigned char temp;
(0120) Start();//I2C启动
A5 EA84 LDI R24,0xA4
A6 BF86 OUT 0x36,R24
(0121) Wait();
A7 B626 IN R2,0x36
A8 FE27 SBRS R2,7
A9 CFFD RJMP 0x00A7
(0122) if (TestAck()!=START)
AA B181 IN R24,0x01
AB 7F88 ANDI R24,0xF8
AC 3088 CPI R24,0x8
AD F011 BEQ 0x00B0
(0123) return 1; //ACK
AE E001 LDI R16,1
AF C040 RJMP 0x00F0
(0124)
(0125) Write8Bit(WD_DEVICE_ADDR); //写I2C从器件地址和写方式
B0 EA80 LDI R24,0xA0
B1 B983 OUT 0x03,R24
B2 E884 LDI R24,0x84
B3 BF86 OUT 0x36,R24
(0126) Wait();
B4 B626 IN R2,0x36
B5 FE27 SBRS R2,7
B6 CFFD RJMP 0x00B4
(0127) if (TestAck()!=MT_SLA_ACK)
B7 B181 IN R24,0x01
B8 7F88 ANDI R24,0xF8
B9 3188 CPI R24,0x18
BA F011 BEQ 0x00BD
(0128) return 1; //ACK
BB E001 LDI R16,1
BC C033 RJMP 0x00F0
(0129)
(0130) Write8Bit(RegAddress); //写器件相应寄存器地址
BD B903 OUT 0x03,R16
BE E884 LDI R24,0x84
BF BF86 OUT 0x36,R24
(0131) Wait();
C0 B626 IN R2,0x36
C1 FE27 SBRS R2,7
C2 CFFD RJMP 0x00C0
(0132) if (TestAck()!=MT_DATA_ACK)
C3 B181 IN R24,0x01
C4 7F88 ANDI R24,0xF8
C5 3288 CPI R24,0x28
C6 F011 BEQ 0x00C9
(0133) return 1;
C7 E001 LDI R16,1
C8 C027 RJMP 0x00F0
(0134)
(0135) Start(); //I2C重新启动
C9 EA84 LDI R24,0xA4
CA BF86 OUT 0x36,R24
(0136) Wait();
CB B626 IN R2,0x36
CC FE27 SBRS R2,7
CD CFFD RJMP 0x00CB
(0137) if (TestAck()!=RE_START)
CE B181 IN R24,0x01
CF 7F88 ANDI R24,0xF8
D0 3180 CPI R24,0x10
D1 F011 BEQ 0x00D4
(0138) return 1;
D2 E001 LDI R16,1
D3 C01C RJMP 0x00F0
(0139)
(0140) Write8Bit(RD_DEVICE_ADDR); //写I2C从器件地址和读方式
D4 EA81 LDI R24,0xA1
D5 B983 OUT 0x03,R24
D6 E884 LDI R24,0x84
D7 BF86 OUT 0x36,R24
(0141) Wait();
D8 B626 IN R2,0x36
D9 FE27 SBRS R2,7
DA CFFD RJMP 0x00D8
(0142) if(TestAck()!=MR_SLA_ACK)
DB B181 IN R24,0x01
DC 7F88 ANDI R24,0xF8
DD 3480 CPI R24,0x40
DE F011 BEQ 0x00E1
(0143) return 1; //ACK
DF E001 LDI R16,1
E0 C00F RJMP 0x00F0
(0144)
(0145) Twi(); //启动主I2C读方式
E1 E884 LDI R24,0x84
E2 BF86 OUT 0x36,R24
(0146) Wait();
E3 B626 IN R2,0x36
E4 FE27 SBRS R2,7
E5 CFFD RJMP 0x00E3
(0147) if(TestAck()!=MR_DATA_NOACK)
E6 B181 IN R24,0x01
E7 7F88 ANDI R24,0xF8
E8 3588 CPI R24,0x58
E9 F011 BEQ 0x00EC
(0148) return 1; //ACK
EA E001 LDI R16,1
EB C004 RJMP 0x00F0
(0149)
(0150) temp=TWDR; //读取I2C接收数据
EC B0A3 IN R10,0x03
(0151) Stop(); //I2C停止
ED E984 LDI R24,0x94
EE BF86 OUT 0x36,R24
(0152) return temp;
EF 2D0A MOV R16,R10
F0 90A9 LD R10,Y+
F1 9508 RET
(0153) }
(0154) //****************************************************************************
(0155) void main()
(0156) {
(0157) unsigned char i,j;
(0158) port_init();
_main:
i --> R20
j --> R20
F2 DF42 RCALL _port_init
(0159) init_devices();
F3 DF49 RCALL _init_devices
(0160)
(0161) iic_init();
F4 DF65 RCALL _iic_init
(0162)
(0163) i=iic_write(0xaa,0X10);//在0X10地址写入数据0XAA
F5 E120 LDI R18,0x10
F6 EA0A LDI R16,0xAA
F7 DF6F RCALL _iic_write
F8 2F40 MOV R20,R16
(0164) if (i==1)
F9 3001 CPI R16,1
FA F419 BNE 0x00FE
(0165) PORTB=0x1;//若写入失败(i=1),B口0x01;若写入成功,B口输出0X02
FB E081 LDI R24,1
FC BB88 OUT 0x18,R24
FD C002 RJMP 0x0100
(0166) else
(0167) PORTB=0x2;
FE E082 LDI R24,2
FF BB88 OUT 0x18,R24
(0168) j=iic_read(0X10);//读出0x10地址的数据
100 E100 LDI R16,0x10
101 E010 LDI R17,0
102 DFA1 RCALL _iic_read
103 2F40 MOV R20,R16
(0169) if(j==1)
104 3001 CPI R16,1
105 F419 BNE 0x0109
(0170) PORTD=0xff; //若读出失败(j=1),D口全灭;若读出成功,D口输出0XAA
106 EF8F LDI R24,0xFF
107 BB82 OUT 0x12,R24
108 C001 RJMP 0x010A
(0171) else
(0172) PORTD=j;
109 BB42 OUT 0x12,R20
(0173) while(1)
FILE: <library>
10A CFFF RJMP 0x010A
10B 9508 RET
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -