Library for NXP (Philips) PCF8591 I2C 4 Channel, 8bit Analog to Digital converter and a 1 Channel, 8bit Digital to Analog converter.
Dependents: 812_hello PCF8591_test_LAAS
PCF8591.cpp
00001 /* PCF8591 - I2C 8 bit 4 channel A/D and 8 bit 1 channel D/A converter 00002 * Copyright (c) 2013 Wim Huiskamp 00003 * 00004 * Released under the MIT License: http://mbed.org/license/mit 00005 * 00006 * version 0.2 Initial Release 00007 */ 00008 #include "mbed.h" 00009 #include "PCF8591.h" 00010 00011 00012 /** Create a PCF8591 AD and DA object using a specified I2C bus and slaveaddress 00013 * 00014 * @param I2C &i2c the I2C port to connect to 00015 * @param char deviceAddress the address of the PCF8591 00016 */ 00017 PCF8591::PCF8591(I2C *i2c, uint8_t deviceAddress) : _i2c(i2c) { 00018 00019 _slaveAddress = deviceAddress; 00020 _init(); 00021 } 00022 00023 00024 #if(0) 00025 //These methods are disabled since they interfere with normal expected behaviour for mbed type Analog I/O 00026 // 00027 00028 /** Set ADC mode 00029 * 00030 * @param adc_mode ADC Channel mode, valid Range (PCF8591_4S, PCF8591_3D, PCF8591_2S_1D, PCF8591_2D) 00031 */ 00032 void PCF8591::setADCMode(uint8_t mode){ 00033 uint8_t data[6]; 00034 00035 _mode = _mode & ~PCF8591_2D; // Clear ADC mode bits 00036 00037 switch (mode) { 00038 case PCF8591_4S: 00039 _mode = _mode | PCF8591_4S; 00040 break; 00041 case PCF8591_3D: 00042 _mode = _mode | PCF8591_3D; 00043 break; 00044 case PCF8591_2S_1D: 00045 _mode = _mode | PCF8591_2S_1D; 00046 break; 00047 case PCF8591_2D: 00048 _mode = _mode | PCF8591_2D; 00049 break; 00050 default: 00051 _mode = _mode | PCF8591_4S; 00052 break; 00053 } 00054 00055 data[0] = _mode; // Control Reg 00056 00057 // write data to the device 00058 _i2c->write(_slaveAddress, (char*) data, 1); 00059 00060 }; 00061 00062 /** Set DAC mode 00063 * 00064 * @param dac_mode DAC Channel mode, valid Range (false=disable, true=enable) 00065 */ 00066 void PCF8591::setDACMode(bool mode) { 00067 uint8_t data[6]; 00068 00069 if (mode) 00070 _mode = _mode | PCF8591_AOUT; // Enable DAC output 00071 else 00072 _mode = _mode & ~PCF8591_AOUT; // Disable DAC output 00073 00074 data[0] = _mode; // Control Reg 00075 00076 // write data to the device 00077 _i2c->write(_slaveAddress, (char*) data, 1); 00078 00079 }; 00080 #endif 00081 00082 00083 /** Write Analog Output 00084 * 00085 * @param analogOut output value (0..255) 00086 */ 00087 void PCF8591::write(uint8_t analogOut) { 00088 uint8_t data[6]; 00089 00090 data[0] = _mode; // Control Reg 00091 data[1] = analogOut; // DAC Channel 00092 00093 // write data to the device 00094 _i2c->write(_slaveAddress, (char*) data, 2); 00095 }; 00096 00097 /** Read Analog Channel 00098 * 00099 * @param Channel ADC channel, valid range PCF8591_ADC0, PCF8591_ADC1, PCF8591_ADC2 or PCF8591_ADC3 00100 * @return value uint8_t AD converted value (0..255, representing 0V..Vcc) 00101 */ 00102 #if(0) 00103 // I2C block operations test 00104 // Causes problems with Ticker and printf on LPC812. No issues found on LPC1768 00105 uint8_t PCF8591::read(uint8_t channel) { 00106 // uint8_t data[6]; 00107 uint8_t data[6] = {123,123,123,123,123,123}; //test to check failed read 00108 00109 _mode = _mode & ~PCF8591_CHMSK; // Clear ADC Channel bits 00110 _mode = _mode | (channel & PCF8591_CHMSK); // Set ADC Channel bits 00111 00112 data[0] = _mode; // Init Control Reg 00113 00114 // write data to the device to select the ADC channel 00115 _i2c->write(_slaveAddress, (char*) data, 1); 00116 00117 // read selected ADC channel 00118 // note that first byte is a 'dummy' and should be ignored 00119 _i2c->read(_slaveAddress, (char*) data, 2); 00120 return data[1]; 00121 }; 00122 00123 #else 00124 // I2C single byte operations test 00125 // No issues found on LPC812 00126 uint8_t PCF8591::read(uint8_t channel) { 00127 uint8_t data[6]; 00128 // uint8_t data[6] = {123,123,123,123,123,123}; //test to check failed read 00129 00130 _mode = _mode & ~PCF8591_CHMSK; // Clear ADC Channel bits 00131 _mode = _mode | (channel & PCF8591_CHMSK); // Set ADC Channel bits 00132 00133 data[0] = _mode; // Init Control Reg 00134 00135 // write data to the device to select the ADC channel 00136 _i2c->start(); 00137 _i2c->write(_slaveAddress); // Slave write address 00138 _i2c->write(data[0]); 00139 _i2c->stop(); 00140 00141 // read selected ADC channel 00142 // note that first byte is a 'dummy' and should be ignored 00143 _i2c->start(); 00144 _i2c->write(_slaveAddress | 0x01); // Slave read address 00145 data[0]=_i2c->read(1); //ack 00146 data[1]=_i2c->read(0); //nack 00147 _i2c->stop(); 00148 00149 return data[1]; 00150 }; 00151 00152 #endif 00153 00154 00155 /** Initialise AD and DA driver 00156 * 00157 */ 00158 void PCF8591::_init() { 00159 uint8_t data[6]; 00160 00161 _mode = PCF8591_CTRL_DEF; // Init mode 00162 00163 data[0] = _mode; // Init Control Reg 00164 data[1] = 0x00; // Init DAC Channel to 0 00165 00166 // write data to the device 00167 _i2c->write(_slaveAddress, (char*) data, 2); 00168 }; 00169 00170 00171 00172 00173 00174 /** Create a PCF8591 AnalogOut object connected to the specified I2C bus and deviceAddress 00175 * 00176 */ 00177 PCF8591_AnalogOut::PCF8591_AnalogOut(I2C *i2c, uint8_t deviceAddress) : _i2c(i2c) { 00178 00179 _slaveAddress = deviceAddress; 00180 _init(); 00181 } 00182 00183 00184 /** Write Analog Output 00185 * 00186 * @param analogOut value (0 .. 1.0) 00187 */ 00188 void PCF8591_AnalogOut::write(float analogOut) { 00189 uint8_t data[6]; 00190 00191 data[0] = _mode; // Control Reg 00192 00193 // DAC Channel 00194 if (analogOut < 0.0) data[1] = 0; 00195 else if (analogOut >= 1.0) data[1] = 255; 00196 else data[1] = uint8_t (analogOut * 255.0); 00197 00198 // write data to the device 00199 _i2c->write(_slaveAddress, (char*) data, 2); 00200 }; 00201 00202 /** Operator = Analog Output 00203 * 00204 * @param analogOut value (0.0f .. 1.0f) 00205 */ 00206 PCF8591_AnalogOut& PCF8591_AnalogOut::operator= (float value){ 00207 write(value); 00208 return *this; 00209 } 00210 00211 00212 /** Initialise DAC driver 00213 * 00214 */ 00215 void PCF8591_AnalogOut::_init() { 00216 uint8_t data[6]; 00217 00218 _mode = PCF8591_CTRL_DEF; // Init mode 00219 00220 data[0] = _mode; // Init Control Reg 00221 data[1] = 0x00; // Init DAC Channel to 0 00222 00223 // write data to the device 00224 _i2c->write(_slaveAddress, (char*) data, 2); 00225 }; 00226 00227 00228 00229 /** Create a PCF8591 AnalogIn object connected to the specified I2C bus and deviceAddress 00230 * 00231 */ 00232 PCF8591_AnalogIn::PCF8591_AnalogIn(I2C *i2c, uint8_t channel, uint8_t deviceAddress) : _i2c(i2c) { 00233 00234 _slaveAddress = deviceAddress; 00235 _channel = channel; 00236 _init(); 00237 } 00238 00239 00240 /** Read Analog input 00241 * 00242 * @return analogIn value (0 .. 1.0) 00243 */ 00244 float PCF8591_AnalogIn::read() { 00245 uint8_t data[6]; 00246 00247 data[0] = _mode; // Init Control Reg 00248 00249 // write data to the device to select the ADC channel 00250 _i2c->start(); 00251 _i2c->write(_slaveAddress); // Slave write address 00252 _i2c->write(data[0]); 00253 _i2c->stop(); 00254 00255 // read selected ADC channel 00256 // note that first byte is a 'dummy' and should be ignored 00257 _i2c->start(); 00258 _i2c->write(_slaveAddress | 0x01); // Slave read address 00259 data[0]=_i2c->read(1); //ack 00260 data[1]=_i2c->read(0); //nack 00261 _i2c->stop(); 00262 00263 00264 // ADC Channel 00265 return ((float) data[1] / 255.0); 00266 00267 }; 00268 00269 00270 /** Operator float Analog Input 00271 * 00272 * @return analogIn value (0 .. 1.0) 00273 */ 00274 PCF8591_AnalogIn::operator float(){ 00275 return (read()); 00276 } 00277 00278 00279 /** Initialise ADC driver 00280 * 00281 */ 00282 void PCF8591_AnalogIn::_init() { 00283 uint8_t data[6]; 00284 00285 _mode = PCF8591_CTRL_DEF; // Init mode 00286 _mode = _mode & ~PCF8591_CHMSK; // Clear ADC Channel bits 00287 _mode = _mode | (_channel & PCF8591_CHMSK); // Set ADC Channel bits 00288 00289 data[0] = _mode; // Init Control Reg 00290 00291 // write data to the device 00292 _i2c->write(_slaveAddress, (char*) data, 1); 00293 };
Generated on Tue Jul 12 2022 17:26:42 by 1.7.2