Dear friends,
I am now working with STM32F103-LDC1101.
After configuring the LDC1101, I found that the output waveform is not similar to the datasheet.
Here is the output waveform from INA and INB.
Please help me to configure the LDC1101 to generate the output waveform similar to EVM.
Thank you
Here is my setting for SPI:
void SPI_CLOCK_Configuration(void) { GPIO_InitTypeDef GPIO_InitStructure; RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE); GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(GPIOA, &GPIO_InitStructure); // GPIO_PinAFConfig(GPIOA, GPIO_PinSource8, GPIO_AF_0); RCC_MCOConfig(RCC_MCO_HSE); //Sets MCO to 8 MHz // RCC_MCOConfig(RCC_MCO_SYSCLK); //Sets MCO to 8 MHz // __disable_interrupt(); // __enable_interrupt(); } void SPI_Configuration(void) { uint32_t Div = 2; uint32_t DivVal = 0; GPIO_InitTypeDef GPIO_InitStructure; SPI_InitTypeDef SPI_InitStructure; RCC_ClocksTypeDef Clk; // Init LCD IOs and SPI1 RCC_APB2PeriphResetCmd( RCC_APB2Periph_GPIOA | RCC_APB2Periph_GPIOB | RCC_APB2Periph_SPI1 | RCC_APB2Periph_AFIO, DISABLE); RCC_APB2PeriphClockCmd( RCC_APB2Periph_GPIOA | RCC_APB2Periph_GPIOB | RCC_APB2Periph_SPI1 | RCC_APB2Periph_AFIO, ENABLE); // Deinitializes the SPI1 SPI_I2S_DeInit(SPI1); /* Configure SPI_MASTER pins: SCK and MOSI ---------------------------------*/ GPIO_InitStructure.GPIO_Pin = SPI_MASTER_PIN_SCK | SPI_MASTER_PIN_MOSI; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; GPIO_Init(SPI_MASTER_GPIO, &GPIO_InitStructure); /* Configure SCK and MOSI pins as Alternate Function Push Pull */ GPIO_InitStructure.GPIO_Pin = SPI_MASTER_PIN_MISO; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; GPIO_Init(SPI_MASTER_GPIO, &GPIO_InitStructure); /* Configure SPI pins : NSS4 */ GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; GPIO_Init(GPIOA, &GPIO_InitStructure); /* SPI1 no remap (NSS/PA4, SCK/PA5, MISO/PA6, MOSI/PA7) */ GPIO_PinRemapConfig(GPIO_Remap_SPI1, DISABLE); /* SPI_MASTER configuration ---------------------------*/ SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex; SPI_InitStructure.SPI_Mode = SPI_Mode_Master; SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b; SPI_InitStructure.SPI_CPOL = SPI_CPOL_High; SPI_InitStructure.SPI_CPHA = SPI_CPHA_2Edge; SPI_InitStructure.SPI_NSS = SPI_NSS_Soft; SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_64; SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB; SPI_InitStructure.SPI_CRCPolynomial = 7; SPI_Init(SPI_MASTER, &SPI_InitStructure); /* Enable SPI_MASTER TXE and RXNE interrupt */ // SPI_I2S_ITConfig(SPI_MASTER, SPI_I2S_IT_TXE, ENABLE); // SPI_I2S_ITConfig(SPI_MASTER, SPI_I2S_IT_RXNE, ENABLE); // Clock Freq. Identification Mode < 4MHz RCC_GetClocksFreq(&Clk); while ((MAX_SPI_FREQ * Div) <= Clk.PCLK1_Frequency) { Div <<= 1; if (++DivVal == 7) { break; } } SPI1->CR1 = (SPI1->CR1 & ~(0x7 << 3)) | ((DivVal&0x7) << 3); // Enable SPI1 SPI_Cmd(SPI1, ENABLE); } void SPI_write(uint8_t addr, uint8_t data) { addr = addr & 0x7F; // The MSB is a 0-write register, which is a 1-read register LDC_CS_LOW; delay_a(1); while (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_TXE) == RESET); SPI_I2S_SendData(SPI1, addr); // send 8Bit address while(!SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_TXE)); SPI_I2S_SendData(SPI1, data); // send 8Bit 8bit data while (SPI1->SR & SPI_I2S_FLAG_BSY); LDC_CS_HIGH; delay_a(2); } uint16_t SPI_read(int8_t addr) { static uint8_t data=0; addr = addr | 0x80; // The MSB is 1-read register delay_a(5); LDC_CS_LOW; delay_a(2); // address bits while (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_TXE) == RESET); SPI_I2S_SendData(SPI1, addr);// send Address while(!SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_RXNE)); SPI_I2S_ReceiveData(SPI1); // data bits while(!SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_TXE)); SPI_I2S_SendData(SPI1, 0x00); while(!SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_RXNE)); data = SPI_I2S_ReceiveData(SPI1); while( SPI1->SR & SPI_I2S_FLAG_BSY ); delay_a(2); LDC_CS_HIGH; delay_a(5); return data; }
#include "stm32f10x.h" #include "LDC1101.h" #include "LDC1101_CMD.h" /* Global variable----------------------------------------------------*/ uint32_t LHR_DATA; uint16_t RP_DATA; uint16_t _responsetime; // Response Time uint8_t _divider; // divider uint16_t _LHRoffset; // LHR_OFFSET float _RPmin; // RP_MIN float _RPmax; // RP_MAX float _fsensor; // f_sensor: the calculated frequency of the sensor float f_sensor_min = 5E+5; float _fCLKIN = 8E+6; // f_CLKIN: frequency of external clock: 16MHz float _cap = 42E-9; // capacitor: 120 pF uint16_t _Rcount = 0x1F29; // The reference count - 1kSPS 0x1F29 /*---------------------------------------- Function: LDC write register Function parameters: addr: register address dat: data ----------------------------------------*/ void writeSPI(uint8_t dat , uint8_t addr) { // uint16_t tmp=0; // uint32_t i = 0; addr = addr & 0x7F; // The MSB is a 0-write register. // tmp = ((uint16_t)addr << 8) | dat; LDC_CS_LOW; delay_a(1); // address bits while (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_TXE) == RESET); SPI_I2S_SendData(SPI1, addr); // data bits while (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_TXE) == RESET); SPI_I2S_SendData(SPI1, dat); while( SPI1->SR & SPI_I2S_FLAG_BSY ); LDC_CS_HIGH; delay_a(2); } /*---------------------------------------- Function: LDC read register Function parameters: addr: register address ----------------------------------------*/ uint8_t readSPI(int8_t addr) { static uint8_t data=0; // uint16_t tmp = 0; addr = addr | 0x80; // The MSB is 1-read register // tmp = ((uint16_t)addr << 8); delay_a(5); LDC_CS_LOW; delay_a(2); // address bits while(!SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_TXE)); SPI_I2S_SendData(SPI1, addr); while(!SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_RXNE)); SPI_I2S_ReceiveData(SPI1); // data bits while(!SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_TXE)); SPI_I2S_SendData(SPI1,0x00); while(!SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_RXNE)); data=SPI_I2S_ReceiveData(SPI1); while(SPI1->SR & SPI_I2S_FLAG_BSY); delay_a(2); LDC_CS_HIGH; delay_a(5); return data; }
Here is my setting for LDC1101:
void func_mode(LDC_MODE mode) { // Sleep mode writeSPI(mode,0x0B); // delay(0.8); } void setRPmode( void ) { writeSPI( 0x02, 0x05 ); // ALT_CONFIG: 0000 0010 --> RP modus + Shutdown enabled writeSPI( 0x00, 0x0C ); // D_CONFIG: Enables LHR modus, disables RP } void setLHRmode(void){ writeSPI(0x01,0x05); writeSPI(0x01,0x0C); } void setResponseTime(LDC_RESPONSE responsetime) { static uint16_t resps[] = {0, 0, 192, 384, 768, 1536, 3072, 6144}; _responsetime = resps[responsetime]; // uint8_t DIG_CONF; // DIG_CONF = readSPI(0x04); // writeSPI(( DIG_CONF & 0xF8) + responsetime, 0x04); writeSPI(responsetime, 0x04); } void setReferenceCount(uint16_t rcount) { _Rcount = rcount; uint8_t LHR_RCOUNT_LSB = (rcount & 0x00ff); uint8_t LHR_RCOUNT_MSB = ((rcount & 0xff00) >> 8); writeSPI(LHR_RCOUNT_LSB, 0x30); //LSB writeSPI(LHR_RCOUNT_MSB, 0x31); //MSB } void set_fsensor_min(void) { // uint8_t DIG_CONF; // DIG_CONF = readSPI(0x04); // uint8_t MIN_FREQ = 16.0f - (8.0f / f_sensor_min); // writeSPI(((MIN_FREQ << 4) + (DIG_CONF & 0x00)), 0x04 ); writeSPI(0x00,0x04); } void setRPsettings(bool RP_MAX_DIS, RPMAX rpmax, RPMIN rpmin) { static float rps[] = {96, 48, 24, 12, 6, 3, 1.5, 0.75}; _RPmin = rps[rpmin]; _RPmax = rps[rpmax]; writeSPI((RP_MAX_DIS << 7) | (rpmax << 4) | rpmin, 0x01); } void setDivider(DIVIDER div) { static uint8_t divs[] = {1, 2, 4, 8}; _divider = divs[div]; writeSPI(div, 0x34); } void setLHRoffset( uint16_t offset ) { _LHRoffset = offset; uint16_t LHR_OFFSET = offset; writeSPI((uint8_t) (LHR_OFFSET & 0x00ff), 0x32 ); // LSB writeSPI((uint8_t) ((LHR_OFFSET & 0xff00) >> 8), 0x33 ); // MSB } void sleep(void) { /* stop toggling the CLKIN pin input and drive the CLKIN pin Low */ func_mode( LDC_MODE_STANDBY ); } void wakeup(void) { /* start toggling the clock input on the CLKIN pin */ init(); // delay(0.5); } void init_LDC1101(void) { /********* SETTINGS ***************** ** C_sensor = 120 pF ** L_sensor = 5 uH ** Rp_min = 1500 Ohm ** ** RCount = 65535 (max) ** Samplerate = 1 kHz ** t_conv = 1 ms ** ** f_sensor_min = 6.4 MHz (d = inf) ** f_sensor_max = 10 MHz (d = 0) ** divider = 1 ************************************/ // Set LDC1101 in configuration modus func_mode( LDC_MODE_STANDBY ); // STANDBY = 0x01 naar 0x0B // - initialise LHR mode & enable SHUTDOWN mode setLHRmode(); // LHR mode // setRPmode(); // RP+L modek // - set ResponseTime to 192 // setResponseTime( LDC_RESPONSE_192 ); // - set LHR_Rcount to highest resolution(LHR) setReferenceCount( _Rcount ); // - set calibrated value for f_sensor_min (d = inf, no target) // set_fsensor_min(); // minimum 500kHz // - disable RP_MAX // - set RP_MIN to 1,5 kOhm (RPMIN_1) setRPsettings( 1, RPMAX_0, RPMIN_1 ); // LHR mode // setRPsettings( 0, RPMAX_96, RPMIN_1 ); // RP+L mode // - set Divider to 1 (for large range / ENOB / resolution) setDivider( DIVIDER_1 ); // - shift the signal down a bit setLHRoffset( 0x00 ); // Done configuring settings, set LDC1101 in measuring modus func_mode( LDC_MODE_ACTIVE ); } void LDC_Init() { // Set LDC1101 in configuration modus func_mode( LDC_MODE_STANDBY ); // STANDBY = 0x01 naar 0x0B writeSPI(0x36, LDC1101_CMD_RP); writeSPI(0xDD, LDC1101_CMD_TC1); writeSPI(0xFD, LDC1101_CMD_TC2); writeSPI(0xD7, LDC1101_CMD_DIGCONFIG); writeSPI(0x00, LDC1101_CMD_ALTCONFIG); writeSPI(0x00, LDC1101_CMD_THRESHILSB); writeSPI(0x00, LDC1101_CMD_THRESHIMSB); writeSPI(0x00, LDC1101_CMD_THRESLOLSB); writeSPI(0x00, LDC1101_CMD_THRESLOMSB); writeSPI(0x00, LDC1101_CMD_INTB_CONFIG); writeSPI(0x00, LDC1101_CMD_D_CONFIG); writeSPI(0x00, LDC1101_CMD_LTHRESHLSB); writeSPI(0x00, LDC1101_CMD_LTHRESHMSB); writeSPI(0x00, LDC1101_CMD_LTHRESLLSB); writeSPI(0x00, LDC1101_CMD_LTHRESLMSB); writeSPI(0x68, LDC1101_CMD_STATUS); writeSPI(0x00, LDC1101_CMD_RP_DATA_LSB); writeSPI(0x00, LDC1101_CMD_RP_DATA_MSB); writeSPI(0x00, LDC1101_CMD_L_DATA_LSB); writeSPI(0x00, LDC1101_CMD_L_DATA_MSB); writeSPI(0x29, LDC1101_CMD_LHR_RCOUNT_LSB); //0xFF writeSPI(0x1F, LDC1101_CMD_LHR_RCOUNT_MSB); //0xFF writeSPI(0x00, LDC1101_CMD_LHR_OFFSET_LSB); writeSPI(0x00, LDC1101_CMD_LHR_OFFSET_MSB); writeSPI(0x00, LDC1101_CMD_LHR_CONFIG); writeSPI(0x00, LDC1101_CMD_LHR_DATA_LSB); writeSPI(0x00, LDC1101_CMD_LHR_DATA_MID); writeSPI(0x00, LDC1101_CMD_LHR_DATA_MSB); // Done configuring settings, set LDC1101 in measuring modus func_mode( LDC_MODE_ACTIVE ); } float get_fsensor_min() { uint8_t DIG_CONF; DIG_CONF = readSPI(0x04); return (float) 8.0f/(16.0f - (float) ((DIG_CONF& 0xf0) >> 4)); } bool is_New_LHR_data(void) { return(!(get_LHR_status() & 0x01)); } bool is_Oscillation_Error(void) { return(get_status() & 0x80); } uint8_t get_status(void) { uint8_t status; status = readSPI(0x20); return status; } uint8_t get_LHR_status(void) { static uint8_t LHR_status; LHR_status = readSPI(0x3B); // ERR_ZC: (LHR_status & 0x10) >> 4 // // ERR_OR: (LHR_status & 0x08) >> 3 // // ERR_UR: (LHR_status & 0x04) >> 2 // 1 = LHR_DATA < 0 because LHR_OFFSET > LHR_DATA // ERR_OF: (LHR_status & 0x02) >> 1 // // LHR_DRDY: (LHR_status & 0x01) // 1 = Data ready return LHR_status; } //float get_Q(void) //{ // return _RPmin * sqrt(_cap/_inductance*1000000); //} float get_fsensor( uint32_t Ldata ) { static float _Ldata; _Ldata =(float)Ldata; // LHR mode if( Ldata == 0 ) { _Ldata = get_LHR_Data(); } _fsensor = _fCLKIN * (float)_divider * (_Ldata + (float)_LHRoffset*256)/16777216; // (p.26) // RP+L mode // if( Ldata == 0 ) { Ldata = get_L_Data(); } // _fsensor = (_fCLKIN * 6144) / (3 * Ldata); // (p.31) return _fsensor; } /* GETTING DATA FROM SENSOR-------------------------------------------------- */ uint16_t get_RP_Data(void) { RP_DATA=0; LDC_CS_LOW; // address bits while(!SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_TXE)); SPI_SendData8(SPI1, 0x80 | 0x21); while(!SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_RXNE)); SPI_ReceiveData8(SPI1); // data bits while(!SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_TXE)); SPI_SendData8(SPI1, 0x00); while(!SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_RXNE)); RP_DATA += ((uint16_t)SPI_ReceiveData8(SPI1)); // data bits while(!SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_TXE)); SPI_SendData8(SPI1, 0x80 | 0x22); while(!SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_RXNE)); RP_DATA += ((uint16_t)SPI_ReceiveData8(SPI1))<<8 ; // writeSPI(ADG); while( SPI1->SR & SPI_I2S_FLAG_BSY ); LDC_CS_HIGH; return RP_DATA; } float get_RP( uint16_t RPdata ) { static float _rp; // if( RPdata == 0 ){ // RPdata = get_RP_Data(); // } _rp=_RPmin * (1.0f - ((float) RPdata / (65535.0f-1.0f))); //return (_RPmax * _RPmin) / ( _RPmax * (1.0f - ((float) RPdata / 65535.0f)) + _RPmin * ((float) RPdata / 65535.0f)); return _rp; } uint32_t get_LHR_Data(void) { LHR_DATA=0; LDC_CS_LOW; // address bits while(!SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_TXE)); SPI_I2S_SendData(SPI1, 0x80 | 0x38); while(!SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_RXNE)); SPI_I2S_ReceiveData(SPI1); // data bits while(!SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_TXE)); SPI_I2S_SendData(SPI1, 0x00); while(!SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_RXNE)); LHR_DATA += ((uint32_t)SPI_I2S_ReceiveData(SPI1)); // data bits while(!SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_TXE)); SPI_I2S_SendData(SPI1, 0x80 | 0x39); while(!SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_RXNE)); LHR_DATA += ((uint32_t)SPI_I2S_ReceiveData(SPI1))<<8 ; // data bits while(!SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_TXE)); SPI_I2S_SendData(SPI1, 0x80 | 0x3A); while(!SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_RXNE)); LHR_DATA += ((uint32_t)SPI_I2S_ReceiveData(SPI1))<<16 ; // writeSPI(ADG); while( SPI1->SR & SPI_I2S_FLAG_BSY ); LDC_CS_HIGH; return LHR_DATA; } float get_Inductance( uint32_t Ldata ) { static float _inductance; // the calculated inductance _fsensor = get_fsensor( Ldata ); _inductance = 1/(_cap * 4*PI*PI*_fsensor*_fsensor); // (p.34) return _inductance; } // Delay ms void delay_a(uint32_t nCount) { uint32_t index = 0; for(index = (nCount*1); index != 0; index--) ; }