Hardware Introduction:
The hardware mainly includes the SPI interface of MSP430 and the instructions for using the AD7708 chip.
The SPI interface of msp430 supports both host mode and slave mode, and the polarity and phase are always adjustable. When communicating with the AD conversion chip, the polarity needs to be consistent.
AD7718 has 28 external pins. They are mainly divided into two parts according to their nature: analog and digital. The analog part pins are divided into three categories: analog input, reference voltage input and analog power supply. The analog input pins can be configured as 8-channel or 10-channel pseudo differential inputs, and they all refer to the AINCOM terminal.
The digital pins are divided into four categories: SPI interface, data ready, general I/O port and digital power supply. The 4 standard signal lines of the SPI interface are chip select signal CS, serial clock input SCLK, serial data input DIN and serial data output DOUT. When AD7718 is connected to the SPI bus, it is a slave device. A low-level signal is input from the CS pin to enable AD7718. Data ready RDY is a low-level effective output pin. When there is valid data in the selected channel data register, a low-level signal is output; after the data is read out, a high level is output. The general I/O port of AD7718 is 2 one-bit ports P1 and P2. They can be configured as input or output. The microcontroller reads and writes the relevant registers in the AD7718 chip through the SPI port to operate P1 and P2. They expand the I/O interface capabilities of the microcontroller.
The analog power supply and digital power supply of AD7718 are powered separately, and both can be powered by +3V or +5V. But they must be consistent, either +3V or +5V.
The AD7708 and AD7718 are controlled and configured via a set of on-chip registers. The first of these registers is the Communications Register, which is used to control all operations of the converter. All communications with these parts must be preceded by a write to the Communications Register to specify the next operation to be performed. After power-up or reset, the device defaults to waiting for a write to the Communications Register. The STATUS Register contains information about the operating condition of the converter. The STATUS Register is a read-only register. The Mode Register is used to configure the conversion mode, calibration, chop enable/disable, reference voltage selection, channel configuration, and pseudo differential AINCOM analog input operation when buffered or unbuffered. The Mode Register is a read/write register. The ADC Control Register is a read/write register that is used to select the active channel and encode the input range and bipolar/unipolar operation. The I/O Control Register is a read/write register that is used to configure the operation of the 2 I/O ports. The Filter Register is a read/write register that is used to encode the data update rate of the converter. The ADC Data Register is a read-only register that contains the result of a data conversion on the selected channel. The ADC Offset Register is a read/write register that contains the offset calibration data. There are five offset registers, one for each fully differential input channel. The channels share the offset registers when configured in pseudo differential input mode. The ADC gain register is a read/write register that contains gain calibration data. There are five ADC gain registers, one for each fully differential input channel. The channels share the gain registers when configured in pseudo differential input mode. The ADC contains factory applied test registers and the user should not change the operating conditions of these registers. The ID register is a read-only register used for silicon identification purposes.
The hardware connection method I use is: P3.0 of 430 is connected to the CS terminal of AD7708, and P3.1-P3.2 are connected to the SPI port of the corresponding AD chip; the RDY signal is not connected; therefore, the program uses the query method and waits for the RDY bit of the STATUS register to indicate that the conversion is complete.
For detailed information about AD7708, please refer to its datasheet; in addition, I have translated the register section and program flow section of the datasheet. If necessary, you can download it in the attachment at the bottom of this blog .
Program implementation:
First, the read and write register functions of AD7708. Each operation of AD7708 starts with writing the communication register. Through this step, it indicates what operation will be performed next. For the meaning of each bit of the register, refer to the AD7708-Register in the attachment (end of the blog)
Write register:
void AD7708WriteRegister(char addr,long dat)
{
SpiWriteData(addr); //Write the communication register to notify the next operation: write the addr register
if(IsLong[addr]) //If it is a 16-bit register, then 7718 is a 24-bit register. If you want to transplant it, you need to change the statement in if
{
SpiWriteData(that>>8);
}
SpiWriteData(0xFF&dat); //Write low bit data
}
For the register address, you can refer to the datasheet or the part I translated; the IsLong character array indicates whether the corresponding register is 8-bit or 16-bit:
char IsLong[16] = {0,0,0,0,1,1,1,0,0,0,0,0,1,1,0,0};
Read registers:
long AD7708ReadRegister(char addr)
{
char h = 0, l = 0; //high and low byte data
SpiWriteData(0x40|addr); //Write the communication register and notify the next operation: read the addr register
if(IsLong[addr])
{
h = SpiWriteData(0xFF);
}
l = SpiWriteData(0xFF);
return ((unsigned int)h<<8)|l;
}
SPI explanation: 430 is the SPI host module. When sending, another clock edge is sampled and received at the same time. Therefore, the data can be read out in half a cycle after each sending is completed; so the SpiWriteData function returns the characters received at the same time when writing. Sending 0xFF is to provide a clock for reading the upcoming data. For details, please refer to the precautions section of the previous article (just updated).
Read the result data:
long AD7708ReadResultData()
{
while((AD7708ReadRegister(0x00)&0x80)==0); //Wait for the conversion to complete
return AD7708ReadRegister(0x04);
}
Wait for the RDY bit of STATUS to become high (AD data conversion update is completed) and read the contents of the data register.
Calibration: The calibration process has a detailed flowchart in the datasheet; you can refer to the AD7708-register in the datasheet or the attachment. This subfunction only completes the calibration of one channel. The channel address has parameter input for easy calling:
void AD7708Cal(char channel)
{
adccon = (adccon&0x0f)|(channel<<4);
mode = (mode&0xf8)|0x04; //Internal 0 calibration
AD7708WriteRegister(0x02,adccon); //ADC control register, channel
AD7708WriteRegister(0x01,mode); //Mode register
while((AD7708ReadRegister(0x01)&0x07)!=0x01); //Wait for calibration to complete
mode = (mode&0xf8)|0x05; //Internal full-scale calibration
AD7708WriteRegister(0x01,mode); //Mode register
while((AD7708ReadRegister(0x01)&0x07)!=0x01); //Wait for calibration to complete
}
adccon is the content of the ADCCON register recorded by the program last time, and mode is the content of the MODE register recorded by the program last time. Because serial port reading takes time, in order to obtain faster speed, the program records these two variables for use. For channel addresses, refer to the datasheet or the document in the attachment.
initialization:
void AD7708Init(char chop)
{
P3DIR|=BIT0;
P3OUT&=~BIT0; //CS selected
//Host mode, 115200, 8 data bits, three-wire mode, clock mode 1 (see spi.c for details)
SpiMasterInit(115200,8,3,1); //The clock is not accurate to 115200 (see spi.c for details)
_EINT(); //Open interrupt, spi read and write programs need interrupt
char filter;
adccon = 0x0f;
if(chop == 0)
{
filter = 0x03; //The filter register is set to the minimum value, which can be changed
mode = 0x91; //Chop disabled, 10 channels, unbuffered, idle mode
}
else
{
filter = 0x0D; //The filter register is set to the minimum value, which can be changed
mode = 0x11; //Chop enabled, 10 channels, unbuffered, idle mode
}
AD7708WriteRegister(0x07,0x00); //IO register, not used ==
AD7708WriteRegister(0x03,filter); //Filter register
AD7708WriteRegister(0x02,0x0F); //ADC control register, channel 0, unipolar
AD7708WriteRegister(0x01,mode); //Mode register
if(chop == 0)
for(int i = 0; i<5;i++)
{
//Calibration, because there are only 5 offset registers, more will overwrite the previous ones, so only calibrate 5
AD7708Cal(5);
}
_DINT();
}
The initialization system introduces the parameter of chopping, and the others use fixed parameters: 10-channel pseudo differential, unipolar, unbuffered, the filter register is set to the fastest speed when chopping or chopping is disabled, which can be modified if necessary. After SPI initialization, the interrupt is turned on to write content to AD to initialize AD. After initialization, the interrupt is turned off to make the library consistent after initialization. However, after calling this function, the interrupt needs to be turned on to use other functions of AD sampling normally.
Sampling start: This program only supports the start of word sampling. If you need a continuous mode, you can implement it yourself (relatively easy to implement: just change the value of the register):
void AD7708Start(char channel)
{
adccon = (adccon&0x0f)|(channel<<4);
mode = (mode&0xf8)|0x02;
AD7708WriteRegister(0x02,adccon);
AD7708WriteRegister(0x01,mode);
}
According to the previous settings of the control register and mode register, change the values needed now and write them into the corresponding registers.
At this point, the program is partially completed. If you need to expand it, you can add it yourself.