打印
[STM32L1]

STM32L152 SPI 通信问题

[复制链接]
8078|17
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
kanta|  楼主 | 2012-7-14 23:35 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
本帖最后由 kanta 于 2012-7-14 23:40 编辑

我现在使用的是STM32L152,用了两个ST的开发板,用SPI2进行通信,通信不成功,软件配置如下:
void SPI_INIT()
{
  SPI_InitTypeDef SPI_InitStructure;
  GPIO_InitTypeDef GPIO_InitStructure;
  //EXTI_InitTypeDef EXTI_InitStructure;
  //NVIC_InitTypeDef NVIC_InitStructure;
  
  SPI_Cmd(SPI2,DISABLE);
  
  RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOB, ENABLE); //使能GPIOB 时钟
  RCC_APB1PeriphClockCmd(RCC_APB1Periph_SPI2, ENABLE);
  
  /*!< Configure SPI_FLASH_SPI pins: SCK */
  GPIO_InitStructure.GPIO_Pin =  GPIO_Pin_12|GPIO_Pin_13|GPIO_Pin_15;// 初始化指定管脚
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;// //
GPIO_Mode_AF   = 0x02, /*!< GPIO Alternate function Mode */
  GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;//  
  GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;// 推挽方式输出 还是 集电极开路方式输出
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_40MHz;//
  GPIO_Init(GPIOB, &GPIO_InitStructure);
  
  /*!< Configure SPI_FLASH_SPI pins: MISO */
  GPIO_InitStructure.GPIO_Pin =  GPIO_Pin_14;// 初始化指定管脚
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;// 管脚工作模式:输出
  GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;// 输入时上(下)拉状态:上拉
  GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;// 推挽方式输出 还是 集电极开路方式输出
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_40MHz;// 管脚输出的速度
  GPIO_Init(GPIOB, &GPIO_InitStructure);
  SPI_InitStructure.SPI_Direction=SPI_Direction_2Lines_FullDuplex;//2线全双工
  SPI_InitStructure.SPI_Mode=SPI_Mode_Master;//SPI主设备
  SPI_InitStructure.SPI_DataSize=SPI_DataSize_8b;//SPI传输数据8位
  SPI_InitStructure.SPI_CPOL=SPI_CPOL_Low;//时钟极性为低跳变到高采集数据
  SPI_InitStructure.SPI_CPHA=SPI_CPHA_1Edge;//时钟相位(第一个跳变沿采集数据)
  SPI_InitStructure.SPI_NSS=SPI_NSS_Soft;//片选方式   
  SPI_InitStructure.SPI_BaudRatePrescaler=SPI_BaudRatePrescaler_16;//波特率预分频,16分频
  SPI_InitStructure.SPI_FirstBit=SPI_FirstBit_MSB;;//指定数据传输从MSB位还是LSB位开始
  SPI_InitStructure.SPI_CRCPolynomial=7;//设置crc多项式
  SPI_Init(SPI2,&SPI_InitStructure);
  //SPI_Cmd(SPI2,ENABLE);
/*Enable SPI1.NSS as a GPIO*/
  SPI_SSOutputCmd(SPI1, ENABLE);
  GPIO_InitStructure.GPIO_Pin =GPIO_Pin_12;
  GPIO_InitStructure.GPIO_Mode=GPIO_OType_PP;
  GPIO_Init(GPIOB, &GPIO_InitStructure);
  SPI_Cmd(SPI2,ENABLE);
}
主函数如下:
int main(void)
{
  unsigned int i,j;
  SystemInit();
  SPI_INIT();
  
  /* Check if the StandBy flag is set */
  if (PWR_GetFlagStatus(PWR_FLAG_SB) != RESET)
  {
    /* System resumed from STANDBY mode */
    /* Clear StandBy flag */
    RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR,ENABLE);//清除标志位
    PWR_ClearFlag(PWR_FLAG_SB);
    /* set StandbyWakeup indicator*/
    //StanbyWakeUp = TRUE;
  }
  else
  {
    /* Reset StandbyWakeup indicator*/
   // StanbyWakeUp = FALSE;   
  }
  
  enableInterrupts();
   
  while(1)
  {
    GPIO_ResetBits(GPIOB, GPIO_Pin_12);
    while(SPI_I2S_GetFlagStatus(SPI2,SPI_I2S_FLAG_BSY )!= RESET)//线路忙则等待
    {
;
    }
    SPI_I2S_SendData(SPI2, 0x01);
    while(SPI_I2S_GetFlagStatus(SPI2,SPI_I2S_FLAG_BSY )!= RESET)//线路忙则等待
    {
;
    }
    GPIO_SetBits(GPIOB, GPIO_Pin_12);
   
   
   
    GPIO_SetBits(GPIOB, GPIO_Pin_6);// GPIO_Pin_6输出为1
    GPIO_SetBits(GPIOB, GPIO_Pin_7);// GPIO_Pin_7输出为1
   
    Delay(200);
    GPIO_ResetBits(GPIOB, GPIO_Pin_6);// GPIO_Pin_6输出为0     
    GPIO_ResetBits(GPIOB, GPIO_Pin_7);// GPIO_Pin_7输出为0
    Delay(200);
    /*for( i=BufferSize; i>0; i-- )
     {
       TI_CC_SPIStrobe(SIDLE);
       TI_CC_SPIWriteBurstReg(TXFIFO,SPI2_Buffer_Tx,BufferSize);
       TI_CC_SPIStrobe(STX);
      
     }
     
     Delay(200);*/
}
}


SPI2从机的配置如下:
void SPI_INIT()
{
  SPI_InitTypeDef SPI_InitStructure;
  GPIO_InitTypeDef GPIO_InitStructure;
  //EXTI_InitTypeDef EXTI_InitStructure;
  //NVIC_InitTypeDef NVIC_InitStructure;
  
  SPI_Cmd(SPI2,DISABLE);
  
  RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOB, ENABLE); //使能GPIOA 时钟
  RCC_APB1PeriphClockCmd(RCC_APB1Periph_SPI2, ENABLE);
  
  /*!< Configure SPI_FLASH_SPI pins: SCK */
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12 | GPIO_Pin_13 | GPIO_Pin_15;// 初始化指定管脚
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;// 管脚工作模式:输出//
  GPIO_Mode_AF   = 0x02, /*!< GPIO Alternate function Mode */
  GPIO_InitStructure.GPIO_OType = GPIO_OType_OD;// 输入时上(下)拉状态:
  GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;// 推挽方式输出 还是 集电极开路方式输出
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_40MHz;// 管脚输出的速度
  GPIO_Init(GPIOB, &GPIO_InitStructure);
  
  /*!< Configure SPI_FLASH_SPI pins: MISO */
  GPIO_InitStructure.GPIO_Pin =  GPIO_Pin_14;// 初始化指定管脚
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;// 管脚工作模式:输出
  GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;//
  GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;// 推挽方式输出 还是 集电极开路方式输出
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_40MHz;// 管脚输出的速度:
  GPIO_Init(GPIOB, &GPIO_InitStructure);
  SPI_InitStructure.SPI_Direction=SPI_Direction_2Lines_FullDuplex;//2线全双工
  SPI_InitStructure.SPI_Mode=SPI_Mode_Slave;//SPI从设备
  SPI_InitStructure.SPI_DataSize=SPI_DataSize_8b;//SPI传输数据8位
  SPI_InitStructure.SPI_CPOL=SPI_CPOL_Low;//时钟极性为低跳变到高采集数据
  SPI_InitStructure.SPI_CPHA=SPI_CPHA_1Edge;//时钟相位(第一个跳变沿采集数据)
  SPI_InitStructure.SPI_NSS=SPI_NSS_Soft;//片选方式     
  //SPI_InitStructure.SPI_BaudRatePrescaler=SPI_BaudRatePrescaler_16;//波特率预分频,16分频
  SPI_InitStructure.SPI_FirstBit=SPI_FirstBit_MSB;;//指定数据传输从MSB位还是LSB位开始
  SPI_InitStructure.SPI_CRCPolynomial=7;//设置crc多项式
  SPI_Init(SPI2,&SPI_InitStructure);

  
  SPI_SSOutputCmd(SPI1, ENABLE);
  GPIO_InitStructure.GPIO_Pin =GPIO_Pin_12;
  GPIO_InitStructure.GPIO_Mode=GPIO_OType_PP;
  GPIO_Init(GPIOB, &GPIO_InitStructure);
  
   SPI_Cmd(SPI2,ENABLE);
}

主函数如下:
#define enableInterrupts()   __set_PRIMASK(0);
int main(void)
{
  unsigned int i,j;
  SystemInit();
  SPI_INIT();
  
   if (PWR_GetFlagStatus(PWR_FLAG_SB) != RESET)
  {
    /* System resumed from STANDBY mode */
    /* Clear StandBy flag */
    RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR,ENABLE);//清除标志位
    PWR_ClearFlag(PWR_FLAG_SB);
    /* set StandbyWakeup indicator*/
    //StanbyWakeUp = TRUE;
  }
  else
  {
    /* Reset StandbyWakeup indicator*/
   // StanbyWakeUp = FALSE;   
  }
  
  enableInterrupts();
   
  while(1)
  {
     
     while(SPI_I2S_GetFlagStatus(SPI2,SPI_I2S_FLAG_RXNE )!= RESET)//线路忙则等待
    {
;
    }
    i=SPI_I2S_ReceiveData(SPI2);
    if(i!=0)
    {
      GPIO_SetBits(GPIOB, GPIO_Pin_6);// GPIO_Pin_6输出为1
      GPIO_SetBits(GPIOB, GPIO_Pin_7);// GPIO_Pin_7输出为1
      Delay(200);
      //while(1);
    }
    else if(i==0)
    {
      
      GPIO_ResetBits(GPIOB, GPIO_Pin_6);// GPIO_Pin_6输出为1
      GPIO_SetBits(GPIOB, GPIO_Pin_7);// GPIO_Pin_7输出为1
      //Delay(200);
    }
     
      }
}

从机读出的结果总是0;
没有示波器,没法看波形,麻烦各位帮我提提意见,看我的配置是否正确,先谢了。
沙发
kanta|  楼主 | 2012-7-15 08:52 | 只看该作者
顶起

使用特权

评论回复
板凳
kanta|  楼主 | 2012-7-15 10:06 | 只看该作者
看来周末没人啊

使用特权

评论回复
地板
a868247| | 2012-7-16 14:55 | 只看该作者
本帖最后由 a868247 于 2012-7-20 08:46 编辑

楼主,搞的蛮快的

使用特权

评论回复
5
香水城| | 2012-7-16 15:27 | 只看该作者
STM32L的GPIO架构和STM32F1的略有不同

LZ请参考下例程代码

配置SPI需要额外调用
GPIO_PinAFConfig(GPIOX, GPIO_PinSourcex, GPIO_AF_SPIx);

使用特权

评论回复
6
香水城| | 2012-7-16 15:27 | 只看该作者
STM32L的GPIO架构和STM32F1的略有不同

LZ请参考下例程代码

配置SPI需要额外调用
GPIO_PinAFConfig(GPIOX, GPIO_PinSourcex, GPIO_AF_SPIx);

使用特权

评论回复
7
zh5202| | 2012-7-16 16:50 | 只看该作者
最好还是找个示波器,打出波形一看就知道是哪里的问题了。

使用特权

评论回复
8
kanta|  楼主 | 2012-7-17 12:00 | 只看该作者
感谢各位的回复,昨天我用了GPIO_PinAFConfig(GPIOX, GPIO_PinSourcex, GPIO_AF_SPIx)后,总是出现硬件错误,掉到硬件中断里面出不来,还没找到原因

使用特权

评论回复
9
yinyangdianzi| | 2012-7-17 13:26 | 只看该作者
:$

L系列勘误.pdf

237.16 KB

F1升级L1.pdf

312 KB

使用特权

评论回复
10
IJK| | 2012-7-17 14:51 | 只看该作者
没有示波器,调试确实很麻烦。但还是有办法的,其实用MCU的GPIO,也可以检测SPI有没有数据发送出来。
建议LZ先检查,SPI有没有数据发出?

使用特权

评论回复
11
figo20042005| | 2012-7-17 15:12 | 只看该作者
同意LS,可以用给数据发出程序里加一些现象用GPIO显示,看看是不是SPI有数据发出

使用特权

评论回复
12
kanta|  楼主 | 2012-7-17 22:28 | 只看该作者
OK,我试试看

使用特权

评论回复
13
kanta|  楼主 | 2012-7-17 23:19 | 只看该作者
我用了GPIO_PinAFConfig(GPIOB, GPIO_Pin_13, GPIO_AF_SPI2)后,程序一直在
void HardFault_Handler(void)
{
  /* Go to infinite loop when Hard Fault exception occurs */
  while (1);
}跳不出这个中断,我在网上了个网站好像是介绍这个问题的,非英文的没看明白

使用特权

评论回复
14
kanta|  楼主 | 2012-7-18 00:14 | 只看该作者
跳不出这个中断的问题找到了,我以前定义是
GPIO_PinAFConfig(GPIOB, GPIO_Pin_12, GPIO_AF_SPI2);
改成这样定义
GPIO_PinAFConfig(GPIOX, GPIO_PinSourcex, GPIO_AF_SPIx);就可以,具体原因未知,没时间仔细研究

使用特权

评论回复
15
figo20042005| | 2012-7-18 08:54 | 只看该作者
看来STM的配置定义很关键,很容易犯错,还需理解DATASHEET

使用特权

评论回复
16
zuowei43| | 2016-3-23 09:36 | 只看该作者
kanta 发表于 2012-7-18 00:14
跳不出这个中断的问题找到了,我以前定义是
GPIO_PinAFConfig(GPIOB, GPIO_Pin_12, GPIO_AF_SPI2);
改成这 ...

楼主找到原因了吗?

使用特权

评论回复
17
zuowei43| | 2016-3-23 09:39 | 只看该作者
香水城 发表于 2012-7-16 15:27
STM32L的GPIO架构和STM32F1的略有不同

LZ请参考下例程代码

跳不出这个中断的问题找到了,我以前定义是
GPIO_PinAFConfig(GPIOB, GPIO_Pin_12, GPIO_AF_SPI2);
改成这样定义
GPIO_PinAFConfig(GPIOX, GPIO_PinSourcex, GPIO_AF_SPIx);就可以,具体原因未知,没时间仔细研究

直接这样调用?

使用特权

评论回复
18
Donil| | 2017-6-2 17:15 | 只看该作者
GPIO_Pin_12 并不是 GPIO_PinSourcex 而已

使用特权

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

本版积分规则

7

主题

44

帖子

0

粉丝