?? ps2.lst
字號:
1: #include <pic.h>
2: #include "..\delay.h"
3: #include "i2c.h"
4:
5: /*
6: * I2C functions for HI-TECH PIC C - master mode only
7: */
8:
9: /*
10: * TIMING - see Philips document: THE I2C-BUS SPECIFICATION
11: */
12:
13:
14: /*
15: * Send stop condition
16: * - data low-high while clock high
17: */
18:
19: void
20: i2c_Stop(void)
21: {
22: /* don't assume SCL is high on entry */
23:
24: SDA_LOW(); /* ensure data is low first */
25: SCL_HIGH();
26:
27: DelayUs(I2C_TM_DATA_SU);
28: SCL_DIR = I2C_INPUT; /* float clock high */
29: DelayUs(I2C_TM_STOP_SU);
30: SDA_HIGH(); /* the low->high data transistion */
31: DelayUs(I2C_TM_BUS_FREE); /* bus free time before next start */
32: SDA_DIR = I2C_INPUT; /* float data high */
33:
34: return;
35: }
36:
37: /*
38: * Send (re)start condition
39: * - ensure data is high then issue a start condition
40: * - see also i2c_Start() macro
41: */
42:
43: void
44: i2c_Restart(void)
45: {
46: SCL_LOW(); /* ensure clock is low */
47: SDA_HIGH(); /* ensure data is high */
48:
49: DelayUs(I2C_TM_DATA_SU);
50:
51: SCL_DIR = I2C_INPUT; /* clock pulse high */
52: DelayUs(I2C_TM_SCL_HIGH);
53:
54: SDA_LOW(); /* the high->low transition */
55: DelayUs(I2C_TM_START_HD);
56: return;
57: }
58:
59: /*
60: * Send a byte to the slave
61: * - returns true on error
62: */
63: unsigned char
64: i2c_SendByte(unsigned char byte)
65: {
66: signed char i;
67:
68: for(i=7; i>=0; i--)
69: {
70: SCL_LOW(); /* drive clock low */
71:
72: /* data hold time = 0, send data now */
73: SDA_DIR = ((byte>>i)&0x01);
74: if ((byte>>i)&0x01) { /* bit to send */
75: SDA_HIGH();
76: }else {
77: SDA_LOW();
78: }
79: DelayUs(I2C_TM_DATA_SU);
80: SCL_DIR = I2C_INPUT; /* float clock high */
81:
82: if(i2c_WaitForSCL()) /* wait for clock release */
83: return TRUE; /* bus error */
84:
85: DelayUs(I2C_TM_SCL_HIGH); /* clock high time */
86: }
87:
88: return FALSE;
89: }
90:
91: /*
92: * send an address and data direction to the slave
93: * - 7-bit address (lsb ignored)
94: * - direction (FALSE = write )
95: */
96: unsigned char
97: i2c_SendAddress(unsigned char address, unsigned char rw)
98: {
99: return i2c_SendByte(address | (rw?1:0));
100: }
101:
102: /*
103: * Check for an acknowledge
104: * - returns ack or ~ack, or ERROR if a bus error
105: */
106: signed char
107: i2c_ReadAcknowledge(void)
108: {
109: unsigned char ack;
110:
111: SCL_LOW(); /* make clock is low */
112: SDA_DIR = I2C_INPUT; /* disable data line - listen for ack */
113: DelayUs(I2C_TM_SCL_TO_DATA); /* SCL low to data out valid */
114: SCL_DIR = I2C_INPUT; /* float clock high */
115: DelayUs(I2C_TM_DATA_SU);
116: ack = SDA; /* read the acknowledge */
117:
118: /* wait for slave to release clock line after processing byte */
119: if(i2c_WaitForSCL())
120: return I2C_ERROR;
121: return ack;
122: }
123:
124: /*
125: * Read a byte from the slave
126: * - returns the byte, or I2C_ERROR if a bus error
127: */
128: int
129: i2c_ReadByte(void)
130: {
131: unsigned char i;
132: unsigned char byte = 0;
133:
134: for(i=0; i<8; i++)
135: {
136: SCL_LOW(); /* drive clock low */
137: DelayUs(I2C_TM_SCL_LOW); /* min clock low period */
138: SDA_DIR = I2C_INPUT; /* release data line */
139:
140: SCL_DIR = I2C_INPUT; /* float clock high */
141: if(i2c_WaitForSCL())
142: return I2C_ERROR;
143: DelayUs(I2C_TM_SCL_HIGH);
144: byte = byte << 1; /* read the next bit */
145: byte |= SDA;
146: }
147: return (int)byte;
148: }
149:
150: /*
151: * Send an (~)acknowledge to the slave
152: * - status of I2C_LAST implies this is the last byte to be sent
153: */
154: void
155: i2c_SendAcknowledge(unsigned char status)
156: {
157: SCL_LOW();
158: if ( status & 0x01) {
159: SDA_LOW(); /* drive line low -> more to come */
160: }else {
161: SDA_HIGH();
162: }
163: DelayUs(I2C_TM_DATA_SU);
164: SCL_DIR = I2C_INPUT; /* float clock high */
165: DelayUs(I2C_TM_SCL_HIGH);
166: return;
167: }
168:
169: /*
170: * Send a byte to the slave and acknowledges the transfer
171: * - returns I2C_ERROR, ack or ~ack
172: */
173: signed char
174: i2c_PutByte(unsigned char data)
175: {
176: if(i2c_SendByte(data))
177: return I2C_ERROR;
178: return i2c_ReadAcknowledge(); /* returns ack, ~ack */
179: }
180:
181: /*
182: * Get a byte from the slave and acknowledges the transfer
183: * - returns true on I2C_ERROR or byte
184: */
185: int
186: i2c_GetByte(unsigned char more)
187: {
188: int byte;
189:
190: if((byte = i2c_ReadByte()) == I2C_ERROR)
191: return I2C_ERROR;
192:
193: i2c_SendAcknowledge(more);
194:
195: return byte;
196: }
197:
198: /*
199: * Send an array of bytes to the slave and acknowledges the transfer
200: * - returns number of bytes not successfully transmitted
201: */
202: int
203: i2c_PutString(const unsigned char *str, unsigned char length)
204: {
205: signed char error;
206:
207: while(length)
208: {
209: if((error = i2c_PutByte(*str)) == I2C_ERROR)
210: return -(int)length; /* bus error */
211: else
212: if(error)
213: return (int)length; /* non acknowledge */
214: str++;
215: length--;
216: }
217:
218: return FALSE; /* everything OK */
219: }
220:
221: /*
222: * Reads number bytes from the slave, stores them at str and acknowledges the transfer
223: * - returns number of bytes not successfully read in
224: */
225: unsigned char
226: i2c_GetString(unsigned char *str, unsigned char number)
227: {
228: int byte;
229:
230: while(number)
231: {
232: if((byte = i2c_GetByte(number-1)) == I2C_ERROR)
233: return number; /* bus error */
234: else
235: *str = (unsigned char)byte;
236: str++;
237: number--;
238: }
239:
240: return FALSE; /* everything OK */
241: }
242:
243: /*
244: * Opens communication with a device at address. mode
245: * indicates I2C_READ or I2C_WRITE.
246: * - returns TRUE if address is not acknowledged
247: */
248: unsigned char
249: i2c_Open(unsigned char address, unsigned char mode)
250: {
251: i2c_Start();
252: i2c_SendAddress(address, mode);
253: if(i2c_ReadAcknowledge())
254: return TRUE;
255:
256: return FALSE;
257: }
258:
259: /*
260: * wait for the clock line to be released by slow slaves
261: * - returns TRUE if SCL was not released after the
262: * time out period.
263: * - returns FALSE if and when SCL released
264: */
265: unsigned char
266: i2c_WaitForSCL(void)
267: {
268: /* SCL_DIR should be input here */
269: if(!SCL)
270: {
271: DelayUs(I2C_TM_SCL_TMO);
272: /* if the clock is still low -> bus error */
273: if(!SCL)
274: return TRUE;
275: }
276: return FALSE;
277: }
278:
279: void
280: i2c_Free()
281: {
282: unsigned char ucI;
283:
284: SDA_DIR=I2C_INPUT;
285: for(ucI=0;ucI!=9;ucI++)
286: {
287: SCL_HIGH();
288: DelayUs(5);
289: SCL_LOW();
290: DelayUs(5);
291: }
292: }
293:
294: unsigned char i2c_read(unsigned char ucAdr)
295: {
296: unsigned char ucDat;
297:
298: if (i2c_ReadFrom(ucAdr)==0)
299: {
300: ucDat=i2c_GetByte(I2C_MORE);
301: i2c_Stop();
302:
303: }
304:
305: return(ucDat);
306: }
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -