完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
我将ESP8266的HSPI配置为从机,然后连接到我的STM32单片机上,写入与读取数据都没有问题,但是,通过逻辑分析仪的观察,发现MISO信号是在上升沿变化的,且逻辑分析仪分析出的数据是错误的。
STM32上运行的是RT_Thread操作系统,不停的发送与读取数据。代码如下: 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("rnesp8266 write Buf is rn"); for (i = 0; i < 34; i++) { rt_kprintf("%02X ", esp8266_writeBuf); } } 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("rnesp8266 read Buf is rn"); for (i = 0; i < 34; i++) { rt_kprintf("%02X ", esp8266_readBuf); } } /******************************************************************************* * 函数名 : 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("rnspi_slave_isr_sta SPI_USER[0x%08x]nr",regvalue); regvalue = READ_PERI_REG(SPI_ADDR(SpiNum_HSPI)); os_printf("spi_slave_isr_sta SPI_ADDR[0x%08x]nr",regvalue); regvalue = READ_PERI_REG(SPI_CTRL(SpiNum_HSPI)); os_printf("spi_slave_isr_sta SPI_CTRL[0x%08x]nr",regvalue); regvalue = READ_PERI_REG(SPI_RD_STATUS(SpiNum_HSPI)); os_printf("spi_slave_isr_sta SPI_RD_STATUS[0x%08x]nr",regvalue); regvalue = READ_PERI_REG(SPI_WR_STATUS(SpiNum_HSPI)); os_printf("spi_slave_isr_sta SPI_WR_STATUS[0x%08x]nr",regvalue); */ regvalue = READ_PERI_REG(SPI_SLAVE(SpiNum_HSPI)); os_printf("rnspi_slave_isr_sta SPI_SLAVE[0x%08x] count is %dnr",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_DONEnr"); 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: nr"); for(i=0;i<32;i++) { os_printf("%02X ",spi_data); } os_printf("rn"); } else if (regvalue & SPI_SLV_RD_BUF_DONE) { // TO DO os_printf("spi_slave_isr_sta : SPI_SLV_RD_BUF_DONEnr"); } 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]nr", 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]nr", statusR,statusW); } if ((regvalue & SPI_TRANS_DONE) && ((regvalue & 0xf) == 0)) { os_printf("spi_slave_isr_sta : SPI_TRANS_DONEnr"); } //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("rn ============= spi init slave =============rn"); 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:%sn", system_get_sdk_version()); //spi_test_init(); //spi_master_test(); spi_slave_test(); } 上半部分是STM32打印的调试信息,可以看到数据读取是没有问题的,下半部分是ESP8266打印的调试信息,可以发现数据写入也是没有问题的 但是,通过逻辑分析仪可以看到,ESP8266通过miso传送到STM32的数据出问题了,是在上升沿变化,且数据不正确 请问有朋友能帮我解答一下吗,谢谢 |
|
相关推荐
1个回答
|
|
从您的描述来看,问题可能出在MISO信号的相位上。在SPI通信中,有两种数据传输模式:CPHA=0(数据在时钟的上升沿采样)和CPHA=1(数据在时钟的下降沿采样)。根据您的描述,MISO信号在上升沿变化,这可能是由于STM32和ESP8266之间的CPHA设置不一致导致的。
要解决这个问题,您可以尝试以下步骤: 1. 检查STM32和ESP8266的SPI配置。确保它们的CPHA设置相同。在STM32上,您可以在初始化SPI时设置CPHA: ```c SPI_InitStructure.SPI_CPHA = SPI_CPHA_1; ``` 在ESP8266上,您需要查找相应的SPI配置选项并进行设置。 2. 如果您已经确保了CPHA设置相同,但问题仍然存在,请检查SPI时钟极性(CPOL)。CPOL设置为0表示时钟空闲状态为低电平,设置为1表示时钟空闲状态为高电平。同样,确保STM32和ESP8266的CPOL设置相同。 3. 检查SPI速率(波特率)。确保STM32和ESP8266的SPI速率设置相同,以避免通信错误。 4. 如果以上步骤都无法解决问题,请尝试使用逻辑分析仪检查STM32和ESP8266之间的SPI信号,以确定问题出在哪个环节。 5. 如果问题仍然存在,您可以尝试在STM32上使用软件SPI,而不是硬件SPI,以获得更多的灵活性和控制。 希望这些建议能帮助您解决问题。如果问题仍然存在,请随时提供更多信息,以便我们能够更好地帮助您。 |
|
|
|
只有小组成员才能发言,加入小组>>
406浏览 6评论
338浏览 5评论
有没有办法在不使用混杂模式的情况下实现Wifi驱动程序接收缓冲区访问中断呢?
321浏览 5评论
322浏览 4评论
309浏览 4评论
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2024-8-16 08:12 , Processed in 0.843994 second(s), Total 75, Slave 62 queries .
Powered by 电子发烧友网
© 2015 www.ws-dc.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191 工商网监 湘ICP备2023018690号