OpenEdv-开源电子网

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

GPIO模拟SPI 驱动W25Q64碰到了个奇怪问题

[复制链接]

4

主题

26

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
212
金钱
212
注册时间
2016-7-28
在线时间
25 小时
发表于 2016-11-3 22:20:40 | 显示全部楼层 |阅读模式
5金钱
学了原子哥的SPI实验后,想发挥一下用GPIO模拟SPI来操作Flash.
可是模拟的读写函数 u8 SPI_RWByte(u8 TxData) 出了问题

SPI.H文件
#ifndef __SPI_H
#define __SPI_H
#include "sys.h"
#define MOSI_H  GPIO_SetBits(GPIOB,GPIO_Pin_15)
#define MOSI_L  GPIO_ResetBits(GPIOB,GPIO_Pin_15)

#define READ_MISO GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_14)

#define SCK_H  GPIO_SetBits(GPIOB,GPIO_Pin_13)
#define SCK_L  GPIO_ResetBits(GPIOB,GPIO_Pin_13)
void SPI2_Init(void);       
u8 SPI_RWByte(u8 TxData);                 
#endif


SPI.C文件
#include "spi.h"
#include "delay.h"
void SPI2_Init(void)
{
        GPIO_InitTypeDef GPIO_InitStructure;
        RCC_APB2PeriphClockCmd(        RCC_APB2Periph_GPIOB, ENABLE );

        GPIO_InitStructure.GPIO_Pin = GPIO_Pin_13 | GPIO_Pin_15;
        GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;  //输出模式
        GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
        GPIO_Init(GPIOB, &GPIO_InitStructure);
       
        GPIO_InitStructure.GPIO_Pin = GPIO_Pin_14;
        GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;  //输入模式
        GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
        GPIO_Init(GPIOB, &GPIO_InitStructure);
       
}   

u8 SPI1_RWByte(u8 TxData)
{               
        u8 i;

                for(i=0;i<8;i++)
        {
                if(TxData & 0x80)
                        MOSI_H;
                else
                        MOSI_L;
                TxData = (TxData << 1);
                SCK_H;      //上升沿写入
                delay_us(2);      //稳定数据
                if(READ_MISO)
                TxData |= 0x01;
                SCK_L;      //下降沿读出
                delay_us(2);     //稳定数据
        }
        return TxData;
}

u8 SPI2_RWByte(u8 TxData)
{               
        u8 i;

                for(i=0;i<8;i++)
        {
                if(TxData & 0x80)
                        MOSI_H;
                else
                        MOSI_L;
                TxData = (TxData << 1);
                SCK_L;   //下降沿写入
                delay_us(2);      //稳定数据
                if(READ_MISO)
                TxData |= 0x01;
                SCK_H;   //上升沿读出
                delay_us(2);     //稳定数据
        }
        return TxData;
}


我把 u8 SPI1_RWByte(u8 TxData)配置成 SCK_H;  上升沿写入   SCK_L;  下降沿读出 时可以正常操作Flash的读写
我把 u8 SPI2_RWByte(u8 TxData)配置成SCK_L;   下降沿写入   SCK_H;   上升沿读出 时也可以正常操作Flash的读写
这是为什么?







时序图

时序图

最佳答案

查看完整内容[请看2#楼]

有时候,外设其实是兼容某些不正确的时序的。但是不正确的时序的对错,他是不保证的
正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

30

主题

1170

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1993
金钱
1993
注册时间
2016-2-16
在线时间
527 小时
发表于 2016-11-3 22:20:41 | 显示全部楼层
本帖最后由 憨厚诚实大叔 于 2016-11-14 21:17 编辑
旺旺佳 发表于 2016-11-4 11:34
我知道是错的,但是他确实可以通过自检和读写Flash.就因为这让我很迷惑

有时候,外设其实是兼容某些不正确的时序的。但是不正确的时序的对错,他是不保证的
回复

使用道具 举报

50

主题

1805

帖子

0

精华

论坛元老

Rank: 8Rank: 8

积分
6662
金钱
6662
注册时间
2016-5-29
在线时间
910 小时
发表于 2016-11-4 09:19:12 | 显示全部楼层
很明显你的代码是错误的.SPI哪里是这样子的哟.

   for(i=0;i<8;i++)
        {
                if(TxData & 0x80)
                        MOSI_H;
                else
                        MOSI_L;
                TxData = (TxData << 1);
                SCK_L;   //下降沿写入
                delay_us(2);      //稳定数据
                if(READ_MISO)
                TxData |= 0x01;
                SCK_H;   //上升沿读出
                delay_us(2);     //稳定数据
        }

这一段有错..
回复

使用道具 举报

4

主题

26

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
212
金钱
212
注册时间
2016-7-28
在线时间
25 小时
 楼主| 发表于 2016-11-4 11:34:55 | 显示全部楼层
操作系统 发表于 2016-11-4 09:19
很明显你的代码是错误的.SPI哪里是这样子的哟.

   for(i=0;i

我知道是错的,但是他确实可以通过自检和读写Flash.就因为这让我很迷惑
回复

使用道具 举报

16

主题

60

帖子

0

精华

高级会员

Rank: 4

积分
798
金钱
798
注册时间
2016-9-17
在线时间
241 小时
发表于 2016-11-14 15:49:33 | 显示全部楼层
哥们模拟spi驱动w25q64代码能借阅一下吗
回复

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165536
金钱
165536
注册时间
2010-12-1
在线时间
2117 小时
发表于 2016-11-14 19:13:12 | 显示全部楼层
旺旺佳 发表于 2016-11-4 11:34
我知道是错的,但是他确实可以通过自检和读写Flash.就因为这让我很迷惑

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

使用道具 举报

0

主题

3

帖子

0

精华

新手入门

积分
17
金钱
17
注册时间
2018-7-5
在线时间
1 小时
发表于 2018-7-5 16:16:22 | 显示全部楼层
初始化默认gpio低电平,按照正常情况你这样肯定是不能正常读写的。
回复

使用道具 举报

0

主题

3

帖子

0

精华

新手入门

积分
17
金钱
17
注册时间
2018-7-5
在线时间
1 小时
发表于 2018-7-5 16:42:10 | 显示全部楼层
操作系统 发表于 2016-11-4 09:19
很明显你的代码是错误的.SPI哪里是这样子的哟.

   for(i=0;i

sck肯定一开始就要拉高拉低的,
回复

使用道具 举报

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

本版积分规则



关闭

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

正点原子公众号

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

GMT+8, 2025-6-11 13:24

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

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