The AD8556 is a zero-drift, sensor signal amplifier with digitally programmable gain and output offset.

Dependents:   AD8556_HelloWolrd

Committer:
fblanc
Date:
Wed Sep 11 13:30:19 2013 +0000
Revision:
0:05eaa16f3327
OK

Who changed what in which revision?

UserRevisionLine numberNew contents of line
fblanc 0:05eaa16f3327 1 /**
fblanc 0:05eaa16f3327 2 * @brief AD8556: Digitally Programmable Sensor Signal Amplifier with EMI Filters
fblanc 0:05eaa16f3327 3 * http://www.analog.com/en/specialty-amplifiers/instrumentation-amplifiers/ad8556/products/product.html
fblanc 0:05eaa16f3327 4 * @date 05/09/2013
fblanc 0:05eaa16f3327 5 * @author F.BLANC LAAS-CNRS
fblanc 0:05eaa16f3327 6 * http://homepages.laas.fr/fblanc/
fblanc 0:05eaa16f3327 7 */
fblanc 0:05eaa16f3327 8
fblanc 0:05eaa16f3327 9 #include "AD8556.h"
fblanc 0:05eaa16f3327 10
fblanc 0:05eaa16f3327 11 /**
fblanc 0:05eaa16f3327 12 * @brief Constructor.
fblanc 0:05eaa16f3327 13 *
fblanc 0:05eaa16f3327 14 * @param dig
fblanc 0:05eaa16f3327 15
fblanc 0:05eaa16f3327 16 */
fblanc 0:05eaa16f3327 17 AD8556::AD8556(PinName dig) : _dig(dig)
fblanc 0:05eaa16f3327 18 {
fblanc 0:05eaa16f3327 19 }
fblanc 0:05eaa16f3327 20
fblanc 0:05eaa16f3327 21 /**
fblanc 0:05eaa16f3327 22 * @brief Destructor.
fblanc 0:05eaa16f3327 23 */
fblanc 0:05eaa16f3327 24 AD8556::~AD8556()
fblanc 0:05eaa16f3327 25 {
fblanc 0:05eaa16f3327 26 }
fblanc 0:05eaa16f3327 27
fblanc 0:05eaa16f3327 28
fblanc 0:05eaa16f3327 29
fblanc 0:05eaa16f3327 30
fblanc 0:05eaa16f3327 31
fblanc 0:05eaa16f3327 32 /**
fblanc 0:05eaa16f3327 33 * @brief init
fblanc 0:05eaa16f3327 34 * @param mode
fblanc 0:05eaa16f3327 35 * @param First_Stage_Gain_Code
fblanc 0:05eaa16f3327 36 * @param Second_Stage_Gain_Code
fblanc 0:05eaa16f3327 37 * @param Vdac_Code
fblanc 0:05eaa16f3327 38 */
fblanc 0:05eaa16f3327 39 int AD8556::init(unsigned char mode,unsigned char First_Stage_Gain_Code, unsigned char Second_Stage_Gain_Code,unsigned char Vdac_Code)
fblanc 0:05eaa16f3327 40 {
fblanc 0:05eaa16f3327 41 trame(ADC_Second_Stage_Gain_Code,mode,Second_Stage_Gain_Code);
fblanc 0:05eaa16f3327 42 trame(ADC_First_Stage_Gain_Code,mode,First_Stage_Gain_Code);
fblanc 0:05eaa16f3327 43 trame(ADC_Output_Offset_Code,mode,Vdac_Code);
fblanc 0:05eaa16f3327 44 return 0;
fblanc 0:05eaa16f3327 45 }
fblanc 0:05eaa16f3327 46
fblanc 0:05eaa16f3327 47 /**
fblanc 0:05eaa16f3327 48 * @brief trame
fblanc 0:05eaa16f3327 49 * @param parameter
fblanc 0:05eaa16f3327 50 * @param mode
fblanc 0:05eaa16f3327 51 * @param data
fblanc 0:05eaa16f3327 52 */
fblanc 0:05eaa16f3327 53 void AD8556::trame(unsigned char parameter,unsigned char mode,unsigned char data)
fblanc 0:05eaa16f3327 54 {
fblanc 0:05eaa16f3327 55 //12-Bit Start of Packet 1000 0000 0001
fblanc 0:05eaa16f3327 56 write_bit(1);
fblanc 0:05eaa16f3327 57 for(unsigned char i=0; i<10; ++i)
fblanc 0:05eaa16f3327 58 write_bit(0);
fblanc 0:05eaa16f3327 59 write_bit(1);
fblanc 0:05eaa16f3327 60 //2-Bit Function
fblanc 0:05eaa16f3327 61 switch (mode) {
fblanc 0:05eaa16f3327 62 case ADC_MODE_SENSE_CURENT :
fblanc 0:05eaa16f3327 63 write_bit(0);
fblanc 0:05eaa16f3327 64 write_bit(0);
fblanc 0:05eaa16f3327 65 break;
fblanc 0:05eaa16f3327 66 case ADC_MODE_SIMULATION :
fblanc 0:05eaa16f3327 67 write_bit(0);
fblanc 0:05eaa16f3327 68 write_bit(1);
fblanc 0:05eaa16f3327 69 break;
fblanc 0:05eaa16f3327 70 case ADC_MODE_FUSE :
fblanc 0:05eaa16f3327 71 write_bit(1);
fblanc 0:05eaa16f3327 72 write_bit(0);
fblanc 0:05eaa16f3327 73 break;
fblanc 0:05eaa16f3327 74 case ADC_MODE_READ :
fblanc 0:05eaa16f3327 75 write_bit(1);
fblanc 0:05eaa16f3327 76 write_bit(1);
fblanc 0:05eaa16f3327 77 break;
fblanc 0:05eaa16f3327 78 }
fblanc 0:05eaa16f3327 79 //2-Bit Parameter
fblanc 0:05eaa16f3327 80 switch (parameter) {
fblanc 0:05eaa16f3327 81 case ADC_Second_Stage_Gain_Code :
fblanc 0:05eaa16f3327 82 write_bit(0);
fblanc 0:05eaa16f3327 83 write_bit(0);
fblanc 0:05eaa16f3327 84 break;
fblanc 0:05eaa16f3327 85 case ADC_First_Stage_Gain_Code :
fblanc 0:05eaa16f3327 86 write_bit(0);
fblanc 0:05eaa16f3327 87 write_bit(1);
fblanc 0:05eaa16f3327 88 break;
fblanc 0:05eaa16f3327 89 case ADC_Output_Offset_Code :
fblanc 0:05eaa16f3327 90 write_bit(1);
fblanc 0:05eaa16f3327 91 write_bit(0);
fblanc 0:05eaa16f3327 92 break;
fblanc 0:05eaa16f3327 93 case ADC_Other_Functions :
fblanc 0:05eaa16f3327 94 write_bit(1);
fblanc 0:05eaa16f3327 95 write_bit(1);
fblanc 0:05eaa16f3327 96 break;
fblanc 0:05eaa16f3327 97 }
fblanc 0:05eaa16f3327 98
fblanc 0:05eaa16f3327 99
fblanc 0:05eaa16f3327 100 //2-Bit Dummy 10
fblanc 0:05eaa16f3327 101 write_bit(1);
fblanc 0:05eaa16f3327 102 write_bit(0);
fblanc 0:05eaa16f3327 103 //8-Bit Value
fblanc 0:05eaa16f3327 104 for(char i=0; i<8; ++i) {
fblanc 0:05eaa16f3327 105 write_bit( data & (0x80>>i) );
fblanc 0:05eaa16f3327 106 }
fblanc 0:05eaa16f3327 107 //12-Bit End of Packet 1000 0000 0001
fblanc 0:05eaa16f3327 108 write_bit(0);
fblanc 0:05eaa16f3327 109 for(unsigned char i=0; i<10; ++i)
fblanc 0:05eaa16f3327 110 write_bit(1);
fblanc 0:05eaa16f3327 111 write_bit(0);
fblanc 0:05eaa16f3327 112 }
fblanc 0:05eaa16f3327 113
fblanc 0:05eaa16f3327 114 /**
fblanc 0:05eaa16f3327 115 * @brief write_bit
fblanc 0:05eaa16f3327 116 *
fblanc 0:05eaa16f3327 117 * @param bit 1 or 0
fblanc 0:05eaa16f3327 118 */
fblanc 0:05eaa16f3327 119 void AD8556::write_bit(unsigned char bit)
fblanc 0:05eaa16f3327 120 {
fblanc 0:05eaa16f3327 121 _dig = 0;
fblanc 0:05eaa16f3327 122 _dig.output();
fblanc 0:05eaa16f3327 123 wait_us(10);
fblanc 0:05eaa16f3327 124 _dig = 1;
fblanc 0:05eaa16f3327 125 if ( bit )
fblanc 0:05eaa16f3327 126 wait_us(50); //1
fblanc 0:05eaa16f3327 127 wait_us(5);
fblanc 0:05eaa16f3327 128 _dig = 0;
fblanc 0:05eaa16f3327 129 wait_us(10);
fblanc 0:05eaa16f3327 130 }
fblanc 0:05eaa16f3327 131
fblanc 0:05eaa16f3327 132 /**
fblanc 0:05eaa16f3327 133 * @brief vdac
fblanc 0:05eaa16f3327 134 * @param vdac consigne (volt)
fblanc 0:05eaa16f3327 135 * @param vdd positive voltage supply (volt)
fblanc 0:05eaa16f3327 136 * @param vss nagative voltage supply (volt)
fblanc 0:05eaa16f3327 137 * @param mode
fblanc 0:05eaa16f3327 138 */
fblanc 0:05eaa16f3327 139 void AD8556::prog_vdac(float vdac,float vdd,float vss, unsigned char mode)
fblanc 0:05eaa16f3327 140 {
fblanc 0:05eaa16f3327 141 unsigned char Vdac_Code;
fblanc 0:05eaa16f3327 142 Vdac_Code=256*(vdac-vss)/(vdd-vss)-0.5;
fblanc 0:05eaa16f3327 143 trame(ADC_Output_Offset_Code,mode,Vdac_Code);
fblanc 0:05eaa16f3327 144
fblanc 0:05eaa16f3327 145 }
fblanc 0:05eaa16f3327 146 /**
fblanc 0:05eaa16f3327 147 * @brief prog_gain
fblanc 0:05eaa16f3327 148 * @param gain 70 to 1280
fblanc 0:05eaa16f3327 149 * @param mode
fblanc 0:05eaa16f3327 150 */
fblanc 0:05eaa16f3327 151 void AD8556::prog_gain(float gain, unsigned char mode)
fblanc 0:05eaa16f3327 152 {
fblanc 0:05eaa16f3327 153 float Second_Stage_Gain;
fblanc 0:05eaa16f3327 154 int First_Stage_Gain_Code;
fblanc 0:05eaa16f3327 155 if (gain<70) {
fblanc 0:05eaa16f3327 156 trame(ADC_Second_Stage_Gain_Code,mode,0);
fblanc 0:05eaa16f3327 157 trame(ADC_First_Stage_Gain_Code,mode,0);
fblanc 0:05eaa16f3327 158 } else if (gain<100) {
fblanc 0:05eaa16f3327 159 trame(ADC_Second_Stage_Gain_Code,mode,0);
fblanc 0:05eaa16f3327 160 Second_Stage_Gain=17.5;
fblanc 0:05eaa16f3327 161 First_Stage_Gain_Code=(int)(((gain/Second_Stage_Gain)-4.0)*66.7);
fblanc 0:05eaa16f3327 162 trame(ADC_First_Stage_Gain_Code, mode, First_Stage_Gain_Code);
fblanc 0:05eaa16f3327 163 } else if (gain<140) {
fblanc 0:05eaa16f3327 164 trame(ADC_Second_Stage_Gain_Code,mode,1);
fblanc 0:05eaa16f3327 165 int First_Stage_Gain_Code=(int)gain/25;
fblanc 0:05eaa16f3327 166 Second_Stage_Gain=25;
fblanc 0:05eaa16f3327 167 First_Stage_Gain_Code=(int)(((gain/Second_Stage_Gain)-4.0)*66.7);
fblanc 0:05eaa16f3327 168 trame(ADC_First_Stage_Gain_Code, mode, First_Stage_Gain_Code);
fblanc 0:05eaa16f3327 169 } else if (gain<200) {
fblanc 0:05eaa16f3327 170 trame(ADC_Second_Stage_Gain_Code,mode,2);
fblanc 0:05eaa16f3327 171 Second_Stage_Gain=35;
fblanc 0:05eaa16f3327 172 First_Stage_Gain_Code=(int)(((gain/Second_Stage_Gain)-4.0)*66.7);
fblanc 0:05eaa16f3327 173 trame(ADC_First_Stage_Gain_Code, mode, First_Stage_Gain_Code);
fblanc 0:05eaa16f3327 174 } else if (gain<280) {
fblanc 0:05eaa16f3327 175 trame(ADC_Second_Stage_Gain_Code,mode,3);
fblanc 0:05eaa16f3327 176 Second_Stage_Gain=50;
fblanc 0:05eaa16f3327 177 First_Stage_Gain_Code=(int)(((gain/Second_Stage_Gain)-4.0)*66.7);
fblanc 0:05eaa16f3327 178 trame(ADC_First_Stage_Gain_Code, mode, First_Stage_Gain_Code);
fblanc 0:05eaa16f3327 179 } else if (gain<400) {
fblanc 0:05eaa16f3327 180 trame(ADC_Second_Stage_Gain_Code,mode,4);
fblanc 0:05eaa16f3327 181 Second_Stage_Gain=70;
fblanc 0:05eaa16f3327 182 First_Stage_Gain_Code=(int)(((gain/Second_Stage_Gain)-4.0)*66.7);
fblanc 0:05eaa16f3327 183 trame(ADC_First_Stage_Gain_Code, mode, First_Stage_Gain_Code);
fblanc 0:05eaa16f3327 184 } else if (gain<560) {
fblanc 0:05eaa16f3327 185 trame(ADC_Second_Stage_Gain_Code,mode,5);
fblanc 0:05eaa16f3327 186 Second_Stage_Gain=100;
fblanc 0:05eaa16f3327 187 First_Stage_Gain_Code=(int)(((gain/Second_Stage_Gain)-4.0)*66.7);
fblanc 0:05eaa16f3327 188 trame(ADC_First_Stage_Gain_Code, mode, First_Stage_Gain_Code);
fblanc 0:05eaa16f3327 189 } else if (gain<800) {
fblanc 0:05eaa16f3327 190 trame(ADC_Second_Stage_Gain_Code,mode,6);
fblanc 0:05eaa16f3327 191 Second_Stage_Gain=140;
fblanc 0:05eaa16f3327 192 First_Stage_Gain_Code=(int)(((gain/Second_Stage_Gain)-4.0)*66.7);
fblanc 0:05eaa16f3327 193 trame(ADC_First_Stage_Gain_Code, mode, First_Stage_Gain_Code);
fblanc 0:05eaa16f3327 194 } else if (gain<1280) {
fblanc 0:05eaa16f3327 195 trame(ADC_Second_Stage_Gain_Code,mode,7);
fblanc 0:05eaa16f3327 196 Second_Stage_Gain=200;
fblanc 0:05eaa16f3327 197 First_Stage_Gain_Code=(int)(((gain/Second_Stage_Gain)-4.0)*66.7);
fblanc 0:05eaa16f3327 198 trame(ADC_First_Stage_Gain_Code, mode, First_Stage_Gain_Code);
fblanc 0:05eaa16f3327 199 } else if (gain>=1280) {
fblanc 0:05eaa16f3327 200 trame(ADC_Second_Stage_Gain_Code,mode,7);
fblanc 0:05eaa16f3327 201 trame(ADC_First_Stage_Gain_Code, mode, 127);
fblanc 0:05eaa16f3327 202 }
fblanc 0:05eaa16f3327 203
fblanc 0:05eaa16f3327 204 }