用的标准库。
问题1、硬件设计是否有问题?连线如图1所示:
问题2、NSS这根数据线的电平信号在数据传输的过程中需要设置嘛?主从都设计成SPI_NSS_Soft 软件模式。在各大论坛上看到的这个实验,主从配置没有什么区别,关键是主程序的读数据和写数据。以下是配置文件和主程序。这配置是否有问题?主程序能不能这样写?
主从都是SPI2.
主机配置:
- void SPI2_Init(void)
- {
- SPI_Cmd(SPI2, DISABLE);
- GPIO_InitTypeDef GPIO_InitStructure;
- SPI_InitTypeDef SPI2_InitStructure;
- RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB, ENABLE);//ê1ÄüGPIODê±Öó
- RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOD, ENABLE);//ê1ÄüGPIOBê±Öó
- SPI_I2S_DeInit(SPI2);
- //GPIOs initialize
- GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9|GPIO_Pin_14| GPIO_Pin_15;//PB3~5¸′óÃ1|Äüêä3ö
- GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;//¸′óÃ1|Äü
- GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;//íÆíìêä3ö
- GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;//100MHz
- GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;//éÏà-
- GPIO_Init(GPIOB, &GPIO_InitStructure);//3õê¼»ˉ
- GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3;//Master CLK_Pin
- GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;//ÆÕí¨êä3öÄ£ê½
- GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;//íÆíìêä3ö
- GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
- GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;//éÏà-
- GPIO_Init(GPIOD, &GPIO_InitStructure);//3õê¼»ˉGPIO
- //GPIO AF
- GPIO_PinAFConfig(GPIOB,GPIO_PinSource9,GPIO_AF_SPI2);
- GPIO_PinAFConfig(GPIOB,GPIO_PinSource14,GPIO_AF_SPI2);
- GPIO_PinAFConfig(GPIOB,GPIO_PinSource15,GPIO_AF_SPI2);
- GPIO_PinAFConfig(GPIOD,GPIO_PinSource3,GPIO_AF_SPI2);
- GPIO_SetBits(GPIOB,GPIO_Pin_9|GPIO_Pin_14| GPIO_Pin_15);
- GPIO_SetBits(GPIOD,GPIO_Pin_3); //3õê¼»ˉà-¸ßμçƽ
- RCC_APB1PeriphClockCmd(RCC_APB1Periph_SPI2, ENABLE);//ê1ÄüSPI2ê±Öó
- SPI2_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex; //éèÖÃSPIμ¥Ïò»òÕßË«ÏòμÄêy¾YÄ£ê½:SPIéèÖÃÎaË«ÏßË«Ïòè«Ë«1¤
- SPI2_InitStructure.SPI_Mode = SPI_Mode_Master; //éèÖÃSPI1¤×÷Ä£ê½:éèÖÃÎaÖ÷SPI
- SPI2_InitStructure.SPI_DataSize = SPI_DataSize_8b; //éèÖÃSPIμÄêy¾Y′óD¡:SPI·¢Ëí½óêÕ8λ֡½á11
- SPI2_InitStructure.SPI_CPOL = SPI_CPOL_Low; //′®DDí¬2½ê±ÖóμÄ¿ÕÏD×′ì¬μíμçƽ
- SPI2_InitStructure.SPI_CPHA = SPI_CPHA_2Edge; //′®DDí¬2½ê±ÖóμÄμú¶t¸öìø±äÑØ£¨éÏéy»òϽ죩êy¾Y±»2éÑù
- SPI2_InitStructure.SPI_NSS = SPI_NSS_Soft; //NSSDÅoÅóéó2¼t£¨NSS1ü½Å£©»1êÇèí¼t£¨ê1óÃSSI룩1üàí:Äú2¿NSSDÅoÅóDSSIλ¿ØÖÆ
- SPI2_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_64; //¶¨òå2¨ìØÂêÔ¤·ÖÆμμÄÖμ:2¨ìØÂêÔ¤·ÖÆμÖμÎa256
- SPI2_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB; //Ö¸¶¨êy¾Y′«êä′óMSBλ»1êÇLSBλ¿aê¼:êy¾Y′«êä′óMSBλ¿aê¼
- SPI2_InitStructure.SPI_CRCPolynomial = 7; //CRCÖμ¼ÆËãμĶàÏîê½
- SPI_Init(SPI2, &SPI2_InitStructure); //¸ù¾YSPI_InitStructÖDÖ¸¶¨μÄ2Îêy3õê¼»ˉíaéèSPIx¼Ä′æÆ÷
- SPI_Cmd(SPI2, ENABLE); //ê1ÄüSPIíaéè
- // SPI2_ReadWriteByte(0xff);//Æô¶ˉ′«ê䣬¿éòa¿é2»òa
- }
复制代码
从机配置
- void SPI2_Init(void)
- {
- SPI_Cmd(SPI2, DISABLE);
- GPIO_InitTypeDef GPIO_InitStructure;
- SPI_InitTypeDef SPI2_InitStructure;
-
- RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB, ENABLE);//ê1ÄüGPIODê±Öó
-
- //GPIOs initialize
- GPIO_InitStructure.GPIO_Pin = GPIO_Pin_14| GPIO_Pin_15|GPIO_Pin_13;
- GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;//
- GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;//íÆíìêä3ö
- GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;//100MHz
- GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;//éÏà-
- GPIO_Init(GPIOB, &GPIO_InitStructure);//3õê¼»ˉ
-
- GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12;// NSS
- GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN;//êäèë
- // GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;//íÆíìêä3ö
- GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
- GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;//éÏà-
- GPIO_Init(GPIOB, &GPIO_InitStructure);//3õê¼»ˉGPIO
- //GPIO AF
- GPIO_PinAFConfig(GPIOB,GPIO_PinSource12|GPIO_PinSource14|GPIO_PinSource15|GPIO_PinSource13,GPIO_AF_SPI2);
-
- //ÕaàïÖ»Õë¶ÔSPI¿ú3õê¼»ˉ
- RCC_APB1PeriphClockCmd(RCC_APB1Periph_SPI2, ENABLE);//ê1ÄüSPI2ê±Öó
- SPI2_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex; //éèÖÃSPIμ¥Ïò»òÕßË«ÏòμÄêy¾YÄ£ê½:SPIéèÖÃÎaË«ÏßË«Ïòè«Ë«1¤
- SPI2_InitStructure.SPI_Mode = SPI_Mode_Slave; //éèÖÃSPI1¤×÷Ä£ê½:éèÖÃÎaÖ÷SPI
- SPI2_InitStructure.SPI_DataSize = SPI_DataSize_8b; //éèÖÃSPIμÄêy¾Y′óD¡:SPI·¢Ëí½óêÕ8λ֡½á11
- SPI2_InitStructure.SPI_CPOL = SPI_CPOL_Low; //′®DDí¬2½ê±ÖóμÄ¿ÕÏD×′ì¬Îa¸ßμçƽ
- SPI2_InitStructure.SPI_CPHA = SPI_CPHA_2Edge; //′®DDí¬2½ê±ÖóμÄμú¶t¸öìø±äÑØ£¨éÏéy»òϽ죩êy¾Y±»2éÑù
- SPI2_InitStructure.SPI_NSS = SPI_NSS_Soft; //NSSDÅoÅóéó2¼t£¨NSS1ü½Å£©»1êÇèí¼t£¨ê1óÃSSI룩1üàí:Äú2¿NSSDÅoÅóDSSIλ¿ØÖÆ
- SPI2_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_64; //¶¨òå2¨ìØÂêÔ¤·ÖÆμμÄÖμ:2¨ìØÂêÔ¤·ÖÆμÖμÎa256
- SPI2_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB; //Ö¸¶¨êy¾Y′«êä′óMSBλ»1êÇLSBλ¿aê¼:êy¾Y′«êä′óMSBλ¿aê¼
- SPI2_InitStructure.SPI_CRCPolynomial = 7; //CRCÖμ¼ÆËãμĶàÏîê½
-
- SPI_Init(SPI2, &SPI2_InitStructure); //¸ù¾YSPI_InitStructÖDÖ¸¶¨μÄ2Îêy3õê¼»ˉíaéèSPIx¼Ä′æÆ÷
- SPI_Cmd(SPI2, ENABLE); //ê1ÄüSPIíaéè
- }
复制代码
主机的主程序
- int main(void)
- {
- SPI2_Init();
- while(1)
- {
- for( i=0;i<4;i++)
- {
- while(SPI_I2S_GetFlagStatus(SPI2,SPI_I2S_FLAG_TXE)==RESET)
- {
- retry++;
- if (retry>200)
- {
- return 0;
- }
- }
- SPI_I2S_SendData(SPI2,txbuffer[i]);
- while(SPI_I2S_GetFlagStatus(SPI2,SPI_I2S_FLAG_RXNE)==RESET)
- {
- retry++;
- if (retry>200)
- {
- return 0;
- }
- }
- SPI_I2S_ReceiveData(SPI2);
- }
- }
- }
复制代码从机的主程序
- int main(void)
- {
- Uart3_init(115200);
- SPI2_Init();
- printf(" %x
",rxbuffer[0]);
- while(1)
- {
- for(int i=0;i<4;i++)
- {
- while(SPI_I2S_GetFlagStatus(SPI2,SPI_I2S_FLAG_RXNE)==RESET){}
- rxbuffer[i]=SPI_I2S_ReceiveData(SPI2);
- while(SPI_I2S_GetFlagStatus(SPI2,SPI_I2S_FLAG_TXE)==RESET){}
- SPI_SendData(SPI2,0x11);
- }
- for(int i=0;i<4;i++)
- {
- printf(" %x
",rxbuffer[i]);
- }
-
- }
- }
复制代码问题3、在debug主机的过程中,只要执行SPI_I2S_SendData(SPI2,txbuffer
);这么一句话,MOSI和SCK数据线,用示波器测量,可以得到正确的数据波形图和时钟信号波形图,但是测试MISO数据线上的话,永远都是高电平,得出从器件的问题。但是不知道哪里问题。
问题4、看完SPI的原理后,最主要是:主器件发起数据的传输,然后从器件同时往miso信号线上发送数据,但是不太明白在程序里面如何体现出这个循环移位过程。我这个是属于查询的方式,中断也尝试过,中断模仿的是原子论坛里面的一个精帖。但是仍然不通。
论坛的各位带哥帮忙看看。
一周热门 更多>