完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
大家好,我在官方提供的ESP8266_NONOS_SDK V1.5.4中的AT工程基础上进行开发,我尝试使用esp8266的HSPI做为从机(Hspi slave)接收外部mcu发来的数据,但是在实现的过程中遇到一些问题。
我根据8J-ESP8266__SPI-WiFi_Passthrough_2-Interrupt_Mode__CN_v0.1.pdf文档中spi从机通信协议的说明,把外部mcu(spi 主机)设置成spi mode0,通信速率设置为500K,每次发送34个字节(命令0x02+地址0x00+32字节数据)。设置完成后,我通过逻辑分析仪捕获spi主机输出的波形,是我期望输出的波形。 然后,我在ESP8266程序里做了如下工作: 1.有用户程序初始化函数里初始化了spi从机。代码如下: void ICACHE_FLASH_ATTR user_init(void) { led_gpio_init(); user_link_led_timer_init(); at_init(); at_port_print("rnreadyrn"); spi_slave_init(HSPI, 32); } spi_slave_init函数内容是采用官方默认的,并没有做修改。 2.在spi的从机中断函数void spi_slave_isr_handler(void *para)中添加了一些打印语句,代码如下: void spi_slave_isr_handler(void *para) { uint32 regvalue,calvalue; static uint8 state =0; uint32 recv_data,send_data; os_printf("spi_slave_isrn"); if(READ_PERI_REG(0x3ff00020)&BIT4) { //following 3 lines is to clear isr signal CLEAR_PERI_REG_MASK(SPI_SLAVE(SPI), 0x3ff); } else if(READ_PERI_REG(0x3ff00020)&BIT7) { //bit7 is for hspi isr, os_printf("hspi ISRn"); regvalue=READ_PERI_REG(SPI_SLAVE(HSPI)); CLEAR_PERI_REG_MASK(SPI_SLAVE(HSPI),//关闭中断使能 SPI_TRANS_DONE_EN| SPI_SLV_WR_STA_DONE_EN| SPI_SLV_RD_STA_DONE_EN| SPI_SLV_WR_BUF_DONE_EN| SPI_SLV_RD_BUF_DONE_EN); SET_PERI_REG_MASK(SPI_SLAVE(HSPI), SPI_SYNC_RESET); CLEAR_PERI_REG_MASK(SPI_SLAVE(HSPI),//清中断标志 SPI_TRANS_DONE| SPI_SLV_WR_STA_DONE| SPI_SLV_RD_STA_DONE| SPI_SLV_WR_BUF_DONE| SPI_SLV_RD_BUF_DONE); SET_PERI_REG_MASK(SPI_SLAVE(HSPI), //中断使能 SPI_TRANS_DONE_EN| SPI_SLV_WR_STA_DONE_EN| SPI_SLV_RD_STA_DONE_EN| SPI_SLV_WR_BUF_DONE_EN| SPI_SLV_RD_BUF_DONE_EN); if(regvalue&SPI_TRANS_DONE)//传输完成? { os_printf("translate donen"); } if(regvalue&SPI_SLV_WR_BUF_DONE)//写从机buff完成? { os_printf("write buff donen"); GPIO_OUTPUT_SET(0, 0); //将寄存器接收数据搬入内存 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++; } //add system_os_post here GPIO_OUTPUT_SET(0, 1);//用于通知主机,数据已经读取完成 os_printf("receive finishn"); } if(regvalue&SPI_SLV_RD_BUF_DONE) { os_printf("read buff donen"); //it is necessary to call GPIO_OUTPUT_SET(2, 1), when new data is preped in SPI_W8-15 and needs to be sended. GPIO_OUTPUT_SET(2, 0); //add system_os_post here //system_os_post(USER_TASK_PRIO_1,WR_RD,regvalue); } } else if(READ_PERI_REG(0x3ff00020)&BIT9) { //bit7 is for i2s isr, os_printf("3n"); } } 在进行主机从机通信测试时,用主机一次发送34字节(命令0x02+地址0x00+32字节数据),结果发现os_printf("hspi ISRn");被执行了十几次(约12次,每次打印出的字符串条数有差异),也即 else if(READ_PERI_REG(0x3ff00020)&BIT7)判断条件被触发约12次,而每次对应 if(regvalue&SPI_TRANS_DONE)条件也均会满足,os_printf("translate donen");会执行并打印字符串。但是 if(regvalue&SPI_SLV_WR_BUF_DONE)条件总是不满足。当我尝试用主机发送读数据指令(0x03,0x00)时,得到的效果也如上所述,并不会触发if(regvalue&SPI_SLV_RD_BUF_DONE)。我尝试打印出regvalue的值,得到的结果为0x66f003f0,每次得到的结果不同,但是最后的三个数字总是3f0。 我现在的疑问是 1.主机一次发送34字节时,为什么会触发进入中断函数十几次,而不是一次,不是34次? 2.为什么SPI_SLV_WR_BUF_DONE和SPI_SLV_RD_BUF_DONE条件总是不被触发?是不是我哪里没有配置好,或者测试的方法有误? 另外,我尝试过用HSPI做为master主动往外发出数据,用逻辑分析仪观察波形,可以得到相应的波形,可以确定hspi的引脚是没有弄错的。 |
|
相关推荐
1个回答
|
|
在这种情况下,我建议您按照以下步骤进行操作:
1. 确保您的ESP8266硬件连接正确。检查HSPI的MISO、MOSI、CLK和CS引脚是否正确连接到外部MCU的相应引脚。 2. 在您的ESP8266程序中,确保您已经正确配置了HSPI接口。这包括设置SPI模式(在您的情况下是Mode 0)、通信速率(500Kbps)以及初始化HSPI接口。 3. 在您的程序中实现SPI从机接收数据的逻辑。这通常包括配置GPIO为输入模式,然后在SPI从机接收到数据时读取数据。您可以使用ESP8266的SPI接口库函数来实现这一点。 4. 在接收到数据后,您可以根据需要对数据进行处理。例如,您可以将接收到的数据存储在数组中,或者根据数据内容执行特定的操作。 5. 如果您在实现过程中遇到问题,可以尝试使用调试工具(如逻辑分析仪)来检查SPI通信是否正常。这可以帮助您确定问题是否出在硬件连接或软件实现上。 |
|
|
|
只有小组成员才能发言,加入小组>>
1014 浏览 1 评论
559浏览 6评论
466浏览 5评论
有没有办法在不使用混杂模式的情况下实现Wifi驱动程序接收缓冲区访问中断呢?
451浏览 5评论
451浏览 4评论
425浏览 4评论
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2024-12-2 02:55 , Processed in 0.683554 second(s), Total 50, Slave 43 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191 工商网监 湘ICP备2023018690号