本帖最后由 okwh 于 2016-2-18 12:22 编辑
兆易创新GD32Colibri-F207ZE评估板体验纪实 (五、曙光) 25_okwh@https://www.cirmall.com/gd32f2mcu 2015.12.24
调试SPI的诡异现象 1)SPI 1 CLK/MISO/MOSI对应PA-5/6/7, 似乎三线的GPIO_Mode全部设为GPIO_MODE_AF_PP, 或把MISO设为GPIO_MODE_IN_FLOATING均可工作。搜索网上资料似乎两种代码都有,GD32-Colibri-F207ZE-DEMO\Colibri_GD32F207\firmware\GD32F20x_Firmware_Library\Example\SPI的代码使用后一种(说明书表5-5似乎也是这一种),本人对管脚配置理解不足,无从评价。(还需要学习推挽、浮空、上拉、下拉、开漏、普通IO都是什么呀,非科班的悲哀呀)
2)众所周知,SPI的读写基本代码为: while((SPIx->STR&I2S_FLAG_TBE)==RESET); //等待可发送 SPIx->DTR=Byte; //发送一字节 while((SPIx->STR&I2S_FLAG_RBNE)==RESET); //等待接收完成 returnSPIx->DTR; //读接收结果 结果在单步调试时,在同时显示sysytem viewwindow—SPI窗口时,可看到STR寄存器RBNE位为1, 代码读STR却为2(如下图RBNE是STR的0位, TBE是1位,有接收时STR应该是3),这怎么可能,百思不解啊!!!!
后来关闭sysytem viewwindow—SPI窗口,即可正常读出STR为3 !!!(下图)
My GOD !!!! 请教,这是Keil uVision的问题吗????
3) 以前发现的时有时无诡异现象有:调试状态时,call-stack窗口中局部变量得不到值、鼠标停留在某变量得不到变量值、watch窗口中的变量得不到值,唉,调试呀,这叫什么事呢………
没办法,俺没足够的经验,这还是首次用uVision真正地做。
4)在用SPI做我计划的ADDA控制之前,先来熟悉验证一下下小红板的SPI操作 修改使用例子中的GD32-Colibri-F207ZE-DEMO\Colibri_GD32F207\firmware\GD32F20x_Firmware_Library\Example\SPI\SPI_FullDuplex_CRC,进行SPI和SPI3的通讯。这例子来自GDM3209xx-EVAL板,并没有针对小红板做修正。 分析手册、原理图、小红板,确定SPI1对应SCK/MISO/MOSI是PA5/6/7,SPI3对应是PB3/4/5,如图:
原代码是以SPI1为主,SPI3为从,二者连接进行全双工通讯。很遗憾,这样配置,我的测试结果是可以发送而接收失败,似乎是SPI3为从时,发送线一直为高不变,不送回数据,原因不明。 我的试验验证结果: (1) 两个分别单独为主时,均可正常发送。(2) 以SPI3为主,SPI1为从,可以正常发送接收。 (3) SPI1为主,SPI3为从,通讯失败,表现为SPI3从的发送线一直为高不变,不送数。 检查手段:示波器。
成功代码如下: - (注意接线: SPI3主,SPI1从,CLK-CLK,MOSI-MOSI,MISO-MISO !!!!)
- /* Private variables -----------------------*/
- uint8_t SPI1_Buffer_Tx[ BufferSize ] = {0xA1, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6, 0xA7, 0xA8, 0xA9, 0xAA };
- uint8_t SPI3_Buffer_Tx[ BufferSize ] = {0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5A };
- uint8_t SPI1_Buffer_Rx[ BufferSize ], SPI3_Buffer_Rx[ BufferSize ];
- uint32_t TxIdx = 0, RxIdx = 0;
- …………………………………………
- /* Enable Peripheral clock */ 配置IO
- RCC_APB2PeriphClock_Enable( RCC_APB2PERIPH_GPIOA | RCC_APB2PERIPH_GPIOB | RCC_APB2PERIPH_GPIOC| RCC_APB2PERIPH_AF , ENABLE);
- RCC_APB2PeriphClock_Enable(RCC_APB2PERIPH_SPI1,ENABLE);
- RCC_APB1PeriphClock_Enable(RCC_APB1PERIPH_SPI3,ENABLE);
- /* 从 Confugure SCK and MOSI pins as Input Floating */
- GPIO_InitStructure.GPIO_Pin = GPIO_PIN_5 | GPIO_PIN_7 ;
- GPIO_InitStructure.GPIO_Speed = GPIO_SPEED_50MHZ;
- GPIO_InitStructure.GPIO_Mode = GPIO_MODE_IN_FLOATING; //从SCK MO 浮空输入
- /* 从 Confugure MISO pin as Alternate Function Push Pull */
- GPIO_Init(GPIOA, &GPIO_InitStructure);
- GPIO_InitStructure.GPIO_Pin = GPIO_PIN_6;
- GPIO_InitStructure.GPIO_Mode = GPIO_MODE_AF_PP; // 从 MI 备用推挽
- GPIO_Init(GPIOA, &GPIO_InitStructure);
-
- /* Configure SPI3 pins: SCK, MISO and MOSI ----*/
- //GD32-Colibri-F207ZE 板 SPI3使用 PB 3/5/4
- /* Confugure SCK and MOSI pins as Alternate Function Push Pull | GPIO_PIN_6*/
- GPIO_InitStructure.GPIO_Pin = GPIO_PIN_3 | GPIO_PIN_5 ;//| GPIO_PIN_4;
- GPIO_InitStructure.GPIO_Speed = GPIO_SPEED_50MHZ;
- GPIO_InitStructure.GPIO_Mode = GPIO_MODE_AF_PP; // 主SCK MO 备用推挽
- GPIO_Init(GPIOB, &GPIO_InitStructure);
- /* Confugure MISO pin as Input Floating */
- GPIO_InitStructure.GPIO_Pin = GPIO_PIN_4;
- GPIO_InitStructure.GPIO_Mode = GPIO_MODE_IN_FLOATING; //主MI 浮空输入
- GPIO_Init(GPIOB, &GPIO_InitStructure);
-
-
- /* SPI1 configuration -----从-------*/ 配置SPI
- SPI_InitStructure.SPI_TransType = SPI_TRANSTYPE_FULLDUPLEX ;
- SPI_InitStructure.SPI_Mode = SPI_MODE_SLAVE; //SPI_MODE_MASTER; //从
- SPI_InitStructure.SPI_FrameFormat = SPI_FRAMEFORMAT_8BIT ;
- SPI_InitStructure.SPI_SCKPL = SPI_SCKPL_LOW;
- SPI_InitStructure.SPI_SCKPH = SPI_SCKPH_2EDGE;
- SPI_InitStructure.SPI_SWNSSEN = SPI_SWNSS_SOFT; ///NSS不用
- SPI_InitStructure.SPI_PSC = SPI_PSC_64; //分频
- SPI_InitStructure.SPI_FirstBit = SPI_FIRSTBIT_MSB;
- SPI_InitStructure.SPI_CRCPOL = 7; //CRC
- SPI_Init(SPI1, &SPI_InitStructure);
- /* SPI3 configuration ----------主-------*/
- SPI_InitStructure.SPI_PSC = SPI_PSC_32; //分频
- SPI_InitStructure.SPI_Mode = SPI_MODE_MASTER;//PI_MODE_SLAVE;
- SPI_Init(SPI3, &SPI_InitStructure);
- /* DisEnable SPI AND SPI3 CRC calculation */
- // SPI_CRC_Enable(SPI1, ENABLE);
- // SPI_CRC_Enable(SPI3, ENABLE);
- SPI_CRC_Enable(SPI1, DISABLE);
- SPI_CRC_Enable(SPI3, DISABLE);
- /* Enable SPI1 AND SPI3 */
- SPI_Enable(SPI1, ENABLE);
- SPI_Enable(SPI3, ENABLE);
-
- /* 开始全双工循环通讯 以便示波器测定 Transfer procedure */
- while (1) //TxIdx < BufferSize - 1)
- {
- while (SPI_I2S_GetBitState(SPI1, SPI_FLAG_TBE) == RESET){__NOP;}
- SPI_I2S_SendData(SPI1, SPI1_Buffer_Tx[ TxIdx ]);
- SPI_I2S_SendData(SPI3, SPI3_Buffer_Tx[ TxIdx++ ] );
- while (SPI_I2S_GetBitState(SPI1, SPI_FLAG_RBNE) == RESET);
- SPI1_Buffer_Rx[ RxIdx ] = SPI_I2S_ReceiveData( SPI1 );
- while (SPI_I2S_GetBitState(SPI3, SPI_FLAG_RBNE) == RESET){__NOP;}
- SPI3_Buffer_Rx[ RxIdx++ ] = SPI_I2S_ReceiveData( SPI3 );
- if (TxIdx == BufferSize)
- { TxIdx=0; RxIdx=0; }
- }
复制代码结果如下简易示波器截图:图中绿色为CLK信号。 SPI1 发送的0xA8 0xA9 0xAA
SPI3 发送的0x52 0x53 0x54
OK, 下次就可以正式做ADDA了。真不容易啊!
本系列:
兆易创新GD32 Colibri-F207ZE评估板体验纪实 (一、邂逅)
兆易创新GD32 Colibri-F207ZE评估板体验纪实 (二、初识)
兆易创新GD32 Colibri-F207ZE评估板体验纪实 (三、定计)
兆易创新GD32 Colibri-F207ZE评估板体验纪实 (四、筑基)
兆易创新GD32 Colibri-F207ZE评估板体验纪实 (五、曙光)
兆易创新GD32 Colibri-F207ZE评估板体验纪实 (六、揭秘)
兆易创新GD32 Colibri-F207ZE评估板体验纪实 (七、回眸)
|