📄 i2c_f76.lst
字号:
1:
2: /*******************************************************************
3: 一、程序说明:
4: 1, 24LC02器件地址是1010000R/W.
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
21: //#define SDA_DIRE TRISC4
22: //#define SCL_E RC3
23: //#define SDA_E RC4
24:
25: #define SCL_E RA0
26: #define SDA_E RA1
27: #define SCL_DIRE TRISA0
28: #define SDA_DIRE 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 delay_250ms();
36: void i2c_error ();
37: int ReadByte_EE(uchar addr);
38:
39: uchar code[]={0X21,0x64,0x03,0x07,0x0f,0x1f,0x3f,0x7f,0xff};
40: uchar no,ack,c,data;
41:
42: /*
43: void main(void)
44: {
45: uchar i;
46:
47: ADCON1=0X06;
48: TRISA=0x0F;
49: PORTA=0;
50:
51: TRISC=0Xff; //C口设为输入 RC3为SCL_DIRE线,RC4为SDA_DIRE线。
52: PORTC=0X0;
53: TRISB=0X00; //D口为输出,显示IC24LC02中读出的内容
54: PORTB=0X00; //初始显示全亮
55:
56: I_send_str(0xa0,0x00,code,6); //页写入code数组到24LC02,器件地址为0Xa0,子地址为0X00,共9个数。
57:
58: delay_250ms();
59:
60:
61: ///////////开始读出到D口进行显示,根据Random read时序图。
62: while (1)
63: {
64: for (i=0x00;i<0x09;i++)
65: {
66: start_i2c();
67: send_byte(0xA0); //发送器件地址,即DEVICE ADDRESS。
68: if (ack==0) i2c_error(); //如果24LC02无应答。则进入I2C ERROR错误指示。
69: send_byte(i); //发送字地址,即WORD ADDRESS。D口显示数组。
70: if (ack==0) i2c_error();
71: start_i2c(); //重新启动总线。
72: send_byte(0xA1); //发送读命令和器件地址DEVICE ADDRESS。
73: if (ack==0) i2c_error();
74: data=receive_byte();
75: stop_i2c();
76: PORTB=data;
77: delay_250ms();
78: PORTB=ReadByte_EE(2);
79: delay_250ms();
80: }
81: }
82: }
83: */
84:
85: /*******************************************************************
86: 起动总线函数
87: 函数原型: void start_i2c();
88: Function: start on the I2C bus
89: *******************************************************************/
90: void start_i2c()
91: {
92: SDA_DIRE=1; //发送启始条件的数据信号
93: nop();
94: SCL_DIRE=1;
95: nop();nop();nop();nop();nop(); //24LC02要求建立时间大于4,7S
96: SDA_DIRE=0; //发送起始信号
97: nop();nop();nop();nop();nop();
98: SCL_DIRE=0; //钳住I2C总线,准备发送数据或接收数据
99: nop();nop();
100: }
101:
102:
103: /*******************************************************************
104: 停止总线函数
105: 函数原型: void stop_i2c();
106: Function: stop the I2C bus
107: *******************************************************************/
108: void stop_i2c()
109: {
110:
111: SDA_DIRE=0; //发送结束条件的数据信号
112: nop();
113: SCL_DIRE=1;
114: nop();nop();nop();nop();nop();
115: SDA_DIRE=1;
116: nop();nop();nop();nop();
117: }
118:
119: /*=================================================================
120: 字节数据传送函数
121: 函数原型: void send_byte(uchar c);
122: Function: 将数据C发送出去,可以是地址,也可以是数据,发完后等待回应,并对此状态
123: 位进行操作(不应答或非应答都使ack=0 ),发送数据正常,ack=1;ack=0
124: 表示被控器无应答或损坏。
125: ==================================================================*/
126: void send_byte(uchar c)
127: {
128: uchar bit_count;
129: for (bit_count=0;bit_count<8;bit_count++)
130: {
131: if ((c<<bit_count)&0x80) {SDA_DIRE=1;}
132: else {SDA_DIRE=0;}
133: nop();
134: SCL_DIRE=1;
135: nop();nop();nop();nop();nop();
136: SCL_DIRE=0;
137: }
138: nop();nop();
139: SDA_DIRE=1;
140: nop();nop();
141: SCL_DIRE=1;
142: nop();nop();nop();
143: if (SDA_E==1) ack=0;
144: else ack=1; //用ASK=1为有应答信号
145: SCL_DIRE=0;
146: nop();nop();
147: }
148:
149: /*==================================================================
150: 字节数据接收函数
151: 函数原型:uchar receive_byte();
152: FUNCTION: 用来接收从器件传来的数据,并判断总线错误(不发应答信号),
153: 发完后请用应答函数。
154: ===================================================================*/
155: uchar receive_byte()
156: {
157: uchar retc,bit_count;
158: retc=0;
159: SDA_DIRE=1;
160: for (bit_count=0;bit_count<8;bit_count++)
161: {
162: nop();
163: SCL_DIRE=0;
164: nop();nop();nop();nop();nop();
165: SCL_DIRE=1;
166: nop();nop();
167: retc=retc<<1;
168: if (SDA_E==1) retc=retc+1;
169: nop();nop();
170: }
171: SCL_DIRE=0;
172: nop();nop();
173: return (retc);
174: }
175:
176: ////////********************************//////////////
177: int ReadByte_EE(uchar addr){
178: uchar data1;
179: start_i2c();
180: send_byte(0xA0); //发送器件地址,即DEVICE ADDRESS。
181: if (ack==0) i2c_error(); //如果24LC02无应答。则进入I2C ERROR错误指示。
182: send_byte(addr); //发送字地址,即WORD ADDRESS。D口显示数组。
183: if (ack==0) i2c_error();
184: start_i2c(); //重新启动总线。
185: send_byte(0xA1); //发送读命令和器件地址DEVICE ADDRESS。
186: if (ack==0) i2c_error();
187: data1=receive_byte();
188: stop_i2c();
189: return(data1);
190: }
191:
192: /*================================================================
193:
194:
195: /*================================================================
196: 向有子地址器件发送多字节数据函数
197: 函数原型: bit I_send_str(uchar sla,uchar suba,uchar *s,uchar no);
198: Function: 从启动总线到发送地址,数据,结束总线的全过程,从器件地址sla。如果
199: 返回1表示操作成功,否则操作有误。
200: =================================================================*/
201: void I_send_str(uchar sla,uchar suba,uchar *s,uchar no)
202: {
203: uchar i;
204: start_i2c();
205: send_byte(sla);
206: if (ack==0) i2c_error();
207: send_byte(suba);
208: if (ack==0) i2c_error();
209: for (i=0;i<no;i++)
210: {
211: send_byte(*s);
212: if (ack==0) i2c_error();
213: s++;
214: }
215: stop_i2c();
216: // return(1);
217: }
218:
219: /*****************************************************************
220: 延时函数
221: 函数原型: void delay_250ms();
222: FUNCTION: 延明250ms
223: *****************************************************************/
224: void delay_250ms()
225: {
226: unsigned int d=24999;
227: while (--d);
228: }
229:
230: /*****************************************************************
231: 总线错误函数
232: 函数原型: void i2c_error();
233: Function: 通过RD7闪动8次表示总线操作失败一次报警。
234: *****************************************************************/
235: void i2c_error ()
236: {
237: uchar i;
238: for (i=0;i<8;i++)
239: {
240: RB7=0;
241: delay_250ms();
242: RB7=1;
243: delay_250ms();
244: }
245:
246: }
247: /**********END**************/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -