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