打印
[STM8]

SPI主从机多字节通讯

[复制链接]
1347|3
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
现在使用2块STM8L作为主机和从机SPI通讯,从机使用中断,如果发送单个字节的时候示波器数据正常,连续发送两个自己的时候数据不正常,求助啊。。。。
主机程序
void SPI_Init(void)//初始化
{
   GPIO_Init(GPIOD,GPIO_Pin_4,GPIO_Mode_In_PU_No_IT);
   GPIO_Init(GPIOD,GPIO_Pin_5,GPIO_Mode_Out_PP_High_Slow);
   GPIO_Init(GPIOD,GPIO_Pin_6,GPIO_Mode_Out_PP_Low_Slow);
   GPIO_Init(SPI_CS, SPI_Pin_CS, GPIO_Mode_Out_PP_High_Slow);
   CLK_PeripheralClockConfig(CLK_Peripheral_SPI2,ENABLE);
   SPI_Init(SPI2,SPI_FirstBit_MSB, SPI_BaudRatePrescaler_256, SPI_Mode_Master,
            SPI_CPOL_Low,SPI_CPHA_1Edge,SPI_Direction_2Lines_FullDuplex,SPI_NSS_Soft, 0x07);
   SPI_Cmd(SPI2,ENABLE);
  GPIO_ResetBits(SPI_CS,SPI_Pin_CS);
}

u8 SPI_SendByte(u8 byte)//发送单字节
{
  /* Loop while DR register in not emplty */
  while (SPI_GetFlagStatus( SPI2,SPI_FLAG_TXE) == RESET);
  /* Send byte through the SPI1 peripheral */
  SPI_SendData(SPI2,byte);
  /* Wait to receive a byte */
  while (SPI_GetFlagStatus(SPI2,SPI_FLAG_RXNE) == RESET);
  /* Return the byte read from the SPI bus */
  return SPI_ReceiveData(SPI2);         
}


void main()
{

  .......
  while(1)
  {
          GPIO_ResetBits(SPI_CS,SPI_Pin_CS);
          RECEIVE_DATA[0]=SPI_FLASH_SendByte(SEND_DATA[0]);
          RECEIVE_DATA[1]=SPI_FLASH_SendByte(SEND_DATA[1]);
         GPIO_SetBits(SPI_CS,SPI_Pin_CS);
  }
}

从机程序
void SPI_FLASH_Init(void)//初始化
{
   GPIO_Init(GPIOD,GPIO_Pin_5,GPIO_Mode_In_PU_No_IT);
   GPIO_Init(GPIOD,GPIO_Pin_4,GPIO_Mode_Out_PP_High_Slow);
   GPIO_Init(GPIOD,GPIO_Pin_6,GPIO_Mode_In_PU_No_IT);
   GPIO_Init(SPI_CS, SPI_Pin_CS, GPIO_Mode_In_PU_No_IT);
   CLK_PeripheralClockConfig(CLK_Peripheral_SPI2,ENABLE);
   SPI_Init(SPI2,SPI_FirstBit_MSB, SPI_BaudRatePrescaler_256, SPI_Mode_Slave,
            SPI_CPOL_Low,SPI_CPHA_1Edge,SPI_Direction_2Lines_FullDuplex,SPI_NSS_Soft, 0x07);
   SPI_ITConfig(SPI2,SPI_IT_RXNE,ENABLE);
   SPI_Cmd(SPI2,ENABLE);
}



INTERRUPT_HANDLER(I2C1_SPI2_IRQHandler,29)
{
    /* In order to detect unexpected events during development,
       it is recommended to set a breakpoint on the following instruction.
    */
    if(flag_spi_loop)
    {
            RECEIVE_DATA[0]=SPI_FLASH_SendByte(SEND_DATA[0]);
            flag_spi_loop=0;
        LED_DATA[0]=(RECEIVE_DATA[0]&0x0f)|0xe0;
        LED_DATA[1]=(RECEIVE_DATA[0]>>4)|0xd0;
    }
    else
    {
            RECEIVE_DATA[1]=SPI_FLASH_SendByte(SEND_DATA[1]);
            flag_spi_loop=1;
            LED_DATA[2]=(RECEIVE_DATA[1]&0x0f)|0xb0;
        LED_DATA[3]=(RECEIVE_DATA[1]>>4)|0x70;
    }
    SPI_ClearITPendingBit(SPI2,SPI_IT_RXNE);
}

基本程序如上,当从机中的flag_spi_loop标志始终为1和主机只发送一个SEND_DATA[0]时候,示波器观察数据正常,但从机flag_spi_loop循环变化,主机发送两个的时候数据就错误了,

沙发
mmuuss586| | 2017-2-14 11:17 | 只看该作者
看你上面的程序也没啥问题啊

发送2个字节时,中间加些延时看看;
另外数据最好用0X55,另外一个0XAA方便验证

使用特权

评论回复
板凳
来自下邳的少年|  楼主 | 2017-2-16 17:05 | 只看该作者
mmuuss586 发表于 2017-2-14 11:17
看你上面的程序也没啥问题啊

发送2个字节时,中间加些延时看看;

谢谢你的回复,问题已经解决了,不是没延迟的问题,主要是在CS脚上

使用特权

评论回复
地板
来自下邳的少年|  楼主 | 2017-2-16 17:06 | 只看该作者
mmuuss586 发表于 2017-2-14 11:17
看你上面的程序也没啥问题啊

发送2个字节时,中间加些延时看看;

谢谢你的回复,问题解决了,不是没有加延迟的问题,只要CS的控制上

使用特权

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

本版积分规则

3

主题

11

帖子

0

粉丝