Stm32f10x microcontroller advanced -- spi use, stm32f10x -- spi
Use SPI to communicate with External flash (MX25L6406EM21) IC
As shown in, the MCU is connected to an external flash chip through SPI2.
Define the SPI port number used in SPI2
Initialize the communication function in spi2
Read and Write Data
View the datasheet of the flash chip. The mx25 chip can be written by PAGE and erased by sector. Page_program is 0x02, and sector_erase is 0x20. Before writing data to each page, make sure that the slice of this page has been erased. The maximum size of each page is 256 bytes, and the size of one slice is 4 Kbytes.
- Write Data and write data by PAGE (write one page of data)
Write command 0x06 Based on Chip
void spi_flash_write_page (uint8_t * pBuffer, uint32_t write_address, uint16_t num_byte_to_write) // Write data to the page, where write_address must be the entire data part of 256, which is the start position of a page,
{
uint16_t i = 0;
// debug_out ("SpiPage: 0x% 08x Len:% d \ r \ n", write_address, num_byte_to_write);
spi_flash_wait_busy (); // Busy wait
spi_flash_write_enable ();
spi_flash_wait_busy ();
spi2_cs_low ();
spi2_read_write_byte (MX25_PAGE_PROGRAM);
spi2_read_write_byte ((uint8_t) (((write_address) >> 16) & 0xFF));
spi2_read_write_byte ((uint8_t) (((write_address) >> 8) & 0xFF));
spi2_read_write_byte ((uint8_t) ((write_address) & 0xff));
for (i = 0; i <num_byte_to_write; i ++)
{
spi2_read_write_byte (pBuffer [i]);
}
spi2_cs_high ();
spi_flash_wait_busy ();
}
void spi_flash_erase_sector (uint32_t addr) // addr is a multiple of 4K and clears a sector
{
spi_flash_wait_busy ();
spi_flash_write_enable ();
spi_flash_wait_busy ();
// ½øÐвÁ³ý²Ù × ÷
spi2_cs_low ();
spi2_read_write_byte (MX25_SECTOR_ERASE);
spi2_read_write_byte ((uint8_t) (((addr) >> 16) & 0xFF));
spi2_read_write_byte ((uint8_t) (((addr) >> 8) & 0xFF));
spi2_read_write_byte ((uint8_t) ((addr) & 0xff));
spi2_cs_high ();
spi_flash_wait_busy ();
}
- Write Data of the specified length at the specified address
Write Data of the specified length from the specified address. It also writes data from the beginning of a sector and calculates the total number of pages to be written. If it is the beginning of a sector, remember to perform the sector erasure operation.
void spi_flash_write(uint8_t* pBuffer,uint32_t address,uint16_t buffer_len)
{
uint16_t pageCount = 0;
uint16_t pageIndex = 0;
uint16_t length = 0;
uint16_t i=0;
pageCount = buffer_len / SPI_FLASH_PAGE_SIZE;
if( ( buffer_len % SPI_FLASH_PAGE_SIZE ) != 0 )
{
pageCount += 1;
}
while( pageIndex < pageCount )
{
length = buffer_len - ( pageIndex * SPI_FLASH_PAGE_SIZE ) ;
length = length > SPI_FLASH_PAGE_SIZE ? SPI_FLASH_PAGE_SIZE : length;
if( ( ( address + pageIndex * SPI_FLASH_PAGE_SIZE ) % SPI_FLASH_SECTOR_SIZE ) == 0 )
{
spi_flash_erase_sector( address + pageIndex * SPI_FLASH_PAGE_SIZE );
}
spi_flash_write_page(pBuffer + pageIndex * SPI_FLASH_PAGE_SIZE, address + pageIndex * SPI_FLASH_PAGE_SIZE, length );
pageIndex ++;
}
}
Reading data is much simpler than writing data. It reads data from a specified address and reads the specified length.
void spi_flash_read(uint8_t* pBuffer,uint32_t read_address,uint16_t num_byte_to_read)
{
uint16_t i=0;
spi_flash_wait_busy();
spi2_cs_low();
spi2_read_write_byte(MX25_READ_DATA);
spi2_read_write_byte((uint8_t) ( ((read_address) >> 16 )&0xFF) );
spi2_read_write_byte((uint8_t) ( ((read_address) >> 8 )&0xFF) );
spi2_read_write_byte((uint8_t) ( (read_address)&0xff ) );
for(i=0;i<num_byte_to_read;i++)
{
pBuffer[i]=spi2_read_write_byte(0xFF);
}
spi2_cs_high();
}
So far, the entire driver has been compiled.