我将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的数据出问题了,是在上升沿变化,且数据不正确
请问有朋友能帮我解答一下吗,谢谢