📄 i2cint.lst
字号:
ARM COMPILER V2.40a, I2CINT 19/07/07 01:23:00 PAGE 1
ARM COMPILER V2.40a, COMPILATION OF MODULE I2CINT
OBJECT MODULE PLACED IN I2CINT.OBJ
COMPILER INVOKED BY: D:\Program Files\keil\ARM\BIN\CA.exe I2CINT.c THUMB DEBUG TABS(4)
stmt level source
1 /****************************************************************************
2 * 文件名:I2CINT.C
3 * 功能:硬件I2C软件包,利用中断方式操作。
4 * 说明:主程序要配置好I2C总线接口(I2C引脚功能和I2C中断,并已使能I2C主模式)
5 ****************************************************************************/
6 #include "config.h"
7 /* 以下为I2C操作时所需要的变量 */
8 volatile uint8 I2C_sla; // 从机地址(即器件地址)
9 volatile uint8 I2C_suba; // 子地址
10 volatile uint8 *I2C_buf; // 数据缓冲区指针 (读操作时会被更改)
11 volatile uint8 I2C_num; // 操作数据个数 (会被更改)
12 volatile uint8 I2C_end; // 操作结束标志,为1时表示操作结束,为0xFF时表示操作失败 (会被设置)
13 volatile uint8 I2C_suba_en; // 子地址使能控制,读操作时请设置为1,写操作时请设置为2 (会被更改)
14
15 /****************************************************************************
16 * 名称:IRQ_I2C()
17 * 功能:I2C中断,通过判断I2C状态字进行相应的操作。
18 * 入口参数:无
19 * 出口参数:无
20 ****************************************************************************/
21 void IRQ_I2C(void)__irq
22 {
23 1 uint8 sta;
24 1
25 1 sta = I2STAT; // 读出I2C状态字
26 1 switch(sta)
27 1 { case 0x08: // 己发送起始条件
28 2 if(1==I2C_suba_en) I2DAT = I2C_sla&0xFE; // 指定子地址读时,先写入地址
29 2 else I2DAT = I2C_sla; // 否则直接发送从机地址
30 2 I2CONCLR = 0x28; // SI=0
31 2 break;
32 2
33 2 case 0x10:
34 2 I2DAT = I2C_sla; // 重启动总线后,发送从地址
35 2 I2CONCLR = 0x28; // SI=0
36 2 break;
37 2
38 2 case 0x18: // 已发送SLA+W,并已接收应答
39 2 if(0==I2C_suba_en) // 无子地址,则直接发送数据
40 2 { if(I2C_num>0)
41 3 { I2DAT = *I2C_buf++;
42 4 I2CONCLR = 0x28;
43 4 I2C_num--;
44 4 }
45 3 else
46 3 { I2CONSET = 0x10; // 无数据发送,结束总线
47 4 I2CONCLR = 0x28;
48 4 I2C_end = 1; // 设置总线操作结束标志
49 4 }
50 3 break;
51 3 }
52 2 if(1==I2C_suba_en) // 发送子地址
53 2 { I2DAT = I2C_suba;
54 3 I2CONCLR = 0x28;
55 3 }
56 2 if(2==I2C_suba_en)
57 2 { I2DAT = I2C_suba;
58 3 I2CONCLR = 0x28;
59 3 I2C_suba_en = 0; // 子地址己处理
ARM COMPILER V2.40a, I2CINT 19/07/07 01:23:00 PAGE 2
60 3 }
61 2 break;
62 2
63 2 case 0x28: // 已发送I2C数据,并接收到应答
64 2 if(0==I2C_suba_en) // 无子地址,则直接发送数据
65 2 { if(I2C_num>0)
66 3 { I2DAT = *I2C_buf++;
67 4 I2CONCLR = 0x28;
68 4 I2C_num--;
69 4 }
70 3 else
71 3 { I2CONSET = 0x10; // 无数据发送,结束总线
72 4 I2CONCLR = 0x28;
73 4 I2C_end = 1;
74 4 }
75 3 break;
76 3 }
77 2 if(1==I2C_suba_en) // 若是指定地址读,则重新启动总线
78 2 { I2CONSET = 0x20;
79 3 I2CONCLR = 0x08;
80 3 I2C_suba_en = 0; // 子地址己处理
81 3 }
82 2 break;
83 2
84 2
85 2 case 0x20:
86 2 case 0x30:
87 2 case 0x38:
88 2 I2CONCLR = 0x28; // 总线进入不可寻址从模式
89 2 I2C_end = 0xFF; // 总线出错,设置标志
90 2 break;
91 2
92 2
93 2 case 0x40: // 己发送SLA+R,并已接收到应答
94 2 if(1==I2C_num) // 最后一字节,接收数据后发送非应答信号
95 2 { I2CONCLR = 0x2C; // AA=0,接收到数据后产生非应答
96 3 }
97 2 else // 接收数据并发送应答信号
98 2 { I2CONSET = 0x04; // AA=1,接收到数据后产生应答
99 3 I2CONCLR = 0x28;
100 3 }
101 2 break;
102 2
103 2 case 0x50:
104 2 *I2C_buf++ = I2DAT; // 读取数据
105 2 I2C_num--;
106 2 if(1==I2C_num)
107 2 { I2CONCLR = 0x2C; // AA=0,接收到数据后产生非应答
108 3 }
109 2 else
110 2 { I2CONSET = 0x04; // AA=1,接收到数据后产生应答
111 3 I2CONCLR = 0x28;
112 3 }
113 2 break;
114 2
115 2 case 0x58:
116 2 *I2C_buf++ = I2DAT; // 读取最后一字节数据
117 2 I2CONSET = 0x10; // 结束总线
118 2 I2CONCLR = 0x28;
119 2 I2C_end = 1;
120 2 break;
121 2
122 2 case 0x48:
123 2 I2CONCLR = 0x28; // 总线进入不可寻址从模式
124 2 I2C_end = 0xFF;
125 2 break;
ARM COMPILER V2.40a, I2CINT 19/07/07 01:23:00 PAGE 3
126 2
127 2 default:
128 2 break;
129 2 }
130 1
131 1 //I2CONCLR = 0x08;
132 1 VICVectAddr = 0x00; // 中断处理结束
133 1 }
134
135 /****************************************************************************
136 * 名称:ISendByte()
137 * 功能:向无子地址器件发送一字节数据。
138 * 入口参数:sla 器件地址
139 * dat 要发送的数据
140 * 出口参数:返回值为0时表示出错,为1时表示操作正确。
141 * 说明:使用前要初始化好I2C引脚功能和I2C中断,并已使能I2C主模式
142 ****************************************************************************/
143 uint8 ISendByte(uint8 sla, uint8 dat)
144 { /* 参数设置 */
145 1 I2C_sla = sla; // 写操作的器件地址
146 1 I2C_buf = &dat; // 待发送的数据
147 1 I2C_num = 1; // 发送1字节数据
148 1 I2C_suba_en = 0; // 无子地址
149 1 I2C_end = 0;
150 1
151 1 I2CONCLR = 0x2C;
152 1 I2CONSET = 0x60; // 设置为主机,并启动总线
153 1
154 1 while(0==I2C_end);
155 1 if(1==I2C_end) return(1);
156 1 else return(0);
157 1 }
158
159 /****************************************************************************
160 * 名称:ISendStr()
161 * 功能:向有子地址器件发送多字节数据。
162 * 入口参数:sla 器件从机地址
163 * suba 器件子地址
164 * s 数据发送缓冲区指针
165 * no 发送数据个数
166 * 出口参数:返回值为0时表示出错,为1时表示操作正确。
167 * 说明:使用前要初始化好I2C引脚功能和I2C中断,并已使能I2C主模式
168 ****************************************************************************/
169 uint8 ISendStr(uint8 sla, uint8 suba, uint8 *s, uint8 no)
170 { /* 参数设置 */
171 1 I2C_sla = sla; // 写操作的器件地址
172 1 I2C_suba = suba; // 子地址
173 1 I2C_buf = s;
174 1 I2C_num = no;
175 1 I2C_suba_en = 2; // 有子地址写
176 1 I2C_end = 0;
177 1
178 1 I2CONCLR = 0x2C;
179 1 I2CONSET = 0x60; // 设置为主机,并启动总线
180 1
181 1 while(0==I2C_end);
182 1 if(1==I2C_end) return(1);
183 1 else return(0);
184 1 }
185
186
187
188 /****************************************************************************
189 * 名称:IRcvByte()
190 * 功能:向无子地址器件读取一字节数据。
191 * 入口参数:sla 器件地址
ARM COMPILER V2.40a, I2CINT 19/07/07 01:23:00 PAGE 4
192 * dat 接收数据的变量指针
193 * 出口参数:返回值为0时表示操作出错,为1时表示操作正确。
194 * 说明:使用前要初始化好I2C引脚功能和I2C中断,并已使能I2C主模式
195 ****************************************************************************/
196 uint8 IRcvByte(uint8 sla, uint8 *dat)
197 { /* 参数设置 */
198 1 I2C_sla = sla+1; // 读操作的器件地址
199 1 I2C_buf = dat;
200 1 I2C_num = 1;
201 1 I2C_suba_en = 0; // 无子地址
202 1 I2C_end = 0;
203 1
204 1 I2CONCLR = 0x2C;
205 1 I2CONSET = 0x60; // 设置为主机,并启动总线
206 1
207 1 while(0==I2C_end);
208 1 if(1==I2C_end) return(1);
209 1 else return(0);
210 1 }
211
212
213
214 /****************************************************************************
215 * 名称:IRcvStr()
216 * 功能:向有子地址器件读取多字节数据。
217 * 入口参数:sla 器件地址
218 * suba 器件子地址
219 * s 数据接收缓冲区指针
220 * no 读取数据个数
221 * 出口参数:返回值为0时表示操作出错,为1时表示操作正确。
222 * 说明:使用前要初始化好I2C引脚功能和I2C中断,并已使能I2C主模式
223 ****************************************************************************/
224 uint8 IRcvStr(uint8 sla, uint8 suba, uint8 *s, uint8 no)
225 { if(0==no) return(0);
226 1
227 1 /* 参数设置 */
228 1 I2C_sla = sla+1; // 读操作的器件地址
229 1 I2C_suba = suba;
230 1 I2C_buf = s;
231 1 I2C_num = no;
232 1 I2C_suba_en = 1; // 有子地址读
233 1 I2C_end = 0;
234 1
235 1 I2CONCLR = 0x2C;
236 1 I2CONSET = 0x60; // 设置为主机,并启动总线
237 1
238 1 while(0==I2C_end);
239 1 if(1==I2C_end) return(1);
240 1 else return(0);
241 1 }
ARM COMPILER V2.40a, I2CINT 19/07/07 01:23:00 PAGE 5
ASSEMBLY LISTING OF GENERATED OBJECT CODE
*** PUBLICS:
PUBLIC IRQ_I2C?A
PUBLIC ISendByte?T
PUBLIC ISendStr?T
PUBLIC IRcvByte?T
PUBLIC IRcvStr?T
PUBLIC I2C_sla
PUBLIC I2C_suba
PUBLIC I2C_buf
PUBLIC I2C_num
PUBLIC I2C_end
PUBLIC I2C_suba_en
*** DATA SEGMENT '?DT0?I2CINT':
00000000 I2C_buf:
00000000 DS 4
00000004 I2C_sla:
00000004 DS 1
00000005 I2C_suba:
00000005 DS 1
00000006 I2C_num:
00000006 DS 1
00000007 I2C_end:
00000007 DS 1
00000008 I2C_suba_en:
00000008 DS 1
*** CODE SEGMENT '?PR?IRQ_I2C?A?I2CINT':
21: void IRQ_I2C(void)__irq
00000000 E92D000F STMDB R13!,{R0-R3}
22: {
00000004 ; SCOPE-START
25: sta = I2STAT; // 读出I2C状态字
00000004 E5100000 LDR R0,=0xE001C004
00000008 E5D01000 LDRB R1,[R0,#0x0]
0000000C ---- Variable 'sta' assigned to Register 'R1' ----
26: switch(sta)
0000000C E1A00001 MOV R0,R1 ; sta
00000010 E3500010 CMP R0,#0x0010 ; sta
00000014 0A000026 BEQ L_4 ; Targ=0xB4
00000018 E3500018 CMP R0,#0x0018 ; sta
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -