关于FPGA和STM32通过SPI通信的问题
时间:10-02
整理:3721RD
点击:
我用stm32 当主机,FPGA为从机进行通信,每次发送16bit数据,目前stm32接收到的数据只有高8为准确,而低8位一直在变化,FPGA接收到的数据则不准确。spi时钟目前256分频,快一点数据就更加不对了。代码如下:
FPGA部分:
entity FPGA_ARM is
generic ( N : integer := 16);
Port ( CLK : in STD_LOGIC;
F_SCLK : in STD_LOGIC;
F_SC : in STD_LOGIC;
F_MOSI : in STD_LOGIC;
F_MISO : out STD_LOGIC;
Rcv_Flag : out STD_LOGIC;
Send_Data : in STD_LOGIC_VECTOR(15 downto 0);
Rcv_Data : out STD_LOGIC_VECTOR(15 downto 0));
end FPGA_ARM;
architecture Behavioral of FPGA_ARM is
signal cur_bit, prev_bit : integer range N-1 downto 0;
begin
process(F_SC,F_SCLK)
begin
if falling_edge(F_SCLK) then
case Send_Data(cur_bit) is
when '0' => F_MISO F_MISO NULL;
end case;
end if;
end process;
process(F_SCLK, F_SC)
begin
if F_SC = '1' then
Rcv_Data '0');
cur_bit Rcv_Data(cur_bit) Rcv_Data(cur_bit) NULL;
end case;
Rcv_Data(cur_bit) <= F_MOSI;
if cur_bit = 0 then cur_bit <= N - 1
else cur_bit <= cur_bit - 1;
end if;
end if;
end if;
end process;
process(CLK, F_SC)
variable td_raised : boolean;
begin
if F_SC = '1' then
prev_bit <= N-1;
td_raised := false;
Rcv_Flag <= '1';
elsif F_SC ='0' then
Rcv_Flag <= '0';
elsif falling_edge(CLK) then
prev_bit <= cur_bit;
if td_raised then
--Rcv_Flag <= '0';
td_raised := false;
elsif prev_bit = 0 and cur_bit = N-1 then
--Rcv_Flag <= '1';
td_raised := true;
end if;
end if;
end process;
stm32部分:
void SPI1_Configuration(void)
{
SPI_InitTypeDef SPI_InitStructure;
SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex;
SPI_InitStructure.SPI_Mode = SPI_Mode_Master;
SPI_InitStructure.SPI_DataSize = SPI_DataSize_16b;
SPI_InitStructure.SPI_CPOL = SPI_CPOL_Low;
SPI_InitStructure.SPI_CPHA = SPI_CPHA_1Edge;
SPI_InitStructure.SPI_NSS = SPI_NSS_Soft;
SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_256;
SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB;
SPI_InitStructure.SPI_CRCPolynomial = 7;
SPI_Init(SPI1, &SPI_InitStructure);
/* Enable SPI1 */
SPI_Cmd(SPI1, ENABLE);
}
void SPI1_Send(uint16_t data)
{
SPI1_NSS_L;
while (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_TXE) == RESET);
SPI_I2S_SendData(SPI1, data);
Delay(5);
while((SPI_I2S_GetFlagStatus(SPI1,SPI_I2S_FLAG_RXNE) == RESET));
SPI_I2S_ClearFlag(SPI2, SPI_I2S_FLAG_RXNE);
SPI1_NSS_H;
}
void main()
{
while(1)
{
SPI1_Send(0x4546);
m = SPI_I2S_ReceiveData(SPI1);
SPI1_RX_Buff[i] = m;
if (i==1)i=0;
else i++;
Delay(20);
}
}
FPGA部分:
entity FPGA_ARM is
generic ( N : integer := 16);
Port ( CLK : in STD_LOGIC;
F_SCLK : in STD_LOGIC;
F_SC : in STD_LOGIC;
F_MOSI : in STD_LOGIC;
F_MISO : out STD_LOGIC;
Rcv_Flag : out STD_LOGIC;
Send_Data : in STD_LOGIC_VECTOR(15 downto 0);
Rcv_Data : out STD_LOGIC_VECTOR(15 downto 0));
end FPGA_ARM;
architecture Behavioral of FPGA_ARM is
signal cur_bit, prev_bit : integer range N-1 downto 0;
begin
process(F_SC,F_SCLK)
begin
if falling_edge(F_SCLK) then
case Send_Data(cur_bit) is
when '0' => F_MISO F_MISO NULL;
end case;
end if;
end process;
process(F_SCLK, F_SC)
begin
if F_SC = '1' then
Rcv_Data '0');
cur_bit Rcv_Data(cur_bit) Rcv_Data(cur_bit) NULL;
end case;
Rcv_Data(cur_bit) <= F_MOSI;
if cur_bit = 0 then cur_bit <= N - 1
else cur_bit <= cur_bit - 1;
end if;
end if;
end if;
end process;
process(CLK, F_SC)
variable td_raised : boolean;
begin
if F_SC = '1' then
prev_bit <= N-1;
td_raised := false;
Rcv_Flag <= '1';
elsif F_SC ='0' then
Rcv_Flag <= '0';
elsif falling_edge(CLK) then
prev_bit <= cur_bit;
if td_raised then
--Rcv_Flag <= '0';
td_raised := false;
elsif prev_bit = 0 and cur_bit = N-1 then
--Rcv_Flag <= '1';
td_raised := true;
end if;
end if;
end process;
stm32部分:
void SPI1_Configuration(void)
{
SPI_InitTypeDef SPI_InitStructure;
SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex;
SPI_InitStructure.SPI_Mode = SPI_Mode_Master;
SPI_InitStructure.SPI_DataSize = SPI_DataSize_16b;
SPI_InitStructure.SPI_CPOL = SPI_CPOL_Low;
SPI_InitStructure.SPI_CPHA = SPI_CPHA_1Edge;
SPI_InitStructure.SPI_NSS = SPI_NSS_Soft;
SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_256;
SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB;
SPI_InitStructure.SPI_CRCPolynomial = 7;
SPI_Init(SPI1, &SPI_InitStructure);
/* Enable SPI1 */
SPI_Cmd(SPI1, ENABLE);
}
void SPI1_Send(uint16_t data)
{
SPI1_NSS_L;
while (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_TXE) == RESET);
SPI_I2S_SendData(SPI1, data);
Delay(5);
while((SPI_I2S_GetFlagStatus(SPI1,SPI_I2S_FLAG_RXNE) == RESET));
SPI_I2S_ClearFlag(SPI2, SPI_I2S_FLAG_RXNE);
SPI1_NSS_H;
}
void main()
{
while(1)
{
SPI1_Send(0x4546);
m = SPI_I2S_ReceiveData(SPI1);
SPI1_RX_Buff[i] = m;
if (i==1)i=0;
else i++;
Delay(20);
}
}
有做过的吗?请教一下
spi的速率一般要低于20Mhz,另外你要在接收高低八位时加一个标志位,否则接收高位后低位刚好更新,就导致数据接收错误。
小编分享的资源很给力,谢谢小编分享,持续关注中!