OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 4501|回复: 5

怎么使用SPI 16位数据宽度读取W25Q64数据

[复制链接]

5

主题

21

帖子

0

精华

初级会员

Rank: 2

积分
97
金钱
97
注册时间
2020-4-22
在线时间
49 小时
发表于 2020-12-16 00:09:16 | 显示全部楼层 |阅读模式
10金钱
怎么使用SPI 16位数据宽度读取W25Q64 。希望有具体代码。原子哥说的精英版综合实验我这边看不懂,基础不好,实在不能理解。
8位的数据宽度可以实现了。但是读取出来的数据要拼接才能写到LCD。速度太慢了。

正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

5

主题

21

帖子

0

精华

初级会员

Rank: 2

积分
97
金钱
97
注册时间
2020-4-22
在线时间
49 小时
 楼主| 发表于 2020-12-25 18:24:27 | 显示全部楼层
结一下:初始化的时候设置成16位,再把SPI读写函数中u8改为u16就行了
回复

使用道具 举报

3

主题

11

帖子

0

精华

初级会员

Rank: 2

积分
60
金钱
60
注册时间
2020-6-30
在线时间
19 小时
发表于 2020-12-25 18:25:40 | 显示全部楼层
帮忙顶
回复

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165540
金钱
165540
注册时间
2010-12-1
在线时间
2117 小时
发表于 2020-12-26 00:44:34 | 显示全部楼层
奥陌陌 发表于 2020-12-25 18:24
结一下:初始化的时候设置成16位,再把SPI读写函数中u8改为u16就行了

搞定了么?
我是开源电子网www.openedv.com站长,有关站务问题请与我联系。
正点原子STM32开发板购买店铺http://openedv.taobao.com
正点原子官方微信公众平台,点击这里关注“正点原子”
回复

使用道具 举报

5

主题

21

帖子

0

精华

初级会员

Rank: 2

积分
97
金钱
97
注册时间
2020-4-22
在线时间
49 小时
 楼主| 发表于 2020-12-26 22:18:23 | 显示全部楼层

多谢原子哥,搞定了。现在把代码贴出来。
回复

使用道具 举报

5

主题

21

帖子

0

精华

初级会员

Rank: 2

积分
97
金钱
97
注册时间
2020-4-22
在线时间
49 小时
 楼主| 发表于 2020-12-26 22:40:27 | 显示全部楼层
这是16位SPI读取SPI FLASH的代码。

********这个是半字发送读取函数 **************
u16 SPI1_ReadWriteHalfWord(u16 TxData)
{
//        u8 retry=0;
//        while(SPI_I2S_GetFlagStatus(SPI1,SPI_I2S_FLAG_TXE)==RESET)
//        {
//                retry++;
//                if(retry>200)return 0;
//        }
//        SPI_SendData(SPI1,TxData);
//        retry=0;
//        while(SPI_I2S_GetFlagStatus(SPI1,SPI_I2S_FLAG_RXNE)==RESET)
//        {
//                retry++;
//                if(retry>200)return 0;
//        }
//        return SPI_I2S_ReceiveData(SPI1);
       
        //过多调用SPI_SendData子函数,造成时间浪费。
        //去掉等待,并且不使用函数操作,转使用寄存器操作
       
//        while(SPI_I2S_GetFlagStatus(SPI1,SPI_I2S_FLAG_TXE)==RESET);
        SPI1->DR = TxData;

        while(SPI_I2S_GetFlagStatus(SPI1,SPI_I2S_FLAG_RXNE)==RESET);
        return SPI1->DR;
}

********这个是SPI 8位16位模式函数设置函数 **************
void SPI_16B_8B_MODE(u8 mode)
{
                u16 tempreg=0;
        if(mode==0)        //8位普通模式,重新配置SPI
        {
                RCC->APB2RSTR = 1<<12;        //复位SPI1     已经进行复位操作了,就不需要除能SPI1了
                RCC->APB2RSTR&= 0<<12;//停止复位SPI1
                tempreg|=0<<10;                        //全双工模式       
                tempreg|=1<<9;                        //软件nss管理
                tempreg|=1<<8;                         
                tempreg|=1<<2;                        //SPI主机  
                tempreg|=0<<11;                        //8位数据格式       
                tempreg|=1<<1;                        //空闲模式下SCK为1 CPOL=1
                tempreg|=1<<0;                        //数据采样从第2个时间边沿开始,CPHA=1   
                tempreg|=0<<3;                        //2分频,设置为30Mhz频率
                tempreg|=0<<7;                        //MSB First  
                tempreg|=1<<6;                        //SPI启动
                SPI1->CR1=tempreg;                 //设置CR1  
               
/*******2020/12/20测试,发现下面这一句相对于上面一段的赋值方法并没有太大的改善。****/
//                SPI1->CR1=0x0347;                 //直接给SPI1 CR1赋值  
//                SPI1->I2SCFGR&=~(1<<11);//选择SPI模式
        }else                                                //16位模式
        {
                SPI1->CR1|=0<<6;    //除能SPI1,先关闭SPI才能操作CR1的SPE位
                SPI1->CR1|=1<<10;         //仅接收模式   
                SPI1->CR1|=1<<11;                //16bit数据格式
//                SPI1->CR2 |= 1<<0;   //开启SPI DMA请求       
                SPI1->CR1|=1<<6;    //操作完成使能SPI1       
        }  
}

********这个是从SPI FLASH中读取数据函数******
void W25QXX_Read_16B(u16* pBuffer,u32 ReadAddr,u16 NumByteToRead)   //读取flash
{
        u16 i;                                                                                       
        W25QXX_CS;                                    //使能器件   
  SPI1_ReadWriteByte(W25X_ReadData);                 //发送读取命令   
  SPI1_ReadWriteByte((u8)((ReadAddr)>>16));          //发送24bit地址   
  SPI1_ReadWriteByte((u8)((ReadAddr)>>8));   
  SPI1_ReadWriteByte((u8)ReadAddr);

        SPI_Cmd(SPI1,DISABLE);//使能SPI1
        SPI1->CR1|=1<<10;                 //仅接收模式   
        SPI1->CR1|=1<<11;                //16bit数据格式
        SPI_Cmd(SPI1,ENABLE);//使能SPI1       
  for(i=0;i<NumByteToRead;i++)
                {
      pBuffer[i]=SPI1_ReadWriteHalfWord(0XFFFF);           //循环读数  
    }
        SPI_16B_8B_MODE(0); //设置SPI1位8位模式
        W25QXX_NCS;        
}

*******这个是把数据上传LCD的函数****
//函数功能:SPI 16位数据宽度读取图片并显示
//函数名称:LCD_show_pic_16B
//形    参:u32 page 定义好的图片地址
//返 回 值:无
//时    间:2020/12/20
//修    改:
u16 datatemp[1024];
void LCD_show_pic_16B(u32 page)
{       
        u16 i =0,j=0;
//        u16 color;

        LCD_SetCursor(0,0);    //设置坐标
        LCD_WriteRAM_Prepare();         //写GRAM
        for (j=0;j<150;j++)
        {
                W25QXX_Read_16B(datatemp,(page+(2048*j)),1024);  //读取flash
                for(i=0;i<1024;i++)
                {
//                                printf("%d_",i);
//                                printf("datatemp = %x\r\n",datatemp[i]);
                                LCD_WR_DATA(datatemp[i]);
                }
        }

}

3.5寸LCD 一张图片转成BIN文件后300K的大小。16位SPI相比于8位的要快200ms左右。因为可以直接读就写到LCD的GRAM中,8位的还要进行数据拼接
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则



关闭

原子哥极力推荐上一条 /2 下一条

正点原子公众号

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2025-6-24 14:20

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

快速回复 返回顶部 返回列表