Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
mcp342x.cpp
00001 #include "mcp342x.h" 00002 00003 #define LEN_ONE_BYTE 1 00004 00005 MCP342x::MCP342x(I2C *i2c, uint8_t device_address) 00006 { 00007 _i2c = i2c; 00008 00009 // The address byte is the device code (4 bits, hardcoded in 00010 // factory) and the device address (3 bits). These are shifted one 00011 // bit to the left because mbed uses 8-bit addresses. 00012 _address = (_device_code << 4) | (device_address << 1); 00013 00014 // Initialise to default settings: channel 1, gain 1x, 12 bits. 00015 // It is necessary to do this to ensure that the variables 00016 // _resolution and _pga are properly set. 00017 _configuration = 0x10; 00018 set_channel(CHANNEL_1); 00019 set_resolution(RESOLUTION_12); 00020 set_pga(PGA_1); 00021 } 00022 00023 void MCP342x::set_channel(mcp342x_channel_t channel) 00024 { 00025 _configuration &= REG_CHANNEL_Clear; 00026 _configuration |= channel << REG_CHANNEL_Pos; 00027 _write_configuration(); 00028 } 00029 00030 void MCP342x::set_conversion_mode(mcp342x_conversion_mode_t mode) 00031 { 00032 _configuration &= REG_MODE_Clear; 00033 _configuration |= mode << REG_MODE_Pos; 00034 _write_configuration(); 00035 } 00036 00037 void MCP342x::set_resolution(mcp342x_resolution_t resolution) 00038 { 00039 _resolution = resolution; 00040 00041 // _lsb and _max_code are variables required for converting the ADC 00042 // data into volts; see Section 4.9 of the MCP342x datasheet. Their 00043 // value depends on the resolution chosen, so it is useful to 00044 // calculate these values here, whenever the resolution setting is 00045 // changed. 00046 // 00047 // _lsb is the magnitude (in volts) of the last significant byte, 00048 // and it is calculated as 2 * 2.048 / (2^N), where N is the 00049 // resolution (datasheet Eq. 4-3). 00050 // 00051 // _max_code is the maximum output code, and it is equal to 00052 // 2^(N-1) - 1 (datasheet Table 4-3). 00053 switch(_resolution){ 00054 case RESOLUTION_12: 00055 _lsb = 2 * 2.048 / 4096; 00056 _max_code = 2047; 00057 break; 00058 case RESOLUTION_14: 00059 _lsb = 2 * 2.048 / 16384; 00060 _max_code = 8191; 00061 break; 00062 case RESOLUTION_16: 00063 _lsb = 2 * 2.048 / 65536; 00064 _max_code = 32767; 00065 break; 00066 case RESOLUTION_18: 00067 _lsb = 2 * 2.048 / 262144; 00068 _max_code = 131071; 00069 break; 00070 } 00071 00072 _configuration &= REG_RESOLUTION_Clear; 00073 _configuration |= _resolution << REG_RESOLUTION_Pos; 00074 _write_configuration(); 00075 } 00076 00077 void MCP342x::set_pga(mcp342x_pga_t pga) 00078 { 00079 // The gain value (1, 2, 4 or 8) is required for converting digital 00080 // output codes to voltage. For this purpose the actual PGA value is 00081 // kept in the variable _pga, instead of keeping the *position* in 00082 // the register of PGA, which is what the variable type 00083 // mcp342x_pga_t represents. 00084 switch (pga) { 00085 case PGA_1: 00086 _pga = 1; 00087 break; 00088 case PGA_2: 00089 _pga = 2; 00090 break; 00091 case PGA_4: 00092 _pga = 4; 00093 break; 00094 case PGA_8: 00095 _pga = 8; 00096 break; 00097 } 00098 00099 _configuration &= REG_PGA_Clear; 00100 _configuration |= pga << REG_PGA_Pos; 00101 _write_configuration(); 00102 } 00103 00104 void MCP342x::_write_configuration() 00105 { 00106 _i2c_command[0] = _configuration; 00107 _i2c->write(_address, _i2c_command, LEN_ONE_BYTE); 00108 } 00109 00110 uint32_t MCP342x::read() 00111 { 00112 uint32_t adc_value = 0; 00113 _i2c->read(_address, _i2c_command, COMMAND_N_BYTES); 00114 00115 switch (_resolution) { 00116 case RESOLUTION_12: 00117 adc_value = (_i2c_command[0] << 8) | _i2c_command[1]; 00118 adc_value &= 0xfff; 00119 break; 00120 00121 case RESOLUTION_14: 00122 adc_value = (_i2c_command[0] << 8) | _i2c_command[1]; 00123 adc_value &= 0x3fff; 00124 break; 00125 00126 case RESOLUTION_16: 00127 adc_value = (_i2c_command[0] << 8) | _i2c_command[1]; 00128 adc_value &= 0xffff; 00129 break; 00130 00131 case RESOLUTION_18: 00132 adc_value = (_i2c_command[0] << 16) | 00133 (_i2c_command[1] << 8) | _i2c_command[2]; 00134 adc_value &= 0x3ffff; 00135 break; 00136 } 00137 return adc_value; 00138 } 00139 00140 float MCP342x::read_volts(){ 00141 float volts = 0.0; 00142 uint32_t adc_value = read(); 00143 00144 // The digital output of the MCP342x is in two's complement format; 00145 // see datasheet Section 4.9. This 'if... else' construction 00146 // determines whether the digital code is negative or positive; if 00147 // it is the former, its two's complement is calculated. 00148 if (adc_value > _max_code) { 00149 // if the output code is negative... 00150 volts = (~adc_value & _max_code) + 1; 00151 volts *= -1; 00152 } else { 00153 // if the output code is positive... 00154 volts = (float)adc_value; 00155 } 00156 00157 // The actual voltage is proportional to the resolution and PGA 00158 // settings. This equation corresponds to Equation 4-4 in the 00159 // datasheet. The variables _lsb and _pga are calculated whenever 00160 // the user changes the resolution or PGA parameters. 00161 return volts * _lsb / _pga; 00162 }
Generated on Sat Aug 6 2022 09:37:44 by
1.7.2