野火电子论坛

 找回密码
 注册

QQ登录

只需一步,快速开始

查看: 22973|回复: 17

问几个问题,在 SPI模块 章节的

[复制链接]
发表于 2013-8-23 22:04:51 | 显示全部楼层 |阅读模式
一,
#define countof(a)      (sizeof(a) / sizeof(*(a)))
#define  BufferSize (countof(Tx_Buffer)-1)

其中 “ -1 ”是什么意思? 是不是因为 “ \0 ”

二,

在 SPI_FLASH_Init() 函数中

void SPI_FLASH_Init(void)
{
  SPI_InitTypeDef  SPI_InitStructure;
  GPIO_InitTypeDef GPIO_InitStructure;

  /* Enable SPI1 and GPIO clocks */
  /*!< SPI_FLASH_SPI_CS_GPIO, SPI_FLASH_SPI_MOSI_GPIO,
       SPI_FLASH_SPI_MISO_GPIO, SPI_FLASH_SPI_DETECT_GPIO
       and SPI_FLASH_SPI_SCK_GPIO Periph clock enable */
  RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_GPIOD, ENABLE); // ??????????????

  /*!< SPI_FLASH_SPI Periph clock enable */
  RCC_APB2PeriphClockCmd(RCC_APB2Periph_SPI1, ENABLE);


  /*!< Configure SPI_FLASH_SPI pins: 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);

  /*!< Configure SPI_FLASH_SPI pins: MISO */
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6;
  GPIO_Init(GPIOA, &GPIO_InitStructure);

  /*!< Configure SPI_FLASH_SPI pins: MOSI */
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_7;
  GPIO_Init(GPIOA, &GPIO_InitStructure);

  /*!< Configure SPI_FLASH_SPI_CS_PIN pin: SPI_FLASH Card CS pin */
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
  GPIO_Init(GPIOA, &GPIO_InitStructure);

  /* Deselect the FLASH: Chip Select high */
  SPI_FLASH_CS_HIGH();

  /* SPI1 configuration */
  // W25X16: data input on the DIO pin is sampled on the rising edge of the CLK.
  // Data on the DO and DIO pins are clocked out on the falling edge of CLK.
  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);

  /* Enable SPI1  */
  SPI_Cmd(SPI1, ENABLE);
}

其中为什么要使能GPIOD ? 我看没有用到GPIOD啊。

三,

在main() 函数中:

int main(void)
{        
        /* 配置串口1为:115200 8-N-1 */
        USART1_Config();
        printf("\r\n 这是一个2M串行flash(W25X16)实验 \r\n");
       
        /* 2M串行flash W25X16初始化 */
        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\n 检测到华邦串行flash W25X16 !\r\n");
               
                /* Erase SPI FLASH Sector to write on */
                SPI_FLASH_SectorErase(FLASH_SectorToErase);                  
               
                /* 将发送缓冲区的数据写到flash中 */
                SPI_FLASH_BufferWrite(Tx_Buffer, FLASH_WriteAddress, BufferSize);
                printf("\r\n 写入的数据为:%s \r\t", Tx_Buffer);
               
                /* 将刚刚写入的数据读出来放到接收缓冲区中 */
                SPI_FLASH_BufferRead(Rx_Buffer, FLASH_ReadAddress, BufferSize);
                printf("\r\n 读出的数据为:%s \r\n", Tx_Buffer); // ??????????????
               
                /* 检查写入的数据与读出的数据是否相等 */
                TransferStatus1 = Buffercmp(Tx_Buffer, Rx_Buffer, BufferSize);
               
                if( PASSED == TransferStatus1 )
                {   
                        printf("\r\n 2M串行flash(W25X16)测试成功!\n\r");
                }
                else
                {        
                        printf("\r\n 2M串行flash(W25X16)测试失败!\n\r");
                }
        }// if (FlashID == sFLASH_ID)
        else
        {   
                printf("\r\n 获取不到 W25X16 ID!\n\r");
        }
       
        SPI_Flash_PowerDown();  
        while(1);  
}

我感觉应该把“ Tx_Buffer ”换成“ Rx_Buffer ”吧。



回复

使用道具 举报

发表于 2013-8-23 23:16:59 | 显示全部楼层
BufferSize  你 看看火哥 用在 哪个地方嘛,根据那个地方来分析为啥要减1
回复 支持 反对

使用道具 举报

发表于 2013-8-23 23:18:58 | 显示全部楼层
好像是没用到 GPIOD  ,你注释一下它,看看能不能运行正常就知道了
回复 支持 反对

使用道具 举报

发表于 2013-8-23 23:21:05 | 显示全部楼层
发现楼主的细心程度,吓人啊!!!
支持一个

那个应该把“ Tx_Buffer ”换成“ Rx_Buffer ” !明显火哥 粗心了
回复 支持 反对

使用道具 举报

发表于 2013-8-24 12:32:43 | 显示全部楼层
比妹子还漂亮,赞一个
回复 支持 反对

使用道具 举报

 楼主| 发表于 2013-8-24 17:51:35 | 显示全部楼层
onlyfly 发表于 2013-8-23 23:18
好像是没用到 GPIOD  ,你注释一下它,看看能不能运行正常就知道了

OK 谢谢哦 我试试
回复 支持 反对

使用道具 举报

 楼主| 发表于 2013-8-24 17:54:07 | 显示全部楼层
风落小鱼 发表于 2013-8-24 12:32
比妹子还漂亮,赞一个

。。。。。。。。。。。。。。。
回复 支持 反对

使用道具 举报

发表于 2013-8-24 20:40:14 | 显示全部楼层
GPIOD 没用到  可以注释  Tx_Buffer 应该换成 Rx_Buffer  我试过了  可以的  不过我也不大懂第一个问题  你弄明白的话麻烦也告诉我一下  谢谢
回复 支持 反对

使用道具 举报

 楼主| 发表于 2013-8-24 22:02:00 | 显示全部楼层
楼上男 发表于 2013-8-24 20:40
GPIOD 没用到  可以注释  Tx_Buffer 应该换成 Rx_Buffer  我试过了  可以的  不过我也不大懂第一个问题  你 ...

OK 搞定了通知你
回复 支持 反对

使用道具 举报

 楼主| 发表于 2013-8-30 16:29:18 | 显示全部楼层
柴柴 发表于 2013-8-24 22:02
OK 搞定了通知你

#define countof(a) (sizeof(a) / sizeof(*(a)))
计算a的成员个数,例如 字符串指针a,
那么a的大小是a指向字符串的长度
*a就是a指向字符串的第一个字符,
countof计算a的字符个数,

#define BufferSize (countof(Tx_Buffer)-1)
个数-1

BufferSize就是所有的字符去掉结束符\n的数量
回复 支持 反对

使用道具 举报

发表于 2013-8-30 16:40:43 | 显示全部楼层
柴柴 发表于 2013-8-30 16:29
#define countof(a) (sizeof(a) / sizeof(*(a)))
计算a的成员个数,例如 字符串指针a,
那么a的大小是a ...

你确定?


#define countof(a) (sizeof(a) / sizeof(*(a)))
这里是求数组的长度吧

如果 a 是字符串的指针,那么 sizeof(a) 是求长度吗?不是 strlen 才是求长度吗?
回复 支持 反对

使用道具 举报

发表于 2013-8-30 17:18:43 | 显示全部楼层
小栋 发表于 2013-8-30 16:40
你确定?

sizeof 字符串地址,结果应该是 4。
如果是 sizeof 数组,这样是 数组 空间
回复 支持 反对

使用道具 举报

 楼主| 发表于 2013-8-31 16:53:37 | 显示全部楼层
小栋 发表于 2013-8-30 16:40
你确定?

      strlen()计算字符数组的字符数,以"\0"为结束判断,不计算为'\0'的数组元素。
      而sizeof计算数据(包括数组、变量、类型、结构体等)所占内存空间,用字节数表示。
回复 支持 反对

使用道具 举报

 楼主| 发表于 2013-8-31 16:55:43 | 显示全部楼层
楼上男 发表于 2013-8-24 20:40
GPIOD 没用到  可以注释  Tx_Buffer 应该换成 Rx_Buffer  我试过了  可以的  不过我也不大懂第一个问题  你 ...

昨天回复错了,回复给我自己了,如果没看到了话可以看一下。
回复 支持 反对

使用道具 举报

发表于 2013-9-3 21:36:00 | 显示全部楼层
柴柴 发表于 2013-8-31 16:55
昨天回复错了,回复给我自己了,如果没看到了话可以看一下。

#define countof(a) (sizeof(a) / sizeof(*(a)))

但是这样做有什么意义吗?
回复 支持 反对

使用道具 举报

发表于 2013-9-3 22:09:06 | 显示全部楼层
楼上男 发表于 2013-9-3 21:36
#define countof(a) (sizeof(a) / sizeof(*(a)))

但是这样做有什么意义吗?

数组元素个数啊!!!
例如你把寄存器配置写到数组里,调用这个宏来求数组元素,就不需要老是手动定义数组元素个数了
回复 支持 反对

使用道具 举报

发表于 2013-9-4 09:20:04 | 显示全部楼层
格拉姆 发表于 2013-9-3 22:09
数组元素个数啊!!!
例如你把寄存器配置写到数组里,调用这个宏来求数组元素,就不需要老是手动定义数 ...

我是说为什么要 用‘/’呢? 如果不用个的话会怎么样?
回复 支持 反对

使用道具 举报

发表于 2013-9-4 23:23:48 | 显示全部楼层
楼上男 发表于 2013-9-4 09:20
我是说为什么要 用‘/’呢? 如果不用个的话会怎么样?

不 /sizeof(*(a)) ,是求数组占用的空间
除非 数组是 char 型那样,每个元素占用1个字节,那情况下,才是 数组占用空间 == 数组元素个数

如果数组是 uint32 类型,则每个元素 4字节,不符合条件
回复 支持 反对

使用道具 举报

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

本版积分规则

联系站长|手机版|野火电子官网|野火淘宝店铺|野火电子论坛 ( 粤ICP备14069197号 ) 大学生ARM嵌入式2群

GMT+8, 2024-5-20 15:28 , Processed in 0.037146 second(s), 24 queries , Gzip On.

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

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