📄 i2c.lst
字号:
C51 COMPILER V7.02b I2C 12/12/2005 10:34:32 PAGE 1
C51 COMPILER V7.02b, COMPILATION OF MODULE I2C
OBJECT MODULE PLACED IN I2C.OBJ
COMPILER INVOKED BY: E:\EDATOOLS\KEILC7.0\C51\BIN\C51.EXE I2C.c BROWSE DEBUG OBJECTEXTEND
stmt level source
1 /*****************************************/
2 /* Copyright (c) 2005, 通信工程学院 */
3 /* All rights reserved. */
4 /* 作 者:戴 佳 */
5 /*****************************************/
6
7 #include "I2C.h"
8
9 /* 延时约5微秒,对于12M时钟 */
10 void delay5us()
11 {
12 1 uint i;
13 1 for (i=0;i<5;i++)
14 1 _nop_();
15 1 }
16
17 /* 起始条件子函数 */
18 void start(void)
19 {
20 1 SDA = 1; // 启动I2C总线
21 1 SCL = 1;
22 1 delay5us();
23 1 SDA = 0;
24 1 delay5us();
25 1 SCL = 0;
26 1 }
27
28 /* 停止条件子函数 */
29 void stop(void)
30 {
31 1 SDA = 0; // 停止I2C总线数据传送
32 1 SCL = 1;
33 1 delay5us();
34 1 SDA = 1;
35 1 delay5us();
36 1 SCL = 0;
37 1 }
38
39 /* 发送应答子函数 */
40 void ack(void)
41 {
42 1 SDA = 0; // 发送应答位
43 1 SCL = 1;
44 1 delay5us();
45 1 SDA = 1;
46 1 SCL = 0;
47 1 }
48
49 /* 发送非应答子函数 */
50 void n_ack(void)
51 {
52 1 SDA = 1; // 发送非应答位
53 1 SCL = 1;
54 1 delay5us();
55 1 SDA = 0;
C51 COMPILER V7.02b I2C 12/12/2005 10:34:32 PAGE 2
56 1 SCL = 0;
57 1 }
58
59 /* 应答位检查子函数 */
60 void checkack(void)
61 {
62 1 SDA = 1; // 应答位检查(将p1.0设置成输入,必须先向端口写1)
63 1 SCL = 1;
64 1 nackFlag = 0;
65 1 if(SDA == 1) // 若SDA=1表明非应答,置位非应答标志F0
66 1 nackFlag = 1;
67 1 SCL = 0;
68 1 }
69
70 /* 发送一个字节数据子函数 */
71 void sendbyte(uchar idata *ch)
72 {
73 1 uchar idata n = 8;
74 1 uchar idata temp;
75 1 temp = *ch;
76 1 while(n--)
77 1 {
78 2 if((temp&0x80) == 0x80) // 若要发送的数据最高位为1则发送位1
79 2 {
80 3 SDA = 1; // 传送位1
81 3 SCL = 1;
82 3 delay5us();
83 3 SDA = 0;
84 3 SCL = 0;
85 3 }
86 2 else
87 2 {
88 3 SDA = 0; // 否则传送位0
89 3 SCL = 1;
90 3 delay5us();
91 3 SCL = 0;
92 3 }
93 2 temp = temp<<1; // 数据左移一位
94 2 }
95 1 }
96
97
98 /* 接收一字节子程序 */
99 void recbyte(uchar idata *ch)
100 {
101 1 uchar idata n=8; // 从SDA线上读取一位数据字节,共8位
102 1 uchar idata temp = 0;
103 1 while(n--)
104 1 {
105 2 SDA = 1;
106 2 SCL = 1;
107 2 temp = temp<<1; // 左移一位
108 2 if(SDA == 1)
109 2 temp = temp|0x01; // 若接收到的位为1,则数据的最后一位置1
110 2 else
111 2 temp = temp&0xfe; // 否则数据的最后一位置0
112 2 SCL=0;
113 2 }
114 1 *ch = temp;
115 1 }
116
117 /* 发送n字节数据子程序 */
C51 COMPILER V7.02b I2C 12/12/2005 10:34:32 PAGE 3
118 void sendnbyte(uchar idata *sla, uchar n)
119 {
120 1 uchar idata *p;
121 1 start(); // 发送启动信号
122 1 sendbyte(sla); // 发送从器件地址字节
123 1 checkack(); // 检查应答位
124 1 if(F0 == 1)
125 1 {
126 2 NACK = 1;
127 2 return; // 若非应答表明器件错误或已坏,置错误标志位NACK
128 2 }
129 1 p = sbuf;
130 1 while(n--)
131 1 {
132 2 sendbyte(p);
133 2 checkack(); // 检查应答位
134 2 if (nackFlag == 1)
135 2 {
136 3 NACK=1;
137 3 return; // 若非应答表明器件错误或已坏,置错误标志位NACK
138 3 }
139 2 p++;
140 2 }
141 1 stop(); // 全部发完则停止
142 1 }
143
144 /* 接收n字节数据子程序 */
145 void recnbyte(uchar idata *sla, uchar n)
146 {
147 1 uchar idata *p;
148 1 start(); // 发送启动信号
149 1 sendbyte(sla); // 发送从器件地址字节
150 1 checkack(); // 检查应答位
151 1 if(nackFlag == 1)
152 1 {
153 2 NACK = 1;
154 2 return;
155 2 }
156 1 p = rbuf; // 接收字节存放在rbuf中
157 1 while(n--)
158 1 {
159 2 recbyte (p);
160 2 ack(); // 收到一个字节后发送一个应答位
161 2 p++;
162 2 }
163 1 n_ack(); // 收到最后一个字节后发送一个非应答位
164 1 stop();
165 1 }
166
167 /* 主函数,模拟实现I2C总线的数据收发 */
168 void main(void)
169 {
170 1 uchar i,numbyte;
171 1
172 1 numbyte = 8;
173 1
174 1 /* 需发送的8字节数据 */
175 1 for (i=0;i<numbyte;i++)
176 1 sbuf[i] = i+0x11;
177 1
178 1 SLAdd = 0x58; // 从器件地址
179 1
C51 COMPILER V7.02b I2C 12/12/2005 10:34:32 PAGE 4
180 1 sendnbyte(&SLAdd,numbyte); // 向从器件发送存放在sbuf中的8字节数据
181 1
182 1 for (i=0;i<10000;i++)
183 1 delay5us();
184 1
185 1 recnbyte(&SLAdd,numbyte); // 由从器件接收8字节数据,存放在rbuf中
186 1
187 1 }
188
189
190
191
192
MODULE INFORMATION: STATIC OVERLAYABLE
CODE SIZE = 320 ----
CONSTANT SIZE = ---- ----
XDATA SIZE = ---- ----
PDATA SIZE = ---- ----
DATA SIZE = ---- ----
IDATA SIZE = 17 4
BIT SIZE = 2 ----
END OF MODULE INFORMATION.
C51 COMPILATION COMPLETE. 0 WARNING(S), 0 ERROR(S)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -