Stm32--spi interface

Source: Internet
Author: User

Stm32--spi Interface


Tenet: The learning of technology is limited and the spirit of sharing is limitless.


First, SPI Agreement " serialperipheral Interface "

Serial Peripheral interface, is a high-speed full-duplex communication bus. Communication between ADC/LCD and MCU.

1 , SPI Signal Line

The SPI contains 4 buses, and the SPI bus contains 4 buses, SS, SCK, MOSI, miso, respectively.

(1) SS (slaveselect): The chip selection signal line, when there are multiple SPI devices connected to the MCU, each device of the chip select signal line is connected to the MCU separate pin, while the other SCK, MOSI, miso line for multiple devices parallel to the same SPI bus, low-level active.

(2) SCK (Serial clocks): Clock signal line, generated by the main communication equipment, different devices support the clock frequency is not the same, such as STM32 SPI clock frequency of the largest is F PCLK/2.

(3) MOSI (master output, Slave input): Main device output/slave input pin. The data of the host is output from this signal line, which is read into the data by this signal line, i.e. the direction of the data on this line for the host to the slave.

(4) Miso (master input, Slave output): Main device input/slave outputs pin. The host reads the data from this signal line, and the data from the slave is output by this signal line, that is, the direction of the data on this line is from the machine to the host.

2 , SPI Mode

Depending on the SPI clock polarity (CPOL) and clock phase (CPHA) configuration, there are 4 different SPI modes. The clock polarity refers to the level signal of the SCK signal line when the SPI communication device is idle (it can also be considered as the beginning of the SPI communication, that is, the SS is low). When Cpol=0, the SCK is low when idle, while the cpol=1 is the opposite. The clock phase is the moment when the data is sampled, and when cpha=0, the signal on the MOSI or miso data line is sampled at the odd edge of the SCK clock line. When cpha=1, the data line is sampled at the even edge of the SCK.

First, by the host to the chip selection signal line SS pull low, meaning the host output, in the SS is pulled low moment, SCK divided into two cases, if we set to cpol=0, then SCK timing at this time is low, if set to Cpol=1, then SCK at this time is high. The sampling time is at the odd edge of the SCK (note that odd edges are sometimes falling along, sometimes rising edges).

When Cpha=1, the sampling time of the data signal is even edge.

Second, SPI Features and Architecture

(1) A single transmission can be selected as 8 or 16 bits.

(2) Baud rate Prescaler factor (max. FPCLK/2).

(3) Clock polarity (Cpol) and phase (CPHA) programmable settings.

(4) The sequence of data sequence can be programmed to choose, MSB in front or LSB in front.

(5) A dedicated send and receive flag that can trigger interrupts.

(6) DMA can be used for data transfer operations.

1 , SPI Architecture

The signal received by the miso data line is processed by the shift register to transfer the data to the receive buffer, and this data can be read from the receive buffer by our software.

When the data is sent, we write the data to the send buffer, and the hardware will output it to the MOSI data line after processing it with a shift register.

The SCK clock signal is generated by the baud rate generator, and we can control its output baud rate by the baud rate control bit (BR).

The control register CR1 governs the main control circuit, and the Protocol settings (clock polarity, phase, etc.) of the STM32 SPI module are made by it. The control register CR2 is used to set various interrupt enable.

Finally, the NSS pin, which plays the role of the SS-select signal line in the SPI protocol, if we configure the NSS pin as a hardware automatic control, the SPI module can automatically determine whether it can become the SPI host, or automatically enter the SPI slave mode. But in fact we use more of the software to control certain Gpio pins as a separate SS signal, this GPIO pin can be arbitrarily selected.

Third, SPI interface Read Flash

Each signal line connected to Flash (model: w25x16/w25q16) of CS, CLK, do and DIO line, to achieve SPI communication, Flash read and write, where w25x16 and w25q16 in different places on the program is the Flash ID is not the same.

Read the Flash ID information, write data, and read it to verify, through the serial port printing to write and read out the data, output test results.

Different devices will have different instructions, such as the EEPROM will interpret the first data as the address of the storage matrix (essentially instructions). Flash, however, defines more commands, such as writing instructions, reading instructions, and reading ID commands.

Spi-flash Communication:

( 1 ) configuration I/O ports, enabling GPIO .

( 2 ) According to the device that will be communicating SPI mode, configuring STM32 of the SPI , to enable SPI clocks.

( 3 ) configured Well SPI after, according to various Flash The defined command controls read and write to it.

Note that the erase operation of the storage sector should be preceded by a write enable command before the erase operation.

1 , main.c

int main (void) {/* Configuration serial 1 is: 115200 8-n-1 */usart1_config ();  printf ("\ r \ n This is a 2M serial Flash (w25x16) experiment \ r \ n");  /* 2M serial Flash W25Q16 initialization */spi_flash_init ();  /* Get SPI Flash Device ID */DeviceID = Spi_flash_readdeviceid ();  Delay (200);  /* Get SPI Flash ID */Flashid = Spi_flash_readid ();  printf ("\ r \ n Flashid is 0x%X, manufacturer Device ID is 0x%x\r\n", Flashid, DeviceID); /* Check the SPI flash ID */if (Flashid = = sflash_id)/* #define SFLASH_ID 0xef3015 */{printf ("\ r \ Nand" \ nthe serial Flash detected    w25x16!\r\n ");    Spi_flash_sectorerase (flash_sectortoerase);    Spi_flash_bufferwrite (Tx_buffer, flash_writeaddress, buffersize);    printf ("\ r \ n Write data is:%s \r\t", Tx_buffer);    Spi_flash_bufferread (Rx_buffer, flash_readaddress, buffersize);    printf ("\ r \ n read out the data is:%s \ r \ n", Tx_buffer);    /* Check that the data written is equal to the read data */TransferStatus1 = buffercmp (Tx_buffer, Rx_buffer, buffersize);    if (PASSED = = TransferStatus1) {printf ("\ r \ n 2M serial Flash (w25x16) test succeeded!\n\r");  } else  {printf ("\ r \ n 2M serial Flash (w25x16) test failed!\n\r");  }}//if (Flashid = = sflash_id) Else {printf ("\ r \ n not get w25x16 id!\n\r");  } spi_flash_powerdown (); while (1);}

(1) Call Usart1confi g () to initialize the serial port.

(2) Call Spi_flash_init () to initialize the SPI module.

(3) Call Spi_flash_readdeviceid () to read the FLASH device manufacturer's ID information.

(4) Call Spi_flash_readid () to read the device ID information of the FLASH device

(5) If the read obtained ID is correct, then call Spi_flash_sectorerase () erase the content of Flash, erase and call Spi_flash_bufferwrite () to write data to Flash, and then call Spi_flash_ Bufferread () reads the data from the address that was just written. The last call to the BUFFERCMP () function compares the data written to the read data, and assigns the flag variable TRANSFERSTATUS1 to PASSED (the custom enumeration variable) if the data being written is the same as the read data.

(6) Finally call the Spi_flash_powerdown () function to turn off the power of the flash device, because the data is written to flash and will not be lost due to power loss, we use it to re-open the Flash power

2 , SPI Initialize

#define Spi_flash_cs_high () gpio_setbits (Gpioa, Gpio_pin_4) #define Spi_flash_cs_low () gpio_resetbits (Gpioa, GPIO_Pin  _4) void Spi_flash_init (void) {spi_inittypedef spi_initstructure;  Gpio_inittypedef gpio_initstructure; Rcc_apb2periphclockcmd (Rcc_apb2periph_gpioa |  Rcc_apb2periph_gpiod, ENABLE);  Rcc_apb2periphclockcmd (Rcc_apb2periph_spi1, ENABLE);  /* SCK */gpio_initstructure.gpio_pin = gpio_pin_5;  Gpio_initstructure.gpio_speed = Gpio_speed_50mhz;  Gpio_initstructure.gpio_mode = gpio_mode_af_pp;  Gpio_init (Gpioa, &gpio_initstructure);  /* Miso */gpio_initstructure.gpio_pin = gpio_pin_6;  Gpio_init (Gpioa, &gpio_initstructure);  /* MOS */gpio_initstructure.gpio_pin = gpio_pin_7;  Gpio_init (Gpioa, &gpio_initstructure);  /* CS */gpio_initstructure.gpio_pin = Gpio_pin_4;  Gpio_initstructure.gpio_mode = gpio_mode_out_pp;  Gpio_init (Gpioa, &gpio_initstructure);  Spi_flash_cs_high ();  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_4;  Spi_initstructure.spi_firstbit = SPI_FIRSTBIT_MSB;  Spi_initstructure.spi_crcpolynomial = 7;  Spi_init (SPI1, &spi_initstructure); Spi_cmd (SPI1, ENABLE);}

(1) Spi_mode: Host mode (spi_mode_master) or slave mode (spi_mode_slave), the maximum difference between the two modes is the timing of the SPI SCK signal line, the SCK timing is generated by the host in the communication. If configured as a slave mode, the SPI module of the STM32 will accept external SCK signals.
(2) Spi_datasize:spi the data size (called data frame) for each communication is 8-bit or 16-bit.

(3) Spi_cpol and Spi_cpha: Configures the SPI's clock polarity (CPOL) and clock phase cpha, which affect the SPI communication mode, which conforms to the requirements of the device that will communicate with each other. Cpol can take Spi_cpol_high (SPI communication is SCK high when idle) and Spi_cpol_low (SPI communication is low when idle). Cpha can take Spi_cpha_1edge (collect data at the odd edge of SCK) and Spi_cpha_2edge (collect data on the SCK even edge).

(4) Spi_nss: Configure the NSS PIN usage mode, hardware mode (spi_nss_hard) and software mode (Spi_nss_soft), the SPI chip selection signal in hardware mode is automatically generated by the hardware, while the software mode requires us to personally put the corresponding GPIO The port is pulled high or low to produce non-chip and chip selection signals. The hardware mode also automatically sets the SPI of the STM32 to the host if external conditions permit. We use software mode to assign a value of Spi_nss_soft to this member.

(5) Spi_baudrateprescaler: This member sets the baud rate divider value, the clock after the frequency is the SPI's sck signal line clock frequency. This member parameter can be set to 2, 4, 6, 8, 16, 32, 64, 128, 256 for F PCLK. The assignment is Spi_baudrateprescaler_4, which is 4 of the F PCLK.

(6) Spi_firstbit: All serial communication protocols will have MSB first (high data in front) or LSB first (low data in front) problem, and the STM32 SPI module can be through the structure of the member, this feature programming control. According to the Flash communication sequence, we assign this member to the MSB first (SPI_FIRSTBIT_MSB).

(7) Spi_crcpolynomial: This is the polynomial in the CRC check of the SPI, and if we use CRC Check, we use the member's parameter (polynomial) to calculate the CRC value. Since the Flash in this experiment does not support CRC verification, it is practically meaningless to assign a value of 7 to this struct member.

After configuring these struct members, we call the Spi_init () function to write these parameters to the register, implement the SPI initialization, and then call Spi_cmd () to enable the SPI1.

2 , read FLASH of the ID

#define Dummy_byte   0xffu8 spi_flash_sendbyte (U8 Byte) {  //waits to send data register empty while  (Spi_i2s_getflagstatus (SPI1 , spi_i2s_flag_txe) = = RESET);   Spi_i2s_senddata (SPI1, Byte); Send data to Slave  while (spi_i2s_getflagstatus (spi1,spi_i2s_flag_rxne) = = RESET)//wait to receive data register non null   return Spi_i2s_ Receivedata (SPI1); Gets the data in the Receive Register}U32 Spi_flash_readdeviceid (void) {  u32 Temp = 0;   Spi_flash_cs_low ();  Spi_flash_sendbyte (W25x_deviceid);  Spi_flash_sendbyte (dummy_byte);  Spi_flash_sendbyte (dummy_byte);  Spi_flash_sendbyte (dummy_byte);  Temp = Spi_flash_sendbyte (dummy_byte);  Spi_flash_cs_high ();   return Temp;} <span style= "font-family:arial, Helvetica, Sans-serif; Background-color:rgb (255, 255, 255); " > </span>

3 , read vendor ID

U32 Spi_flash_readid (void) {  u32 Temp = 0, Temp0 = 0, Temp1 = 0, Temp2 = 0;  Spi_flash_cs_low ();  Spi_flash_sendbyte (W25x_jedecdeviceid); 0x9F  Temp0 = Spi_flash_sendbyte (dummy_byte);  TEMP1 = Spi_flash_sendbyte (dummy_byte);  TEMP2 = Spi_flash_sendbyte (dummy_byte);  Spi_flash_cs_high ();  Temp = (Temp0 << 16) | (TEMP1 << 8) | TEMP2;  return Temp;}

4 , Erase FLASH content

void spi_flash_writeenable (void) {  spi_flash_cs_low ();  Spi_flash_sendbyte (w25x_writeenable); 06H  Spi_flash_cs_high ();} void Spi_flash_waitforwriteend (void) {  U8 flash_status = 0;  Spi_flash_cs_low ();  Spi_flash_sendbyte (W25x_readstatusreg); 05H  do  {    flash_status = Spi_flash_sendbyte (dummy_byte);  }  while ((Flash_status & wip_flag) = = SET);  Spi_flash_cs_high ();} void Spi_flash_sectorerase (U32 sectoraddr) {  spi_flash_writeenable ();  Spi_flash_waitforwriteend ();  Spi_flash_cs_low ();  Spi_flash_sendbyte (w25x_sectorerase); 20H  spi_flash_sendbyte ((sectoraddr & 0xFF0000) >> +);  Spi_flash_sendbyte ((sectoraddr & 0xff00) >> 8);  Spi_flash_sendbyte (Sectoraddr & 0xFF);  Spi_flash_cs_high ();  Spi_flash_waitforwriteend ();}

5 , to Flash Write Data -- page Out

void Spi_flash_pagewrite (u8* pbuffer, U32 writeaddr, U16 numbytetowrite) {spi_flash_writeenable ();  Spi_flash_cs_low (); Spi_flash_sendbyte (W25x_pageprogram);  02H Spi_flash_sendbyte ((writeaddr & 0xFF0000) >> 16);  Spi_flash_sendbyte ((writeaddr & 0xff00) >> 8);  Spi_flash_sendbyte (Writeaddr & 0xFF);  if (Numbytetowrite > spi_flash_perwritepagesize) {numbytetowrite = spi_flash_perwritepagesize;    } while (numbytetowrite--) {spi_flash_sendbyte (*pbuffer);  pbuffer++;  } spi_flash_cs_high (); Spi_flash_waitforwriteend ();} void Spi_flash_bufferwrite (u8* pbuffer, U32 writeaddr, U16 numbytetowrite) {U8 numofpage = 0, Numofsingle = 0, Addr = 0,  Count = 0, temp = 0;  Addr = writeaddr% Spi_flash_pagesize;  Count = spi_flash_pagesize-addr;  Numofpage = numbytetowrite/spi_flash_pagesize;  Numofsingle = numbytetowrite% Spi_flash_pagesize;    if (Addr = = 0) {if (Numofpage = = 0) {spi_flash_pagewrite (pbuffer, writeaddr, numbytetowrite);} else {while (numofpage--) {spi_flash_pagewrite (pbuffer, writeaddr, spi_flash_pagesize);        Writeaddr + = Spi_flash_pagesize;      Pbuffer + = Spi_flash_pagesize;    } spi_flash_pagewrite (pbuffer, writeaddr, Numofsingle);        }} else {if (Numofpage = = 0) {if (Numofsingle > Count) {temp = Numofsingle-count;        Spi_flash_pagewrite (pbuffer, WRITEADDR, Count);        Writeaddr + = count;        Pbuffer + = count;      Spi_flash_pagewrite (pbuffer, writeaddr, temp);      } else {spi_flash_pagewrite (pbuffer, writeaddr, numbytetowrite);      }} else {numbytetowrite-= count;      Numofpage = numbytetowrite/spi_flash_pagesize;      Numofsingle = numbytetowrite% Spi_flash_pagesize;      Spi_flash_pagewrite (pbuffer, WRITEADDR, Count);      Writeaddr + = count;      Pbuffer + = count;   while (numofpage--) {spi_flash_pagewrite (pbuffer, writeaddr, spi_flash_pagesize);     Writeaddr + = Spi_flash_pagesize;      Pbuffer + = Spi_flash_pagesize;      } if (Numofsingle! = 0) {spi_flash_pagewrite (pbuffer, writeaddr, Numofsingle); }    }  }}

6 , from Flash Read

void Spi_flash_bufferread (u8* pbuffer, U32 readaddr, U16 numbytetoread) {  spi_flash_cs_low ();  Spi_flash_sendbyte (W25x_readdata); 03H  spi_flash_sendbyte ((readaddr & 0xFF0000) >> +);  Spi_flash_sendbyte ((readaddr & 0xff00) >> 8);  Spi_flash_sendbyte (Readaddr & 0xFF);  while (numbytetoread--)   {    *pbuffer = Spi_flash_sendbyte (dummy_byte);    pbuffer++;  }  Spi_flash_cs_high ();}

Stm32--spi interface

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.