Jump to content
43oh

Interfacing an EEPROM with STM32F207IG using SPI.


Recommended Posts

I am using Atollic.
This is the link to the datasheet of the memory - http://www.atmel.in/Images/Atmel-5165-SEEPROM-AT25512-Datasheet.pdf

I have some doubts - can you please resolve them?

1. When I check the clock on the Oscilloscope - I don't get a square wave (it's something like a square wave with it's upper part curved), why is that happening? Is it OK to not to have a perfectly square wave?

2. What's wrong with the code below, I am trying to read the status register of the EEPROM. received_val remains 0 even after completely executing the code (I am debugging step by step)

3. However, when I start the code - it starts with a default value of 224 (does that mean that it read something during the previous execution of the code, I am asking this because I am making it 0 every time in code so how come it automatically becomes 224?) If it's correct why doesn't it reflect during the debugging?

 

PS - I have been stuck with this for almost about two months and I can't seem to figure out - I have tried all possible things to test SPI but none of them seem to work. 

I'd really appreciate some help. 

 

#include <stddef.h>

#include "stm32f2xx.h"

 

 

 void init_SPI1(void){

 

 

  GPIO_InitTypeDef GPIO_InitStruct;

  SPI_InitTypeDef SPI_InitStruct;

 

 

  // enable clock for used IO pins

  RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE);

 

 

  /* configure pins used by SPI1

   * PA5 = SCK

   * PA6 = MISO

   * PA7 = MOSI

   * PB0 - CS

   * PB1 - HLD

   * PB2 - WP

   */

  GPIO_InitStruct.GPIO_Pin = GPIO_Pin_7 | GPIO_Pin_6 | GPIO_Pin_5;

  GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF;

  GPIO_InitStruct.GPIO_OType = GPIO_OType_PP;

  GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;

  GPIO_InitStruct.GPIO_PuPd = GPIO_PuPd_NOPULL;

  GPIO_Init(GPIOA, &GPIO_InitStruct);

 

 

  // connect SPI1 pins to SPI alternate function

  GPIO_PinAFConfig(GPIOA, GPIO_PinSource5, GPIO_AF_SPI1);

  GPIO_PinAFConfig(GPIOA, GPIO_PinSource6, GPIO_AF_SPI1);

  GPIO_PinAFConfig(GPIOA, GPIO_PinSource7, GPIO_AF_SPI1);

 

 

  // enable clock for used IO pins

  RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB, ENABLE);

 

 

  /* Configure the chip select pin

     in this case we will use PE7 */

  GPIO_InitStruct.GPIO_Pin =  GPIO_Pin_0 | GPIO_Pin_1 | GPIO_Pin_2;

  GPIO_InitStruct.GPIO_Mode = GPIO_Mode_OUT;

  GPIO_InitStruct.GPIO_OType = GPIO_OType_PP;

  GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;

  GPIO_InitStruct.GPIO_PuPd = GPIO_PuPd_UP;

  GPIO_Init(GPIOB, &GPIO_InitStruct);

 

 

  GPIOB->BSRRL |= GPIO_Pin_0; // set PB0 high

  GPIOB->BSRRL |= GPIO_Pin_0; // set PB1 high

  GPIOB->BSRRL |= GPIO_Pin_0; // set PB2 high

 

 

 

 

  // enable peripheral clock

  RCC_APB2PeriphClockCmd(RCC_APB2Periph_SPI1, ENABLE);

 

 

  /* configure SPI1 in Mode 0

   * CPOL = 0 --> clock is low when idle

   * CPHA = 0 --> data is sampled at the first edge

   */

  SPI_InitStruct.SPI_Direction = SPI_Direction_2Lines_FullDuplex; // set to full duplex mode, seperate MOSI and MISO lines

  SPI_InitStruct.SPI_Mode = SPI_Mode_Master;     // transmit in master mode, NSS pin has to be always high

  SPI_InitStruct.SPI_DataSize = SPI_DataSize_8b; // one packet of data is 8 bits wide

  SPI_InitStruct.SPI_CPOL = SPI_CPOL_Low;        // clock is low when idle

  SPI_InitStruct.SPI_CPHA = SPI_CPHA_1Edge;      // data sampled at first edge

  SPI_InitStruct.SPI_NSS = SPI_NSS_Soft | SPI_NSSInternalSoft_Set; // set the NSS management to internal and pull internal NSS high

  SPI_InitStruct.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_4; // SPI frequency is APB2 frequency / 4

  SPI_InitStruct.SPI_FirstBit = SPI_FirstBit_MSB;// data is transmitted MSB first

  SPI_Init(SPI1, &SPI_InitStruct);

 

 

  SPI_Cmd(SPI1, ENABLE); // enable SPI1

 }

 

 

 uint8_t SPI1_send(uint8_t data){

 

 

  SPI1->DR = data; // write data to be transmitted to the SPI data register

  while( !(SPI1->SR & SPI_I2S_FLAG_TXE) ); // wait until transmit complete

  while( !(SPI1->SR & SPI_I2S_FLAG_RXNE) ); // wait until receive complete

  while( SPI1->SR & SPI_I2S_FLAG_BSY ); // wait until SPI is not busy anymore

  return SPI1->DR; // return received data from SPI data register

 }

 

 

int main(void)

{

uint8_t received_val = 0;

init_SPI1();

while(1)

{

GPIOB->BSRRH |= GPIO_Pin_0; // set PE7 (CS) low

received_val=SPI1_send(0xA5);

GPIOB->BSRRL |= GPIO_Pin_0; // set PE7 (CS) high

}

}

 

Link to post
Share on other sites

1. output is square, that curved part is caused by probe's (and probably oscilloscope's input) capacitance

2. what is your SPI frequency? I don't know what APB2/4 is (I am not familiar with STM32F2.) The max f clock of this memory is 20MHz @5V and 10MHz @3.3V, make sure you stay below.

Link to post
Share on other sites

"The maximum allowed frequency of the high-speed APB2 domain is 60 MHz" - this  is what the user manual says. And someone suggested to send a dummy byte

 

GPIOB->BSRRH |= GPIO_Pin_0; // set PE7 (CS) low
SPI1_send(0x05); //The opcode for reading from the status register
received_val=SPI1_send(0x00);  //this is the dummy byte to be sent in order to read from the buffer.
GPIOB->BSRRL |= GPIO_Pin_0; // set PE7 (CS) high

 

PS - I made a mistake while posting the code over here - the read status code is - 0x05 and not 0xA5.

Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...