cancel
Showing results for 
Search instead for 
Did you mean: 

SPI interface between STM32F103C8 and ADE7758

mt.hust
Associate II

Hi everyone,

I have got some problems with programming SPI between ADE7758 (slave) and STM32F103C8 (master). I use build - in SPI (hardware SPI), and directly connect 4 pin (MOSI, MISO, NSS, CLK) to ADE7758 which is a 5V device without any conversion module, to test my project. Initially I just execute a read operation to ADE7758 to get default value of OPMODE register. Unfortunately what i got back on MISO line is some arbitrary value for example like 0xFF, instead of its default value which is 0x04.

I have also tried to observe the waveform and recognize that the voltage level of MISO is strange, just about 0.2V - 0.3V. The MOSI and CLK pulse are nice.

Do I have to connect STM32 chip to ADE7758 via a voltage level conversion to ensure proper operation?

I have been stuck in this issue many days and still can not find the solution.

Hope someone help me.

Thanks in advance.

9 REPLIES 9
Joerg Wagner
Senior III

You do not need voltage level conversion.

The logic input level of ADE7758 for Input High Voltage, VINH is 2.4V. (page 5)

Does NSS have the right level when you send data?

When you just have one SPI slave only, the CS of ADE7758 can be tied to GND.

Do you send 0x13 0x00 to read the OPMODE register?

mt.hust
Associate II

Thank you for replying to me.

I configure SPI1 with following parameters:

GPIO_InitTypeDef GPIO_InitStructure;
/*-------------Config MOSI and SCK pin-----------------*/
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5 | GPIO_Pin_7;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; 
GPIO_Init(GPIOA, &GPIO_InitStructure);
/*-------------Config MISO pin-----------------*/
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
 GPIO_Init(GPIOA, &GPIO_InitStructure);
/*-------------Config NSS pin-----------------*/
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_Init(GPIOA, &GPIO_InitStructure);
 
SPI_InitTypeDef SPI_InitStructure;
 
SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex;
SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b;  
SPI_InitStructure.SPI_CPOL = SPI_CPOL_Low;
SPI_InitStructure.SPI_CPHA = SPI_CPHA_1Edge;
SPI_InitStructure.SPI_NSS = SPI_NSS_Hard; 		
SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_256;   SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB;
SPI_InitStructure.SPI_CRCPolynomial = 7;
SPI_Init(SPI1, &SPI_InitStructure);
 
SPI_SSOutputCmd(SPI1, ENABLE);     
GPIO_SetBits(GPIOA, GPIO_Pin_4);
SPI_Cmd(SPI1, ENABLE); 

Before that, I set PLK2 clock to get ABP2 running at 18MHz and configure RCC peripherals

RCC_PCLK2Config(RCC_HCLK_Div4);
RCC_APB2PeriphClockCmd( RCC_APB2Periph_GPIOA | RCC_APB2Periph_SPI1 | RCC_APB2Periph_AFIO, ENABLE);

So the SPI clock will be 18MHz / 256.

I use hardware NSS management to simply select/de-select the slave by GPIO_ResetBits(GPIOA, GPIO_Pin_4) / GPIO_SetBits(GPIOA, GPIO_Pin_4)

To read the OPMODE register, I send 0x13 byte first and then send 0xFF for dummy byte to receive rx data.

Is anything not proper throughout my configuration and execution?

Joerg Wagner
Senior III

Basically 0x00 is used to read data. 0x00 is not interpreted by the slave.

Who wrote this line

GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;

for MISO configuration? Try this:

GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP

I follow these configuration by the SPI Full duplex example in STM32F10x_StdPeriph_Examples folder getting from Standard Library Driver.

Even though setting MISO pin as Alternate Function Push Pull, It does not work.

Joerg Wagner
Senior III

Is CS low?

mt.hust
Associate II

Yes, this is my Read 8 bit function

uint8_t ADE7758_Read_8bit(uint8_t add_reg)
{ 	
	GPIO_ResetBits(GPIOA, GPIO_Pin_4);
	SPI_I2S_SendData(SPI1,(uint16_t)data);
	while (RESET == SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_TXE));
       SPI_I2S_SendData(SPI1,0xFF);
	while (RESET == SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_TXE));
	while (RESET == SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_RXNE));
        GPIO_SetBits(GPIOA, GPIO_Pin_4);
	return (uint8_t)SPI_I2S_ReceiveData(SPI1);
}

mt.hust
Associate II

Hi Joerg Wagner,

If you have done successfully this connection without voltage level conversion, please let me know.

Thank you.

Joerg Wagner
Senior III

Basically you have to choose from two options: CS is driven by hardware via NSS

or you obtain the NSS declaration (software) and drive CS manually via GPIO functions.

Like I said, many Analog devices have a 5V supply and their logic H input level is >2.4V.

Most of the input pins of the STM device are 5V tolerant, so there is nothing to do.

I have many Analog devices in use because Analog is my favourite brand.

mt.hust
Associate II

Your answer this time really puzzles me. It is totally different from what I know. I see 2 confusions here:

1. About 2 options of NSS pin management, what I have got from the user manual RM0008, page 707

"If the NSS pin is required in input mode, in hardware mode, connect the NSS pin to a high-level signal during the complete byte transmit sequence. In NSS software mode, set the SSM and SSI bits in the SPI_CR1 register. If the NSS pin is required in output mode, the SSOE bit only should be set."

So following these, I just set SSOE bit, let the default SSM = 0 (hardware management) and use it as usual GPIO output, with GPIO functions. But you set it in software mode and use GPIO functions?

2. Following your recommendation, I have also tried SPI software (bit banged) too, to check whether I got problem with NSS pin low or not when communication while operating in SPI built - in hardware, but unluckily got the same result.

So if I misunderstand something about SPI configuration in STM32, please help me check the code (config function, send function) again and let me khow.

Thank you for spending time.