打印
[STM32]

大神帮我看看SPI3的初始化问题

[复制链接]
3558|11
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
peter_h|  楼主 | 2013-12-9 17:14 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
spi, IO, GPIO, gp, se
请教各位,我用PC10 --CLK,PC11 --MISO,PC12 MOSI,来初始化SPI3接口,另一端是DS26518的芯片,但是怎么也无法读出芯片的Device ID,代码如下,有大神给指点一下吗?

//定义GPIO管脚来通过SPI 初始化E1芯片
#define GPIO_SPI_E1_PORT1        GPIOC //pins,10,11,12,5,6,7,8,9,4
#define GPIO_SPI_E1_PORT2        GPIOD //pins 0,1
#define GPIO_SPI_E1_PORT3        GPIOA //pins 4
#define E26518_SPI_SCLK          GPIO_Pin_10
#define E26518_SPI_MISO          GPIO_Pin_11
#define E26518_SPI_MOSI          GPIO_Pin_12
#define E26518_SPI_SWAP          GPIO_Pin_4
#define E1_SEL1                  GPIO_Pin_4
#define E1_SEL2                  GPIO_Pin_5
#define E1_SEL3                  GPIO_Pin_6
#define E1_SEL4                  GPIO_Pin_7
#define E1_SEL5                  GPIO_Pin_8
#define E1_SEL6                  GPIO_Pin_9
#define E1_SEL7                  GPIO_Pin_0
#define E1_SEL8                  GPIO_Pin_1
//CLK define ...
#define SPI_E26518_SPI_CLK                  RCC_APB1Periph_SPI3         
#define SPI_E26518_SPI_SCLK_GPIO_CLK        RCC_APB2Periph_GPIOC
#define SPI_E26518_SPI_MISO_GPIO_CLK        RCC_APB2Periph_GPIOC
#define SPI_E26518_SPI_MOSI_GPIO_CLK        RCC_APB2Periph_GPIOC
#define SPI_E26518_SPI_SEL1_GPIO_CLK        RCC_APB2Periph_GPIOA
#define SPI_E26518_SPI_SEL2_GPIO_CLK        RCC_APB2Periph_GPIOC
#define SPI_E26518_SPI_SEL3_GPIO_CLK        RCC_APB2Periph_GPIOC
#define SPI_E26518_SPI_SEL4_GPIO_CLK        RCC_APB2Periph_GPIOC
#define SPI_E26518_SPI_SEL5_GPIO_CLK        RCC_APB2Periph_GPIOC
#define SPI_E26518_SPI_SEL6_GPIO_CLK        RCC_APB2Periph_GPIOC
#define SPI_E26518_SPI_SEL7_GPIO_CLK        RCC_APB2Periph_GPIOD
#define SPI_E26518_SPI_SEL8_GPIO_CLK        RCC_APB2Periph_GPIOD
//POLL TYPE AND POLL MODE DEFINE...
//poll type...
#define POLL_SEL1            0x00
#define POLL_SEL2            0x01
#define POLL_SEL3            0x02
#define POLL_SEL4            0x03
#define POLL_SEL5            0x04
#define POLL_SEL6            0x05
#define POLL_SEL7            0x06
#define POLL_SEL8            0x07
#define POLL_ALL             0XFF
//poll mode...
#define POLL_LOW             0
#define POLL_HIGH            1

void SPI_E26518_Poll_Action(u8 poll_type,u8 poll_mode)
{
        if (POLL_LOW == poll_mode)
                {//拉低操作...
                        switch(poll_type)
                        {
                                case POLL_SEL1:
                                         GPIO_ResetBits(GPIO_SPI_E1_PORT3, E1_SEL1);
                                        break;
                                case POLL_SEL2:
                                         GPIO_ResetBits(GPIO_SPI_E1_PORT1, E1_SEL2);
                                        break;
                                case POLL_SEL3:
                                         GPIO_ResetBits(GPIO_SPI_E1_PORT1, E1_SEL3);
                                        break;
                                case POLL_SEL4:
                                         GPIO_ResetBits(GPIO_SPI_E1_PORT1, E1_SEL4);
                                        break;
                                case POLL_SEL5:
                                         GPIO_ResetBits(GPIO_SPI_E1_PORT1, E1_SEL5);
                                        break;
                                case POLL_SEL6:
                                         GPIO_ResetBits(GPIO_SPI_E1_PORT1, E1_SEL6);
                                        break;
                                case POLL_SEL7:
                                         GPIO_ResetBits(GPIO_SPI_E1_PORT2, E1_SEL7);
                                        break;
                                case POLL_SEL8:
                                         GPIO_ResetBits(GPIO_SPI_E1_PORT2, E1_SEL8);
                                        break;
                                case POLL_ALL:
                                        GPIO_ResetBits(GPIO_SPI_E1_PORT3, E1_SEL1);
                                        GPIO_ResetBits(GPIO_SPI_E1_PORT1, E1_SEL2);
                                        GPIO_ResetBits(GPIO_SPI_E1_PORT1, E1_SEL3);
                                        GPIO_ResetBits(GPIO_SPI_E1_PORT1, E1_SEL4);
                                        GPIO_ResetBits(GPIO_SPI_E1_PORT1, E1_SEL5);
                                        GPIO_ResetBits(GPIO_SPI_E1_PORT1, E1_SEL6);
                                        GPIO_ResetBits(GPIO_SPI_E1_PORT2, E1_SEL7);
                                        GPIO_ResetBits(GPIO_SPI_E1_PORT2, E1_SEL8);
                                        printf("herer\r\n");
                                        break;
                                default:
                                        //出错了...
                                        break;
                        }
                }
        else if (POLL_HIGH == poll_mode)
                { //拉高操作...
                        switch(poll_type)
                        {
                                case POLL_SEL1:
                                         GPIO_SetBits(GPIO_SPI_E1_PORT3, E1_SEL1);
                                        break;
                                case POLL_SEL2:
                                         GPIO_SetBits(GPIO_SPI_E1_PORT1, E1_SEL2);
                                        break;
                                case POLL_SEL3:
                                         GPIO_SetBits(GPIO_SPI_E1_PORT1, E1_SEL3);
                                        break;
                                case POLL_SEL4:
                                         GPIO_SetBits(GPIO_SPI_E1_PORT1, E1_SEL4);
                                        break;
                                case POLL_SEL5:
                                         GPIO_SetBits(GPIO_SPI_E1_PORT1, E1_SEL5);
                                        break;
                                case POLL_SEL6:
                                         GPIO_SetBits(GPIO_SPI_E1_PORT1, E1_SEL6);
                                        break;
                                case POLL_SEL7:
                                         GPIO_SetBits(GPIO_SPI_E1_PORT2, E1_SEL7);
                                        break;
                                case POLL_SEL8:
                                         GPIO_SetBits(GPIO_SPI_E1_PORT2, E1_SEL8);
                                        break;
                                case POLL_ALL:
                                        GPIO_SetBits(GPIO_SPI_E1_PORT3, E1_SEL1);
                                        GPIO_SetBits(GPIO_SPI_E1_PORT1, E1_SEL2);
                                        GPIO_SetBits(GPIO_SPI_E1_PORT1, E1_SEL3);
                                        GPIO_SetBits(GPIO_SPI_E1_PORT1, E1_SEL4);
                                        GPIO_SetBits(GPIO_SPI_E1_PORT1, E1_SEL5);
                                        GPIO_SetBits(GPIO_SPI_E1_PORT1, E1_SEL6);
                                        GPIO_SetBits(GPIO_SPI_E1_PORT2, E1_SEL7);
                                        GPIO_SetBits(GPIO_SPI_E1_PORT2, E1_SEL8);
                                        break;
                                default:
                                        //出错了...
                                        break;
                        }
                }
                else
                        {
                                //出错了
                        }
                return;
}
/*******************************************************************************
* Function Name  : E1_SPI_IF_INIT
* Description    : init E1 chip by SPI interface,this function init the SPI interface
* Input          : None
* Output         : None
* Return         : None
*******************************************************************************/
void E1_SPI_IF_init(void)
{
  SPI_InitTypeDef  SPI_InitStructure;
  GPIO_InitTypeDef GPIO_InitStructure;

  /* Disable  E1_SEL 2, 3, 4, 5, 6 */
  GPIO_InitStructure.GPIO_Pin = E1_SEL2|E1_SEL3|E1_SEL4|E1_SEL5|E1_SEL6;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
  GPIO_Init(GPIO_SPI_E1_PORT1, &GPIO_InitStructure);
  GPIO_SetBits(GPIO_SPI_E1_PORT1, E1_SEL2|E1_SEL3|E1_SEL4|E1_SEL5|E1_SEL6);                 //通过设置BSRR寄存器
  
  /* Disable E1_SEL 1 */
  GPIO_InitStructure.GPIO_Pin = E1_SEL1;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
  GPIO_Init(GPIO_SPI_E1_PORT3, &GPIO_InitStructure);
  GPIO_SetBits(GPIO_SPI_E1_PORT3, E1_SEL1);                                                                                 //通过设置BSRR寄存器

  /* Disable E1_SEL 7, 8*/
  GPIO_InitStructure.GPIO_Pin = E1_SEL7|E1_SEL8;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
  GPIO_Init(GPIO_SPI_E1_PORT2, &GPIO_InitStructure);
  GPIO_SetBits(GPIO_SPI_E1_PORT2, E1_SEL7|E1_SEL8);                                                                 //通过设置BSRR寄存器

  
  /* Enable SPI3 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(SPI_E26518_SPI_SCLK_GPIO_CLK|RCC_APB2Periph_GPIOA|
                         RCC_APB2Periph_GPIOD|RCC_APB2Periph_AFIO , ENABLE);                  //设置APB2ENR寄存器对应位,使能GPIO port C 时钟
  
  /*!< AFIO Periph clock enable */
  RCC_APB1PeriphClockCmd(SPI_E26518_SPI_CLK,ENABLE);                                         //SPI3在APB1总线上,使能 SPI3 的时钟

  /*!< Remap SPI3 Pins */
  GPIO_PinRemapConfig(GPIO_Remap_SPI3,ENABLE);  
  
  /*!< Configure SPI_FLASH_SPI pins: SCK */
  GPIO_InitStructure.GPIO_Pin = E26518_SPI_SCLK;
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;//复用推挽模式
  GPIO_Init(GPIO_SPI_E1_PORT1, &GPIO_InitStructure);//初始化SPI,涉及GPIO的CRL\BRR\BSRR寄存器

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

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


  /* Deselect the FLASH: Chip Select high */
  SPI_E26518_Poll_Action(POLL_ALL,POLL_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_LSB;
  SPI_InitStructure.SPI_CRCPolynomial = 7;
  SPI_Init(SPI3, &SPI_InitStructure);        //主要通过设置CR1/I2SCFGR/CRCPR寄存器

  /* Enable SPI1  */
  SPI_Cmd(SPI3, ENABLE);//spi使能,主要通过设置CR1寄存器

}
/*******************************************************************************
* Function Name  : spi read/write base byte
* Description    : read/write one byte through spi interface...
* Input          : None
* Output         : None
* Return         : None
*******************************************************************************/
//read byte through spi
unsigned char readByte_SPIex1(void) {
        unsigned char cBYTE,i;
while (SPI_I2S_GetFlagStatus(SPI3, SPI_I2S_FLAG_RXNE) == RESET);
  /* Return the byte read from the SPI bus */
  return SPI_I2S_ReceiveData(SPI3);
}

//write a byte...
void writeByte_SPIex1( unsigned char cBYTE) {
        /* Loop while DR register in not emplty */
  while (SPI_I2S_GetFlagStatus(SPI3, SPI_I2S_FLAG_TXE) == RESET);
  /* Send byte through the SPI3 peripheral */
  SPI_I2S_SendData(SPI3, cBYTE);
}
/*******************************************************************************
* Function Name  : write value to register of e1
* Description    : spi write a 2byte address to e1 chip and read one or two byte...
* Input          : None
* Output         : None
* Return         : None
*******************************************************************************/
void write_value(u16 addr,u8 value)
{
   u8 SendByte = 0;
   u16 tmp_addr =addr<<1;

   SendByte = (tmp_addr>>8)&0x7f;
   //send first 8bit of addr domain,and the 8th bit must be zero
   writeByte_SPIex1(SendByte);
   //the second 8bit of addr domain
   SendByte = tmp_addr&0xff;
   writeByte_SPIex1(SendByte);
   //send value of resgister
         SPI_E1_SendByte(value);
         return;
}
/*******************************************************************************
* Function Name  : read one address value from register of e1
* Description    : spi write a 2byte address to e1 chip and read one or two byte...
* Input          : None
* Output         : None
* Return         : None
*******************************************************************************/
u8 Read_Value(u16 addr)
{
   u8 SendByte = 0;       
  
   SendByte = (addr>>7)|0x80;//读时,地址的最高位置1

   writeByte_SPIex1(SendByte);

   SendByte = (addr&0xff)<<1;
   writeByte_SPIex1(SendByte);

   SendByte = readByte_SPIex1();
   return SendByte;
}

void Read_Device_ID()
{
  int i = 0;
  int j=0 ,k=0;
  u8 Device_ID = 0;
  //读Device ID operator
  for (i = 0;i< 8 ;i++)
  {
          SPI_E26518_Poll_Action(i,POLL_LOW);
          Device_ID = Read_Value(0x00f8);
          printf("\r\n i = %d,Device_ID=%02x",i,Device_ID);
          SPI_E26518_Poll_Action(i,POLL_HIGH);
          for(j = 0;j<1000;j++)k=j;//sleep a timer...
  }
  return;
}


大神给把把脉吧,不圣感谢。!!!!!!!!!!!!!!!!!!!!!!!!

相关帖子

沙发
craaazyfor| | 2013-12-9 17:36 | 只看该作者
除非谁正好在搞这个,要不然很少会把你的代码都看一遍的,你用其他SPI口试试,注意时钟引脚配置和SPI模式配置就差不多了,不行用示波器看看各引脚波形

使用特权

评论回复
板凳
peter_h|  楼主 | 2013-12-9 19:25 | 只看该作者
谢谢了

使用特权

评论回复
地板
fengdingkusong| | 2013-12-11 17:08 | 只看该作者
代码没有太仔细看,但是要想用SPI3就要关闭JTAG,因为引脚复用了
初始化的时候试试加上代码
AFIO->MAPR &= 0x00ffffff; //关闭JTAG
AFIO->MAPR |= 0x02000000;

使用特权

评论回复
5
peter_h|  楼主 | 2013-12-11 19:47 | 只看该作者
fengdingkusong 发表于 2013-12-11 17:08
代码没有太仔细看,但是要想用SPI3就要关闭JTAG,因为引脚复用了
初始化的时候试试加上代码
AFIO->MAPR &=  ...

但是我没有用jtag那几个口呀,我只用了PC10,PC11,PC12呀,用pb3,pb4,pb5才需要关闭jtag呀?大神帮忙看看吧。

使用特权

评论回复
6
peter_h|  楼主 | 2013-12-11 19:48 | 只看该作者
这个问题已经三天了,请大家帮忙看看吧,先谢了。

使用特权

评论回复
7
fengdingkusong| | 2013-12-11 19:49 | 只看该作者
peter_h 发表于 2013-12-11 19:47
但是我没有用jtag那几个口呀,我只用了PC10,PC11,PC12呀,用pb3,pb4,pb5才需要关闭jtag呀?大神帮忙 ...

MCU型号?

使用特权

评论回复
8
peter_h|  楼主 | 2013-12-11 19:49 | 只看该作者
craaazyfor 发表于 2013-12-9 17:36
除非谁正好在搞这个,要不然很少会把你的代码都看一遍的,你用其他SPI口试试,注意时钟引脚配置和SPI模式配 ...

哥哥有空,给小弟看看,这个问题困扰我三天了,用示波器量,clk口,miso以及mosi都是高电平,似乎spi3没有启动,时钟什么的,我也没有看出问题来。

使用特权

评论回复
9
peter_h|  楼主 | 2013-12-11 19:54 | 只看该作者
fengdingkusong 发表于 2013-12-11 19:49
MCU型号?

stm32f107vc

使用特权

评论回复
10
fengdingkusong| | 2013-12-11 20:28 | 只看该作者
peter_h 发表于 2013-12-11 19:54
stm32f107vc

用示波器看时钟的时候有没有在一直操作SPI?保证测量的时候理论上是由时钟的

使用特权

评论回复
11
xyliusun| | 2016-3-18 16:51 | 只看该作者
相同芯片我遇到了差不多的问题程序停在了这里
while (SPI_I2S_GetFlagStatus(SPI3, SPI_I2S_FLAG_RXNE) == RESET);
你解决了问题了没?

使用特权

评论回复
12
xyliusun| | 2016-3-18 17:28 | 只看该作者
我的问题解决了
RCC_APB1PeriphClockCmd(RCC_APB1Periph_SPI3, ENABLE);
是这里的问题

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

1

主题

6

帖子

0

粉丝