📄 i2c_2.lst
字号:
1:
2: /*******************************************************************
3: 一、程序说明:
4: 1, 24LC02器件地址是1010000R/W. 同时也一部分为SMBUS 0x16
5: 2, 数组写入24LC02采取页写方式.
6: 3, 数组code从24LC02读出时采取自由读方式.
7: 4, 采用4.00M晶体。
8: 5,采用软件I2C。
9:
10: 二、硬件连接:
11: 1, SDA_DIRE------->23 pin.(当然你可以任意选择脚位)
12: 2, SCL_DIRE------->18 Pin.(当然你可以任意选择脚位)
13: 3, PORTD----->外接8个LED,显示读出的数据,在这里,读出的刚好是一个闪动的流水灯状态。
14:
15: *******************************************************************/
16: #include "pic.h"
17:
18: #define uchar unsigned char
19: #define nop() asm("nop")
20: //#define SCL_DIRE TRISC3 //PIC mcu专用I2C
21: //#define SDA_DIRE TRISC4
22: //#define SCL RC3
23: //#define SDA_E RC4
24:
25: //#define SCL RA0
26: //#define SDA RA1
27: //#define SCL_DIR TRISA0
28: //#define SDA_DIR TRISA1
29:
30: void start_i2c();
31: void stop_i2c();
32: void send_byte(uchar c);
33: uchar receive_byte();
34: void I_send_str(uchar sla,uchar suba,uchar *s,uchar no);
35: void I_send_word(uchar sla,uchar suba,uchar datal,uchar datah);
36: void delay_250ms();
37: void i2c_error ();
38: int ReadByte_EE(uchar addr);
39:
40:
41: uchar code[]={0x34,0x64,0x03,0x07,0x0f,0x1f,0x3f,0x7f,0xff};
42: uchar no,ack,c,data;
43:
44:
45: /*******************************************************************
46: 起动总线函数
47: 函数原型: void start_i2c();
48: Function: start on the I2C bus
49: *******************************************************************/
50: void start_i2c()
51: {
52: SDA_DIR=1; //发送启始条件的数据信号
53: nop();
54: SCL_DIR=1;
55: nop();nop();nop();nop();nop(); //24LC02要求建立时间大于4,7S
56: SDA_DIR=0; //发送起始信号
57: nop();nop();nop();nop();nop();
58: SCL_DIR=0; //钳住I2C总线,准备发送数据或接收数据
59: nop();nop();
60: }
61:
62:
63: /*******************************************************************
64: 停止总线函数
65: 函数原型: void stop_i2c();
66: Function: stop the I2C bus
67: *******************************************************************/
68: void stop_i2c()
69: {
70:
71: SDA_DIR=0; //发送结束条件的数据信号
72: nop();
73: SCL_DIR=1;
74: nop();nop();nop();nop();nop();
75: SDA_DIR=1;
76: nop();nop();nop();nop();
77: }
78:
79: /*=================================================================
80: 字节数据传送函数
81: 函数原型: void send_byte(uchar c);
82: Function: 将数据C发送出去,可以是地址,也可以是数据,发完后等待回应,并对此状态
83: 位进行操作(不应答或非应答都使ack=0 ),发送数据正常,ack=1;ack=0
84: 表示被控器无应答或损坏。
85: ==================================================================*/
86: void send_byte(uchar c)
87: {
88: uchar bit_count;
89: for (bit_count=0;bit_count<8;bit_count++)
90: {
91: if ((c<<bit_count)&0x80) {SDA_DIR=1;}
92: else {SDA_DIR=0;}
93: nop();
94: SCL_DIR=1;
95: nop();nop();nop();nop();nop();
96: SCL_DIR=0;
97: }
98: nop();nop();
99: SDA_DIR=1;
100: nop();nop();
101: SCL_DIR=1;
102: nop();nop();nop();
103: if (SDA==1) ack=0;
104: else ack=1; //用ASK=1为有应答信号
105: SCL_DIR=0;
106: nop();nop();
107: }
108:
109: /*==================================================================
110: 字节数据接收函数
111: 函数原型:uchar receive_byte();
112: FUNCTION: 用来接收从器件传来的数据,并判断总线错误(不发应答信号),
113: 发完后请用应答函数。
114: ===================================================================*/
115: uchar receive_byte()
116: {
117: uchar retc,bit_count;
118: retc=0;
119: SDA_DIR=1;
120: for (bit_count=0;bit_count<8;bit_count++)
121: {
122: nop();
123: SCL_DIR=0;
124: nop();nop();nop();nop();nop();
125: SCL_DIR=1;
126: nop();nop();
127: retc=retc<<1;
128: if (SDA==1) retc=retc+1;
129: nop();nop();
130: }
131: SCL_DIR=0;
132: nop();nop();
133: return (retc);
134: }
135:
136: ////////********************************//////////////
137: int ReadByte_EE(uchar addr){
138: uchar data1;
139: start_i2c();
140: send_byte(0xA0); //发送器件地址,即DEVICE ADDRESS。
141: if (ack==0) i2c_error(); //如果24LC02无应答。则进入I2C ERROR错误指示。
142: send_byte(addr); //发送字地址,即WORD ADDRESS。D口显示数组。
143: if (ack==0) i2c_error();
144: start_i2c(); //重新启动总线。
145: send_byte(0xA1); //发送读命令和器件地址DEVICE ADDRESS。
146: if (ack==0) i2c_error();
147: data1=receive_byte();
148: stop_i2c();
149: return(data1);
150: }
151:
152:
153: /*================================================================
154: 向有子地址器件发送多字节数据函数
155: 函数原型: bit I_send_str(uchar sla,uchar suba,uchar *s,uchar no);
156: Function: 从启动总线到发送地址,数据,结束总线的全过程,从器件地址sla。如果
157: 返回1表示操作成功,否则操作有误。
158: =================================================================*/
159: void I_send_str(uchar sla,uchar suba,uchar *s,uchar no)
160: {
161: uchar i;
162: start_i2c();
163: send_byte(sla);
164: if (ack==0) i2c_error();
165: send_byte(suba);
166: if (ack==0) i2c_error();
167: for (i=0;i<no;i++)
168: {
169: send_byte(*s);
170: if (ack==0) i2c_error();
171: s++;
172: }
173: stop_i2c();
174: // return(1);
175: }
176:
177: /*================================================================
178: 向有子地址器件发送两字节数据函数
179: 函数原型: bit I_send_word(uchar sla,uchar suba,uchar datal,uchar datah);
180: Function: 从启动总线到发送地址,数据,结束总线的全过程,从器件地址sla。如果
181: 返回1表示操作成功,否则操作有误。
182: =================================================================*/
183: void I_send_word(uchar sla,uchar suba,uchar datal,uchar datah)
184: {
185: uchar i;
186: start_i2c();
187: send_byte(sla);
188: if (ack==0) i2c_error();
189: send_byte(suba);
190: if (ack==0) i2c_error();
191: send_byte(datal);
192: if (ack==0) i2c_error();
193: send_byte(datah);
194: if (ack==0) i2c_error();
195: stop_i2c();
196: // return(1);
197: }
198: /*****************************************************************
199: 延时函数
200: 函数原型: void delay_250ms();
201: FUNCTION: 延明250ms
202: *****************************************************************/
203: void delay_250ms()
204: {
205: unsigned int d=24999;
206: while (--d);
207: }
208:
209: /*****************************************************************
210: 总线错误函数
211: 函数原型: void i2c_error();
212: Function: 通过RD7闪动8次表示总线操作失败一次报警。
213: *****************************************************************/
214: void i2c_error ()
215: {
216: uchar i;
217: for (i=0;i<8;i++)
218: {
219: RB7=0;
220: delay_250ms();
221: RB7=1;
222: delay_250ms();
223: }
224:
225: }
226: /**********END**************/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -