请教,关于hspi做从机,MISO信号相位不对的问题

PEACE
Posts: 3
Joined: Thu Sep 22, 2016 10:36 am

请教,关于hspi做从机,MISO信号相位不对的问题

Postby PEACE » Thu Sep 22, 2016 11:00 am

我将ESP8266的HSPI配置为从机,然后连接到我的STM32单片机上,写入与读取数据都没有问题,但是,通过逻辑分析仪的观察,发现MISO信号是在上升沿变化的,且逻辑分析仪分析出的数据是错误的。

STM32上运行的是RT_Thread操作系统,不停的发送与读取数据。代码如下:

Code: Select all

void WriteTest(void)
{
   int i;
   esp8266_writeBuf[0] = 0x02;//0x02 写数据  0x03读数据
   esp8266_writeBuf[1] = 0x00;
   
   esp8266_writeBuf[2] = counter++;
   for (i = 0; i < 30; i++)
   {
      esp8266_writeBuf[i + 3] = 2;
   }
   esp8266_writeBuf[33] = esp8266_writeBuf[2];
      
   rt_memset(esp8266_readBuf,0,sizeof(esp8266_readBuf));
   esp8266_message.send_buf = esp8266_writeBuf;
   esp8266_message.recv_buf = esp8266_readBuf;   //设置读写缓存
   esp8266_message.length = 34;         //设置读写长度
   esp8266_message.cs_take = 1;         //开始通信时拉低CS
   esp8266_message.cs_release = 1;      //结束通信时拉高CS
   esp8266_message.next = RT_NULL;
   rt_spi_transfer_message(rt_spi_esp8266_device, &esp8266_message);//进行一次数据传输
   
   rt_kprintf("\r\nesp8266 write Buf is \r\n");
   for (i = 0; i < 34; i++)
   {
      rt_kprintf("%02X ", esp8266_writeBuf[i]);
   }
}

void ReadTest(void)
{
   int i;
   esp8266_writeBuf[0] = 0x03;//0x02 写数据  0x03读数据
   esp8266_writeBuf[1] = 0x00;
   
   rt_memset(esp8266_writeBuf + 2, 0, 32);
   
   rt_memset(esp8266_readBuf,0,sizeof(esp8266_readBuf));
   esp8266_message.send_buf = esp8266_writeBuf;
   esp8266_message.recv_buf = esp8266_readBuf;   //设置读写缓存
   esp8266_message.length = 34;         //设置读写长度
   esp8266_message.cs_take = 1;         //开始通信时拉低CS
   esp8266_message.cs_release = 1;      //结束通信时拉高CS
   esp8266_message.next = RT_NULL;
   rt_spi_transfer_message(rt_spi_esp8266_device, &esp8266_message);//进行一次数据传输
   
   rt_kprintf("\r\nesp8266 read Buf is \r\n");
   for (i = 0; i < 34; i++)
   {
      rt_kprintf("%02X ", esp8266_readBuf[i]);
   }
}
/*******************************************************************************
* 函数名    : wifi_thread_entry
* 描述      : 通信相关线程
* 输入        : - parameter: 线程入口参数
* 输出        : None
* 返回值    : None
*******************************************************************************/
void wifi_thread_entry(void* parameter)
{
   init_esp8266();
   while(1)
   {
      WriteTest();
      rt_thread_delayMs(10);
      ReadTest();
      rt_thread_delayMs(10);
   }   
}


ESP8266上使用的是esp8266_nonos_sdk_v2.0.0_16_07_19,并参照ESP8266_技术参考.pdf上41-44页的程序,只是增加了在中断中将接收到的数据通过串口输出的代码,代码如下

Code: Select all

uint32 intCounter = 0;
static uint8 spi_data[32] = {0};
static uint8 idx = 0;

// SPI interrupt callback function.
void spi_slave_isr_sta(void *para)
{
   uint32 regvalue;
   uint32 statusW, statusR, counter;
   uint32 recv_data,i;
   
   if (READ_PERI_REG(0x3ff00020)&BIT4)
   {
      //following 3 lines is to clear isr signal
      CLEAR_PERI_REG_MASK(SPI_SLAVE(SpiNum_SPI), 0x3ff);
   }
   else if (READ_PERI_REG(0x3ff00020)&BIT7)
   { //bit7 is for hspi isr,
   
/*      regvalue = READ_PERI_REG(SPI_USER(SpiNum_HSPI));
      os_printf("\r\nspi_slave_isr_sta SPI_USER[0x%08x]\n\r",regvalue);
   
      regvalue = READ_PERI_REG(SPI_ADDR(SpiNum_HSPI));
      os_printf("spi_slave_isr_sta SPI_ADDR[0x%08x]\n\r",regvalue);
   
      regvalue = READ_PERI_REG(SPI_CTRL(SpiNum_HSPI));
      os_printf("spi_slave_isr_sta SPI_CTRL[0x%08x]\n\r",regvalue);
   
      regvalue = READ_PERI_REG(SPI_RD_STATUS(SpiNum_HSPI));
      os_printf("spi_slave_isr_sta SPI_RD_STATUS[0x%08x]\n\r",regvalue);
   
      regvalue = READ_PERI_REG(SPI_WR_STATUS(SpiNum_HSPI));
      os_printf("spi_slave_isr_sta SPI_WR_STATUS[0x%08x]\n\r",regvalue);
*/
      regvalue = READ_PERI_REG(SPI_SLAVE(SpiNum_HSPI));
      os_printf("\r\nspi_slave_isr_sta SPI_SLAVE[0x%08x]   count is %d\n\r",regvalue, ++intCounter);
      SPIIntClear(SpiNum_HSPI);
      SET_PERI_REG_MASK(SPI_SLAVE(SpiNum_HSPI), SPI_SYNC_RESET);
      SPIIntClear(SpiNum_HSPI);
      SPIIntEnable(SpiNum_HSPI,    SpiIntSrc_WrStaDone
                           | SpiIntSrc_RdStaDone
                           | SpiIntSrc_WrBufDone
                           | SpiIntSrc_RdBufDone);
      if (regvalue & SPI_SLV_WR_BUF_DONE)
      {
         // User can get data from the W0~W7
         os_printf("spi_slave_isr_sta : SPI_SLV_WR_BUF_DONE\n\r");

         idx=0;
         while(idx<8)   //取8次,每次取出一个32位数,共取出32*8=256位,也即32个字节
         {
            recv_data=READ_PERI_REG(SPI_W0(HSPI)+(idx<<2));
            spi_data[idx<<2] = recv_data&0xff;
            spi_data[(idx<<2)+1] = (recv_data>>8)&0xff;
            spi_data[(idx<<2)+2] = (recv_data>>16)&0xff;
            spi_data[(idx<<2)+3] = (recv_data>>24)&0xff;
            idx++;
         }
         os_printf("data: \n\r");
         for(i=0;i<32;i++)
         {
            os_printf("%02X ",spi_data[i]);
         }
         os_printf("\r\n");
      }
      else if (regvalue & SPI_SLV_RD_BUF_DONE)
      {
         // TO DO
         os_printf("spi_slave_isr_sta : SPI_SLV_RD_BUF_DONE\n\r");
      }
      if (regvalue & SPI_SLV_RD_STA_DONE)
      {
         statusR = READ_PERI_REG(SPI_RD_STATUS(SpiNum_HSPI));
         statusW = READ_PERI_REG(SPI_WR_STATUS(SpiNum_HSPI));
         os_printf("spi_slave_isr_sta : SPI_SLV_RD_STA_DONE[R=0x%08x,W=0x%08x]\n\r", statusR,statusW);
      }
      if (regvalue & SPI_SLV_WR_STA_DONE)
      {
         statusR = READ_PERI_REG(SPI_RD_STATUS(SpiNum_HSPI));
         statusW = READ_PERI_REG(SPI_WR_STATUS(SpiNum_HSPI));
         os_printf("spi_slave_isr_sta : SPI_SLV_WR_STA_DONE[R=0x%08x,W=0x%08x]\n\r", statusR,statusW);
      }
      if ((regvalue & SPI_TRANS_DONE) && ((regvalue & 0xf) == 0))
      {
         os_printf("spi_slave_isr_sta : SPI_TRANS_DONE\n\r");
      }
         //SHOWSPIREG(SpiNum_HSPI);
   }
}

void ICACHE_FLASH_ATTR spi_slave_test()
{
   // SPI initialization configuration, speed = 0 in slave mode
   SpiAttr hSpiAttr;
   hSpiAttr.bitOrder = SpiBitOrder_MSBFirst;
   hSpiAttr.speed = 0;
   hSpiAttr.mode = SpiMode_Slave;
   hSpiAttr.subMode = SpiSubMode_0;
   // Init HSPI GPIO
   // Configure MUX to allow HSPI
   WRITE_PERI_REG(PERIPHS_IO_MUX, 0x105);
   PIN_FUNC_SELECT(PERIPHS_IO_MUX_MTDI_U, 2);//configure io to spi mode
   PIN_FUNC_SELECT(PERIPHS_IO_MUX_MTCK_U, 2);//configure io to spi mode
   PIN_FUNC_SELECT(PERIPHS_IO_MUX_MTMS_U, 2);//configure io to spi mode
   PIN_FUNC_SELECT(PERIPHS_IO_MUX_MTDO_U, 2);//configure io to spi mode
   os_printf("\r\n ============= spi init slave =============\r\n");
   SPIInit(SpiNum_HSPI, &hSpiAttr);
   // Set spi interrupt information.
   SpiIntInfo spiInt;
   spiInt.src = (SpiIntSrc_TransDone
   | SpiIntSrc_WrStaDone
   |SpiIntSrc_RdStaDone
   |SpiIntSrc_WrBufDone
   |SpiIntSrc_RdBufDone);
   spiInt.isrFunc = spi_slave_isr_sta;
   SPIIntCfg(SpiNum_HSPI, &spiInt);
   // SHOWSPIREG(SpiNum_HSPI);
   SPISlaveRecvData(SpiNum_HSPI);
   uint32_t sndData[8] = { 0 };
   sndData[0] = 0x35343332;
   sndData[1] = 0x39383736;
   sndData[2] = 0x3d3c3b3a;
   sndData[3] = 0x11103f3e;
   sndData[4] = 0x15141312;
   sndData[5] = 0x19181716;
   sndData[6] = 0x1d1c1b1a;
   sndData[7] = 0x21201f1e;
   // write 8 word (32 byte) data to SPI buffer W8~W15
   SPISlaveSendData(SpiNum_HSPI, sndData, 8);
   // set the value of status register
   WRITE_PERI_REG(SPI_RD_STATUS(SpiNum_HSPI), 0x8A);
   WRITE_PERI_REG(SPI_WR_STATUS(SpiNum_HSPI), 0x83);
}

/******************************************************************************
 * FunctionName : user_init
 * Description  : entry of user application, init user function here
 * Parameters   : none
 * Returns      : none
*******************************************************************************/
void ICACHE_FLASH_ATTR
user_init(void)
{
    os_printf("SDK version:%s\n", system_get_sdk_version());

   //spi_test_init();
   //spi_master_test();
   spi_slave_test();
}


上半部分是STM32打印的调试信息,可以看到数据读取是没有问题的,下半部分是ESP8266打印的调试信息,可以发现数据写入也是没有问题的
Image

但是,通过逻辑分析仪可以看到,ESP8266通过miso传送到STM32的数据出问题了,是在上升沿变化,且数据不正确
Image
Image

请问有朋友能帮我解答一下吗,谢谢

roc2
Posts: 12
Joined: Tue Oct 25, 2016 3:57 pm

Re: 请教,关于hspi做从机,MISO信号相位不对的问题

Postby roc2 » Mon Nov 07, 2016 7:47 pm

请问您为什么在两次发送间采用10ms延时呢?10ms延时是最佳延时时间吗?

roc2
Posts: 12
Joined: Tue Oct 25, 2016 3:57 pm

Re: 请教,关于hspi做从机,MISO信号相位不对的问题

Postby roc2 » Mon Nov 07, 2016 7:55 pm

请问您为何选择10ms延时?10ms延时是最佳延时时间吗?

Who is online

Users browsing this forum: No registered users and 59 guests