新手入门
- 积分
- 5
- 金钱
- 5
- 注册时间
- 2018-4-21
- 在线时间
- 0 小时
|
11金钱
学习spi好几天了但是 spi双机通讯一直没有调试好。 希望大神解救一下。
主机跟从机接收数据都出现了问题,主机一直接受的数据为0,而从机接收的不是从主机发出的数据。
代码有点多 STM32新手 真心求大家解答。谢谢大家了
原来的主机主函数里面的发送数据的这个函数while(SPI_I2S_GetFlagStatus(SPI2, SPI_I2S_FLAG_RXNE) ==RESET) 会一直循环在这个地方
在网上论坛有人说改成while(SPI_I2S_GetFlagStatus(SPI2, SPI_I2S_FLAG_BSY) == SET)这个 就可以解决 我感觉是这里出现了问题,但又不知道怎么解决。
时钟什么的都配置好了
[mw_shl_code=c,true]主机SPI配置
#include "spi.h"
#include "stm32f10x.h"
void Spi_Init()
{
//SPI_I2S_DeInit(SPI2);
GPIO_InitTypeDef GPIO_InitStruce;
SPI_InitTypeDef SPI_InitStruce;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE);
RCC_APB1PeriphClockCmd(RCC_APB1Periph_SPI2,ENABLE);
GPIO_InitStruce.GPIO_Mode=GPIO_Mode_AF_PP;
GPIO_InitStruce.GPIO_Pin=GPIO_Pin_13|GPIO_Pin_15; //SCLK MOSI推挽复用输出
GPIO_InitStruce.GPIO_Speed=GPIO_Speed_50MHz;
GPIO_Init(GPIOB,&GPIO_InitStruce);
// GPIO_InitStruce.GPIO_Mode= GPIO_Mode_Out_PP;
//GPIO_InitStruce.GPIO_Pin=GPIO_Pin_12; //CS片选信号
GPIO_Init(GPIOB,&GPIO_InitStruce);
GPIO_InitStruce.GPIO_Mode=GPIO_Mode_IN_FLOATING;
GPIO_InitStruce.GPIO_Pin=GPIO_Pin_14; //MISO浮动输入
GPIO_Init(GPIOB,&GPIO_InitStruce);
SPI_InitStruce.SPI_BaudRatePrescaler=SPI_BaudRatePrescaler_128;//波特率进行分频为2
SPI_InitStruce.SPI_CPHA=SPI_CPHA_2Edge;//在第二个跳边沿接收数据
SPI_InitStruce.SPI_CPOL=SPI_CPOL_High;//空闲时间时钟为高电平
SPI_InitStruce.SPI_CRCPolynomial=7; //?
SPI_InitStruce.SPI_DataSize=SPI_DataSize_8b;//选择为八位字节
SPI_InitStruce.SPI_Direction=SPI_Direction_2Lines_FullDuplex;//设置spi为双线全双工模式
SPI_InitStruce.SPI_FirstBit=SPI_FirstBit_MSB;//数据传输从MSB开始
SPI_InitStruce.SPI_Mode=SPI_Mode_Master;//设置为主机模式
SPI_InitStruce.SPI_NSS=SPI_NSS_Soft;//软件控制NSS(片选)信号
SPI_Init(SPI2,&SPI_InitStruce);
SPI_Cmd(SPI2,ENABLE);
}
void SPI2_SetSpeed(u8 SPI_BaudRatePrescaler)
{
assert_param(IS_SPI_BAUDRATE_PRESCALER(SPI_BaudRatePrescaler));
SPI2->CR1&=0XFFC7;
SPI2->CR1|=SPI_BaudRatePrescaler; //设置SPI2速度
SPI_Cmd(SPI2,ENABLE);
}
uint8_t SPI_WriteByte(uint8_t TxData)
{
while((SPI1->SR & SPI_I2S_FLAG_TXE) == (uint16_t)RESET);
SPI1->DR = TxData;
while((SPI1->SR & SPI_I2S_FLAG_RXNE) == (uint16_t)RESET);
return SPI1->DR;
}
uint8_t SPI_ReadByte(void)
{
while((SPI1->SR & SPI_I2S_FLAG_TXE) == (uint16_t)RESET);
SPI1->DR = 0xFF;
while((SPI1->SR & SPI_I2S_FLAG_RXNE) == (uint16_t)RESET);
return SPI1->DR;
}
主机main
#include "stm32f10x.h"
#include "SPI.h"
#include "usart.h"
#include "delay.h"
#include "sys.h"
#define buffersize 1
u8 SPI2_buffer_TX[buffersize]=
{
0X10
};
u8 SPI2_buffer_RX[buffersize];
u8 TX_Counter=0;
u8 RX_Counter=0;
u8 k=0;
u8 i=0;
int main(void)
{
u8 SPI1_RXNE=0;
u8 SPI1_TXE=0;
delay_init();
uart_init(9600);
Spi_Init();
while(TX_Counter<buffersize)
{
while (SPI_I2S_GetFlagStatus(SPI2, SPI_I2S_FLAG_TXE) ==RESET) //检查指定的SPI标志位设置与否:发送缓存空标志位
SPI_I2S_SendData(SPI2, SPI2_buffer_TX[TX_Counter]); //通过外设SPIx发送一个数据
while(SPI_I2S_GetFlagStatus(SPI2, SPI_I2S_FLAG_BSY) == SET);//检查指定的SPI标志位设置与否:接受缓存非空标志位
//返回通过SPIx最近接收的数据
TX_Counter++;
RX_Counter++;
SPI2_buffer_RX[RX_Counter]=SPI_I2S_ReceiveData(SPI2);
}
printf("\r\n 主机输出数据如下:\r\n");
while(i<buffersize)
{
printf(" %2d \r\n ",SPI2_buffer_TX);
i++;
}
printf("\r\n SPI1 主机收到数据如下:\r\n");
while(k<buffersize)
{
printf(" %2d \r\n ",SPI2_buffer_RX[k]);
k++;
}
while(1);
}
[/mw_shl_code]
[mw_shl_code=c,true]从机SPI配置
#include "spi.h"
#include "stm32f10x.h"
void Spi_Init()
{
GPIO_InitTypeDef GPIO_InitStruce;
SPI_InitTypeDef SPI_InitStruce;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE);
RCC_APB1PeriphClockCmd(RCC_APB1Periph_SPI2,ENABLE);
GPIO_InitStruce.GPIO_Mode=GPIO_Mode_IN_FLOATING;
GPIO_InitStruce.GPIO_Pin=GPIO_Pin_13; //SCLK MISO推挽复用输出
GPIO_InitStruce.GPIO_Speed=GPIO_Speed_50MHz;
GPIO_Init(GPIOB,&GPIO_InitStruce);
GPIO_InitStruce.GPIO_Mode=GPIO_Mode_AF_PP;
GPIO_InitStruce.GPIO_Pin=GPIO_Pin_14; //MISO复用推挽
GPIO_Init(GPIOB,&GPIO_InitStruce);
GPIO_InitStruce.GPIO_Mode=GPIO_Mode_IN_FLOATING;
GPIO_InitStruce.GPIO_Pin=GPIO_Pin_15; //MOSI浮动输入
GPIO_Init(GPIOB,&GPIO_InitStruce);
SPI_InitStruce.SPI_BaudRatePrescaler=SPI_BaudRatePrescaler_128;//波特率进行分频为2
SPI_InitStruce.SPI_CPHA=SPI_CPHA_2Edge;//在第二个跳边沿接收数据
SPI_InitStruce.SPI_CPOL=SPI_CPOL_Low;//空闲时间时钟为高电平
SPI_InitStruce.SPI_CRCPolynomial=7; //?
SPI_InitStruce.SPI_DataSize=SPI_DataSize_8b;//选择为八位字节
SPI_InitStruce.SPI_Direction=SPI_Direction_1Line_Rx;//设置spi为双线全双工模式
SPI_InitStruce.SPI_FirstBit=SPI_FirstBit_MSB;//数据传输从MSB开始
SPI_InitStruce.SPI_Mode=SPI_Mode_Slave;//设置为从机模式
SPI_InitStruce.SPI_NSS=SPI_NSS_Soft;//软件控制NSS(片选)信号
SPI_Init(SPI2,&SPI_InitStruce);
SPI_Cmd(SPI2,ENABLE);
SPI_I2S_ITConfig(SPI2, SPI_I2S_IT_RXNE, ENABLE);
}
/*void SPI2_SetSpeed(u8 SPI_BaudRatePrescaler)
{
assert_param(IS_SPI_BAUDRATE_PRESCALER(SPI_BaudRatePrescaler));
SPI2->CR1&=0XFFC7;
SPI2->CR1|=SPI_BaudRatePrescaler; //设置SPI2速度
SPI_Cmd(SPI2,ENABLE);
} */
uint8_t SPI_WriteReadByte(uint8_t TxData)
{
while((SPI1->SR & SPI_I2S_FLAG_TXE) == (uint16_t)RESET);
SPI1->DR = TxData;
while((SPI1->SR & SPI_I2S_FLAG_RXNE) == (uint16_t)RESET);
return SPI1->DR;
}
从机main
#include "stm32f10x.h"
#include "SPI.h"
#include "usart.h"
#include "delay.h"
#include "sys.h"
#define buffersize 1
u8 SPI2_buffer_TX[buffersize]=
{
0X11
};
u8 SPI_buffer_RX[buffersize]={0};
u8 TX_Counter=0;
u8 RX_Counter=0;
u8 k=0;
u8 i=0;
int main(void)
{
u8 SPI2_RXNE=0;
delay_init();
uart_init(9600);
Spi_Init();
while(TX_Counter<buffersize)
{
while (SPI_I2S_GetFlagStatus(SPI2, SPI_I2S_FLAG_TXE) == RESET); //检查指定的SPI标志位设置与否:发送缓存空标志位
SPI_I2S_SendData(SPI2, SPI2_buffer_TX[TX_Counter]); //通过外设SPIx发送一个数据
while(SPI_I2S_GetFlagStatus(SPI2, SPI_I2S_FLAG_RXNE )== RESET); //检查指定的SPI标志位设置与否:接受缓存非空标志位
SPI_buffer_RX[RX_Counter]=SPI_I2S_ReceiveData(SPI2);
TX_Counter++;
RX_Counter++;
}
printf("\r\n SPI2 输出数据如下:\r\n");
while(i<buffersize)
{
printf(" %2d \r\n ",SPI2_buffer_TX);
i++;
}
printf("\r\n SPI2 收到数据如下:\r\n");
while(k<buffersize)
{
printf(" %2d \r\n ",SPI_buffer_RX[k]);
k++;
}
while(1);
}
[/mw_shl_code]
|
|