📄 i2c.lst
字号:
137
138
139
140
141 //--------------------------------------------------------------------
142 // 中断服务程序
143 //--------------------------------------------------------------------
144 // SMBus中断服务程序
145
146 void IIC_isr(void) reentrant
147 {
148 1
149 1 // OS_ENTER_CRITICAL();
150 1
151 1 SFRPAGE=SMB0_PAGE;
152 1
153 1 switch (SMB0STA)
154 1 { // SMBus状态码(SMB0STA寄存器)
155 2 // 主发送器/接收器:起始条件已发送
156 2 // 在该状态发送的COMMAND字的R/W位总是为0(W),
157 2 // 因为对于读和写操作来说都必须先写存储器地址。
158 2 case SMB_START:
159 2
160 2 SMB0DAT = COMMAND; // 装入要访问的从器件的地址
161 2 STA = 0; // 手动清除START位
162 2 break;
163 2 //主发送器/接收器:重复起始条件已发送。
164 2 // 该状态只应在读操作期间出现,在存储器地址已发送并得到确认之后
165 2 case SMB_RP_START:
166 2
167 2 SMB0DAT = COMMAND; // COMMAND中应保持从地址 + R.
168 2 STA = 0;
169 2 break;
170 2 // 主发送器:从地址 + WRITE已发送,收到ACK。
171 2 case SMB_MTADDACK:
172 2
173 2 SMB0DAT = HIGH_ADD; // 装入待写存储器地址的高字节
174 2 break;
175 2 // 主发送器:从地址 + WRITE已发送,收到NACK。
176 2 // 从器件不应答,发送STOP + START重试
177 2 case SMB_MTADDNACK:
178 2
C51 COMPILER V8.08 I2C 03/02/2009 10:49:10 PAGE 4
179 2 STO = 1; //SMBus停止然后才 STA = 1;
180 2 STA = 1; //SMBus开始 重试
181 2 break;
182 2 // 主发送器:数据字节已发送,收到ACK。
183 2 // 该状态在写和读操作中都要用到。BYTE_NUMBER看存储器地址状态 – 如果
184 2 // 只发送了HIGH_ADD,则装入LOW_ADD。如果LOW_ADD已发送,检查COMMAND
185 2 // 中的R/W 值以决定下一状态。
186 2 case SMB_MTDBACK:
187 2 switch (BYTE_NUMBER)
188 2 {
189 3 case 2: // 如果BYTE_NUMBER=2,
190 3 SMB0DAT = LOW_ADD; // 只发送了HIGH_ADD。
191 3 BYTE_NUMBER--; // 减1,为下一轮作准备
192 3 break;
193 3 case 1: // 如果BYTE_NUMBER=1,LOW_ADD已发送。
194 3 if (COMMAND & 0x01) // 如果R/W=READ,发送重复起始条件
195 3 STA = 1;
196 3 else
197 3 {
198 4 SMB0DAT = IIC_dat; // 如果R/W=WRITE,装入待写字节
199 4 BYTE_NUMBER--;
200 4 }
201 3 break;
202 3
203 3 default: // 如果BYTE_NUMBER=0,传输结束
204 3 STO = 1;
205 3 //OSMboxPost(I2cMbox, (void *)I2C_WRITE_END);
206 3 SM_BUSY = 0; // 释放SMBus
207 3 }
208 2 break;
209 2 // 主发送器:数据字节已发送,收到NACK。
210 2 // 从器件不应答,发送STOP + START重试
211 2 case SMB_MTDBNACK:
212 2 STO = 1;
213 2 STA = 1;
214 2 break;
215 2
216 2
217 2
218 2 // 主发送器:竞争失败
219 2 // 不应出现。如果出现,重新开始传输过程
220 2 case SMB_MTARBLOST:
221 2 STO = 1;
222 2 STA = 1;
223 2 break;
224 2 // 主接收器:从地址 + READ 已发送。收到ACK。
225 2 // 设置为在下一次传输后发送NACK,因为那将是最后一个字节(唯一)。
226 2 case SMB_MRADDACK:
227 2 AA = 0; // 在应答周期NACK。
228 2 break;
229 2 // 主接收器:从地址 + READ 已发送。收到NACK。
230 2 // 从器件不应答,发送重复起始条件重试
231 2 case SMB_MRADDNACK:
232 2 STA = 1;
233 2 break;
234 2 // 收到数据字节。ACK已发送。
235 2 // 该状态不应出现,因为AA已在前一状态被清0。如果出现,发送停止条件。
236 2 case SMB_MRDBACK:
237 2 STO = 1;
238 2 //OSMboxPost(I2cMbox, (void *)I2C_ACK_ERR);
239 2 SM_BUSY = 0;
240 2 break;
C51 COMPILER V8.08 I2C 03/02/2009 10:49:10 PAGE 5
241 2 // 收到数据字节。NACK已发送。
242 2 // 读操作已完成。读数据寄存器后发送停止条件。
243 2 case SMB_MRDBNACK:
244 2 IIC_dat = SMB0DAT;
245 2 STO = 1;
246 2 //OSMboxPost(I2cMbox, (void *)I2C_READ_END);
247 2
248 2 SM_BUSY = 0; // 释放SMBus
249 2 break;
250 2
251 2 // 在本应用中,所有其它状态码没有意义。通信复位。
252 2 default:
253 2 STO = 1; // 通信复位。
254 2 SM_BUSY = 0;
255 2
256 2 //OSMboxPost(I2cMbox, (void *)I2C_NOT_GET_BUS);
257 2 break;
258 2 }
259 1
260 1 SI=0; // 清除中断标志
261 1
262 1 // OS_EXIT_CRITICAL();
263 1 }
264
265
266
MODULE INFORMATION: STATIC OVERLAYABLE
CODE SIZE = 411 ----
CONSTANT SIZE = ---- ----
XDATA SIZE = 6 ----
PDATA SIZE = ---- ----
DATA SIZE = ---- ----
IDATA SIZE = ---- ----
BIT SIZE = ---- ----
END OF MODULE INFORMATION.
C51 COMPILATION COMPLETE. 0 WARNING(S), 0 ERROR(S)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -