码迷,mamicode.com
首页 > 其他好文 > 详细

stm32f10x单片机进阶--spi使用

时间:2018-02-05 12:35:56      阅读:174      评论:0      收藏:0      [点我收藏+]

标签:相对   方式   端口   定义   分享图片   address   .com   指令   add   

  使用SPI与外部flash(MX25L6406EM21)IC通信

  • 连接方式

                  技术分享图片

 

         技术分享图片

                  如上图所示,MCU通过SPI2与外部flash芯片进行相连接。

  • MCU spi2初始化

                技术分享图片

    定义SPI2 中所使用的SPI 端口号

                          技术分享图片

               spi2中 通信功能初始化

读数据与写数据

  •   指令说明

       查看flash芯片的datasheet,mx25芯片支持按照页来写,按照扇区来擦除。page_program 为 0x02    ,sector_erase为0x20。并且在向每个页中写数据前,必须先保证此页所在的扇区已经进行擦除操作。并且每一页最大写256byte ,一个扇区的大小为4Kbyte

  • 写数据,按照页来写数据(写一页数据)

依据芯片写指令 0x06

void spi_flash_write_page(uint8_t* pBuffer,uint32_t write_address,uint16_t num_byte_to_write) //向页中写入数据,其中write_address必须为256的整数据部,即一页的开始位置,
{
    uint16_t i=0;
    
//    debug_out("SpiPage:0x%08x Len:%d\r\n", write_address, num_byte_to_write);
    
    spi_flash_wait_busy();   //忙等待
    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地起为4K的倍数,清除一个扇区
{
    spi_flash_wait_busy();
    spi_flash_write_enable();
    spi_flash_wait_busy();
    
    //??DD2á3y2ù×÷
    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();
}
  • 在指定地址处开始写入指定长度的数据

从指定地址,写入指定长度数据。也是从一个扇区的开始处进行写,计算出一共需要写入多少页,同时如果为一个扇区的开始处,记得需要进行扇区擦除操作。

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 ++;
    }
}
  • 读数据

读数据相对于写数据来说,显得比较简单的多,从指定地址开始读,读取指定的长度

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();
    
}

至此整个驱动编写完成。

stm32f10x单片机进阶--spi使用

标签:相对   方式   端口   定义   分享图片   address   .com   指令   add   

原文地址:https://www.cnblogs.com/oops-374565452/p/8416663.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!