PIC18 LaurTec Library  3.2.0
Open Source C Library for PIC18 Microcontrollers based on C18 - XC8 Compilers
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Macros
PCF8574.c
Go to the documentation of this file.
1 /*******************************************************************************
2 
3 Author : Mauro Laurenti
4 Version : 1.1
5 Created on Date : 19/03/2011
6 Last update : 02/02/2013
7 
8 CopyRight 2006/2011 all rights are reserved
9 
10 
11 
12 CopyRight 2006-2013 all rights are reserved
13 
14 ********************************************************
15 SOFTWARE LICENSE AGREEMENT
16 ********************************************************
17 
18 The usage of the supplied software imply the acceptance of the following license.
19 
20 The software supplied herewith by Mauro Laurenti (the Author) is intended for
21 use solely and exclusively on Microchip PIC Microcontroller (registered mark).
22 The software is owned by the Author, and is protected under applicable
23 copyright laws. All rights are reserved.
24 Any use in violation of the foregoing restrictions may subject the
25 user to criminal sanctions under applicable laws, as well as to civil liability
26 for the breach of the terms and conditions of this license.
27 Commercial use is forbidden without a written acknowledgement with the Author.
28 Personal or educational use is allowed if the application containing the
29 following software doesn't aim to commercial use or monetary earning of any kind.
30 
31 THIS SOFTWARE IS PROVIDED IN AN "AS IS" CONDITION. NO WARRANTIES,
32 WHETHER EXPRESS, IMPLIED OR STATUTORY, INCLUDING, BUT NOT LIMITED
33 TO, IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
34 PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. THE AUTHOR SHALL NOT,
35 IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL OR
36 CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER.
37 
38 *******************************************************************************/
39 
40 #ifdef __XC8
41  #include <xc.h>
42  #ifndef _PIC18
43  #error The PCF8574 Library supports only PIC18 devices
44  #endif
45 #endif
46 
47 #include "PCF8574.h"
48 
49 
50 //************************************************************
51 // initialize_PCF8574 function implementation
52 //************************************************************
53 void initialize_PCF8574 (unsigned char crystal_frequency_MHz, unsigned int baud_rate_KHz){
54 
55  OpenI2C(MASTER, SLEW_ON);
56 
57  SSPADD = (((crystal_frequency_MHz *1000)/4)/baud_rate_KHz)-1;
58 }
59 
60 
61 //************************************************************
62 // PCF8574_write_data function implementation
63 //************************************************************
64 
65 signed char write_data_PCF8574(unsigned char control, unsigned char data ){
66 
67 
68 //*****************************
69 // Start Condition and control
70 // Byte are sent
71 //*****************************
72 
73  // Check if the module is idle
74  IdleI2C();
75  // Initiate START condition
76  StartI2C();
77 
78  // Wait until start condition is over
79  while (SSPCON2bits.SEN);
80 
81  // Check if Bus collision happened
82  if (PIR2bits.BCLIF) {
83  // Return with Bus Collision error
84  return (-1);
85  }
86 
87  // Write control byte - R/W bit should be 0
88  if (WriteI2C(control)){
89  // Return with write Collision error
90  return (-3);
91  }
92 
93 
94 //*****************************
95 // Data Byte is sent
96 //*****************************
97 
98  // Check if the module is idle
99  IdleI2C();
100 
101  // Check if ACK condition has been received
102  if (!SSPCON2bits.ACKSTAT){
103 
104  // Write data byte to the data port
105  if (WriteI2C(data)) {
106  // Return with write Collision error
107  return (-3);
108  }
109  } else {
110  // Return with Not Ack error condition
111  return (-2);
112  }
113 
114 //*****************************
115 // Stop command is sent
116 //*****************************
117 
118  // Check if the module is idle
119  IdleI2C();
120 
121  // Check if ACK condition has been received
122  if (!SSPCON2bits.ACKSTAT) {
123 
124  // Send STOP condition
125  StopI2C();
126 
127  // Wait until stop condition is over
128  while (SSPCON2bits.PEN);
129 
130  } else {
131  // Return with Not Ack error condition
132  return (-2);
133  }
134 
135  // Test for bus collision
136  if (PIR2bits.BCLIF){
137  // Return with Bus Collision error
138  return (-1);
139  }
140 
141  // Return with no error
142  return (1);
143 }
144 
145 
146 
147 //************************************************************
148 // PCF8574_read_data function implementation
149 //************************************************************
150 
151 signed char read_data_PCF8574(unsigned char control, unsigned char *data){
152 
153 
154 //*****************************
155 // Start Condition and control
156 // Byte are sent
157 //*****************************
158 
159  // Check if the module is idle
160  IdleI2C();
161  // Initiate START condition
162  StartI2C();
163 
164  // Wait until start condition is over
165  while (SSPCON2bits.SEN);
166 
167  // Check if Bus collision happened
168  if (PIR2bits.BCLIF) {
169  // Return with Bus Collision error
170  return (-1);
171  }
172 
173  // Write Control Byte
174  if (WriteI2C(control + 1)){
175  // Return with write collision error
176  return (-3);
177  }
178 
179 
180 //*****************************
181 // Data is Read
182 //*****************************
183 
184  // Check if the module is idle
185  IdleI2C();
186 
187  // Check if ACK condition has been received
188  if (!SSPCON2bits.ACKSTAT){
189 
190  // Enable master for 1 byte reception
191  SSPCON2bits.RCEN = 1;
192 
193  // Check that receive sequence is over
194  while (SSPCON2bits.RCEN);
195 
196  // Send not ACK condition
197  NotAckI2C();
198 
199  // Wait until ACK sequence is over
200  while (SSPCON2bits.ACKEN );
201 
202  // Send STOP condition
203  StopI2C();
204 
205  // Wait until stop condition is over
206  while (SSPCON2bits.PEN);
207 
208  // Check if Bus collision happened
209  if (PIR2bits.BCLIF) {
210  // return with Bus Collision error
211  return (-1);
212  }
213 
214  } else {
215  // Return with Not Ack error
216  return (-2);
217  }
218 
219  // Data is read from the buffer
220  *data = SSPBUF;
221 
222  // No error occurred
223  return (1);
224 
225 }
226 
227