IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 嵌入式 -> FPGA-STM32-SPI通信 -> 正文阅读

[嵌入式]FPGA-STM32-SPI通信

SPI

SPI,是英语Serial Peripheral Interface的缩写,顾名思义就是串行外围设备接口。SPI,是一种高速的,全双工,同步的通信总线,并且在芯片的管脚上只占用四根线,节约了芯片的管脚,同时为PCB的布局上节省空间,提供方便,正是出于这种简单易用的特性,现在越来越多的芯片集成了这种通信协议。
在这里插入图片描述
在这里插入图片描述

Step1、检验管脚连接是否正确

由单片机传送数据到FPGA,在signaltap上验证
单片机部分代码

//main函数部分


#include "stm32f4xx.h"
#include "delay.h"
#include "test.h"
#include "SPI.h"

 void gpio_led_tick_loop(int n){
  int count = n;
  while(count) 
  {
    GPIO_SetBits(GPIOA,GPIO_Pin_15);
    delay_ms(2000); 
    GPIO_ResetBits(GPIOA,GPIO_Pin_15);
    delay_ms(2000); 
		break;
  }
}
 void gpio_clk_loop(){
  while(1) {
    GPIO_SetBits  (GPIOC,GPIO_Pin_4);          
    GPIO_ResetBits(GPIOC,GPIO_Pin_4);          
    GPIO_SetBits  (GPIOA,GPIO_Pin_7);          
    GPIO_ResetBits(GPIOA,GPIO_Pin_7);          
    GPIO_SetBits  (GPIOC,GPIO_Pin_5);          
    GPIO_ResetBits(GPIOC,GPIO_Pin_5);          
  }
}
int main(void) 
{   
	delay_init(168);
	ALLGPIO_Init();
  gpio_led_tick_loop(1);
//  spi_wr_test_loop();
//  spi_wr_data_loop();
	gpio_clk_loop();
}



//管脚初始化设置


#include "test.h"

void ALLGPIO_Init(void)
{    	 
  GPIO_InitTypeDef  GPIO_InitStructure;
	RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE);//±?D?ê1?üGPIOAê±?ó
	RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOC, ENABLE);//±?D?ê1?üGPIOCê±?ó
	
	//3?ê??ˉLED
  GPIOA->MODER=0x01;
  //GPIOA153?ê??ˉéè??
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_15;//LED1??ó|IO?úPA15
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;//??í¨ê?3??£ê?
  GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;//í?íìê?3?
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;//50MHz,?ù?è??????óD′óó°?ì
  GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_DOWN;//??à-£?3?ê?×′ì?ê±ê?3?μíμ???£?μ??e
  GPIO_Init(GPIOA, &GPIO_InitStructure);//3?ê??ˉGPIO
	
	GPIO_ResetBits(GPIOA,GPIO_Pin_15);//GPIOA15éè??μí£?μ??e
  
	//3?ê??ˉSPI3??òy??
	 GPIO_InitStructure.GPIO_Pin = PIN_MY_SPI_O_CS;//I_CS D1
	 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;//??í¨ê?3??£ê?
	 GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;//í?íìê?3?
	 GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;//50MHz,?ù?è??????óD′óó°?ì
	 GPIO_Init(PORT_MY_SPI_O_CS, &GPIO_InitStructure);//3?ê??ˉGPIO
	 GPIO_SetBits(PORT_MY_SPI_O_CS,PIN_MY_SPI_O_CS);   
	
	 GPIO_InitStructure.GPIO_Pin = PIN_MY_SPI_O_SCLK;//I_SCK D2
	 GPIO_Init(PORT_MY_SPI_O_SCLK, &GPIO_InitStructure);//3?ê??ˉGPIO
	 GPIO_SetBits(PORT_MY_SPI_O_SCLK,PIN_MY_SPI_O_SCLK);  
	
	 GPIO_InitStructure.GPIO_Pin = PIN_MY_SPI_O_SDA; //I_SDA D3
	 GPIO_Init(PORT_MY_SPI_O_SDA, &GPIO_InitStructure);//3?ê??ˉGPIO
	 GPIO_SetBits(PORT_MY_SPI_O_SDA,PIN_MY_SPI_O_SDA);
}


//管脚对应关系

#ifndef _GPIO_H

#define _GPIO_H

#include "sys.h"  //"sys.h"í·???t°üo?á???òaμ?"stm32f4xx.h"???t

#define PIN_MY_SPI_O_SCLK GPIO_Pin_4
#define PIN_MY_SPI_O_CS   GPIO_Pin_7
#define PIN_MY_SPI_O_SDA  GPIO_Pin_5

#define PORT_MY_SPI_O_SCLK GPIOC
#define PORT_MY_SPI_O_CS   GPIOA
#define PORT_MY_SPI_O_SDA  GPIOC
void ALLGPIO_Init(void);

#endif

FPGA部分代码

module spi_bus(
  I_CLK    ,
  I_CS     ,
  I_SCK    ,
  I_SDA    ,
  O_TESTOUT);


input I_CLK    ;
input I_CS     ;
input I_SCK    ;
input I_SDA    ;

output O_TESTOUT;

reg  R1_I_CS  ;
reg  R1_I_SCK ;
reg  R1_I_SDA ;


always @ (posedge I_CLK) begin
  R1_I_CS  <= I_CS  ;
  R1_I_SCK <= I_SCK ;
  R1_I_SDA <= I_SDA ;
end

assign O_TESTOUT = R1_I_CS | R1_I_SDA| R1_I_SCK; 

endmodule

signaltap的波形与单片机程序对应,确认连接无误
在这里插入图片描述

Step2、SPI的数据传给FPGA

单片机部分代码

//main函数

#include "stm32f4xx.h"
#include "delay.h"
#include "test.h"
#include "SPI.h"

 void gpio_led_tick_loop(int n){
  int count = n;
  while(count) 
  {
    GPIO_SetBits(GPIOA,GPIO_Pin_15);
    delay_ms(2000); 
    GPIO_ResetBits(GPIOA,GPIO_Pin_15);
    delay_ms(2000); 
		break;
  }
}
int main(void) 
{   
	delay_init(168);
	ALLGPIO_Init();
  gpio_led_tick_loop(1);
//  spi_wr_test_loop();
  spi_wr_data_loop();
}


//spi_wr_data_loop函数

void spi_wr_data_loop(){
	delay_init(168);
  while(1) {
    spi_wr_32bit_MSB_first(0xA5, 0xA6, 0xA7, 0xA8);
		delay_us(10);
    spi_wr_32bit_MSB_first(0x5A, 0x5B, 0x5C, 0x5D);
  }
}

FPGA部分

module spi_bus(
  I_CLK     ,
  I_CS      ,
  I_SCLK    ,
  I_SDIN    ,
  O_DOUT    ,
  O_DOV     ,
  O_TESTOUT1);


input I_CLK    ;
input I_CS     ;
input I_SCLK   ;
input I_SDIN    ;

output O_TESTOUT1;

reg  R1_I_CS  ,R2_I_CS ,R3_I_CS  ;
reg  R1_I_SCLK ,R2_I_SCLK,R3_I_SCLK ;
reg  R1_I_SDIN ,R2_I_SDIN,R3_I_SDIN ;
reg  W_I_CS_up , W_I_CS_down, W_I_SCLK_up;

reg [32-1:0] R_sdin_shift, R_out_buf;
output [32-1:0] O_DOUT;
output          O_DOV ;   
reg             O_DOV ;   

// pipeline
//                        | meta stability
//  R3_I_CS   |R2_I_CS    |R1_I_CS    |  I_CS 
//  R3_I_SCLK |R2_I_SCLK  |R1_I_SCLK  |  I_SCLK
//  R3_I_SDIN |R2_I_SDIN  |R1_I_SDIN  |  I_SDIN
//            |W_I_CS_up  
//            |W_I_CS_down
//            |W_I_SCLK_up 

always @ (*) begin
  W_I_CS_up   = ((R3_I_CS == 1'b0)&&( R2_I_CS == 1'b1)) ? 1'b1 : 1'b0;
  W_I_CS_down = ((R3_I_CS == 1'b1)&&( R2_I_CS == 1'b0)) ? 1'b1 : 1'b0;
  W_I_SCLK_up  = ((R3_I_SCLK == 1'b0)&&( R2_I_SCLK == 1'b1)) ? 1'b1 : 1'b0;
end
always @ (posedge I_CLK) begin
  R1_I_CS   <= I_CS       ;
  R1_I_SCLK <= I_SCLK     ;
  R1_I_SDIN <= I_SDIN     ;
  R2_I_CS   <= R1_I_CS    ;
  R2_I_SCLK <= R1_I_SCLK  ;
  R2_I_SDIN <= R1_I_SDIN  ;
  R3_I_CS   <= R2_I_CS    ;
  R3_I_SCLK <= R2_I_SCLK  ;
  R3_I_SDIN <= R2_I_SDIN  ;
end
always @ (posedge I_CLK) begin
  if(W_I_CS_down)
    R_sdin_shift <= 0;
  else
    if(W_I_SCLK_up)
      R_sdin_shift <= {R_sdin_shift[30:0],R2_I_SDIN};
  if(W_I_CS_up)
    R_out_buf <= R_sdin_shift;
  O_DOV <= W_I_CS_up;
end
assign O_DOUT = R_out_buf;


assign O_TESTOUT1 =  W_I_SCLK_up ;

endmodule

signaltap验证如下
在这里插入图片描述

Step3、stm32通过spi读取fpga的地址

单片机部分代码

//main函数

#include "stm32f4xx.h"
#include "delay.h"
#include "test.h"
#include "SPI.h"

 void gpio_led_tick_loop(int n){
  int count = n;
  while(count) 
  {
    GPIO_SetBits(GPIOA,GPIO_Pin_15);
    delay_ms(2000); 
    GPIO_ResetBits(GPIOA,GPIO_Pin_15);
    delay_ms(2000); 
		break;
  }
}
int main(void) 
{   
	delay_init(168);
	ALLGPIO_Init();
  gpio_led_tick_loop(1);
//  spi_wr_test_loop();
  //spi_wr_data_loop();
	spi_wr_addr_16b_data_16b_loop();
}

//spi_wr_addr_16b_data_16b_loop函数


void spi_wr_addr_16b_data_16b_loop(){
  while(1) {
    // counter increase value write test case 
    //                     A_H   A_L , D_H , D_L
    spi_wr_32bit_MSB_first(0x00, 0x00, 0x02, 0x02); // 16 bit counter 1
    spi_wr_32bit_MSB_first(0x00, 0x01, 0x01, 0x01); // 16 bit counter 2
    spi_wr_32bit_MSB_first(0x00, 0x00, 0x04, 0x04); // 16 bit counter 1
    spi_wr_32bit_MSB_first(0x00, 0x01, 0x05, 0x05); // 16 bit counter 2

    spi_wr_32bit_MSB_first(0x00, 0x02, 0x01, 0x02); // 32 bit counter  L
    spi_wr_32bit_MSB_first(0x00, 0x03, 0x03, 0x04); // 32 bit counter  H
    spi_wr_32bit_MSB_first(0x00, 0x04, 0x00, 0x00); // 32 bit counter  Update
    
    spi_wr_32bit_MSB_first(0x00, 0x02, 0x04, 0x03); // 32 bit counter  L
    spi_wr_32bit_MSB_first(0x00, 0x03, 0x02, 0x01); // 32 bit counter  H
    spi_wr_32bit_MSB_first(0x00, 0x04, 0x00, 0x00); // 32 bit counter  Update
   
    // ram write test case
    spi_wr_addr_16b_data_16b_ram_128();
  }
}

FPGA部分
在这里插入图片描述
signaltap验证
在这里插入图片描述

Step4、stm32_SPI_read_select_write_fpga_addr_decode

这一步实现fpga与单片机的互传,并在单片机的显示屏上显示
单片机部分代码

//main函数

#include "stm32f4xx.h"
#include "delay.h"
#include "test.h"
#include "SPI.h"
#include "usart.h"
#include "tftlcd.h"

 void gpio_led_tick_loop(int n){
  int count = n;
  while(count) 
  {
    GPIO_SetBits(GPIOA,GPIO_Pin_15);
    delay_ms(2000); 
    GPIO_ResetBits(GPIOA,GPIO_Pin_15);
    delay_ms(2000); 
		break;
  }
}
 void my_sys_init(){
	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); //??NVIC????2:2??????,2??????
		 //??????115200
}
int main(void) 
{   
	uart_init(115200);
	delay_init(168);
	delay_ms(2000);
	printf("hello?");
		LCD_Init(); 
	//LCD_DrawLine(0,240,800,240);
	//LCD_ShowString(340,30,300,24,24,"TFTLCD TEST");
	my_sys_init();

		
		
  printf("Hello Stm32 \r\n");
	delay_init(168);
	ALLGPIO_Init();
//  gpio_led_tick_loop(1);
//  spi_wr_test_loop();
 // spi_wr_data_loop();
	 spi_write_reg_ram_read_reg_rom_test();
}


//spi_write_reg_ram_read_reg_rom_test函数

void spi_write_reg_ram_read_reg_rom_test(){
  unsigned int rd_val = 0;
	LCD_Clear(65535);
	
  while(1) {
		char text[]="";

    // counter increase value write test case 
    //                     A_H   A_L , D_H , D_L
    spi_wr_32bit_MSB_first(0x00, 0x00, 0x02, 0x02); // 16 bit counter 1
    spi_wr_32bit_MSB_first(0x00, 0x01, 0x01, 0x01); // 16 bit counter 2
    spi_wr_32bit_MSB_first(0x00, 0x00, 0x04, 0x04); // 16 bit counter 1
    spi_wr_32bit_MSB_first(0x00, 0x01, 0x05, 0x05); // 16 bit counter 2

    spi_wr_32bit_MSB_first(0x00, 0x02, 0x01, 0x02); // 32 bit counter  L
    spi_wr_32bit_MSB_first(0x00, 0x03, 0x03, 0x04); // 32 bit counter  H
    spi_wr_32bit_MSB_first(0x00, 0x04, 0x00, 0x00); // 32 bit counter  Update
    
    spi_wr_32bit_MSB_first(0x00, 0x02, 0x04, 0x03); // 32 bit counter  L
    spi_wr_32bit_MSB_first(0x00, 0x03, 0x02, 0x01); // 32 bit counter  H
    spi_wr_32bit_MSB_first(0x00, 0x04, 0x00, 0x00); // 32 bit counter  Update
   
    // ram write test case
    spi_wr_addr_7b_data_16b_ram_128();

    printf("#------------------------------------------------------------------------------- \r\n");
    printf("# Counter read test \r\n");
    // read address write test case
    // before read, write the read select value  to mux first, select the mux input 0 to output
    spi_wr_32bit_MSB_first(0x00, 0x07, 0x00, 0x00); 
    // read the output value of the selected mux input port 0, a 16 bit counter  value 
    rd_val = spi_wr_1bit_cmd_read_16bit();
    //printf("# counter 0 read value = %4x\r\n", rd_val);
		sprintf(text,"# counter 0 read value = %4x\r\n", rd_val);
		LCD_ShowString(100,50,200,200,24,text);
    spi_rd_addr_7b_data_8_rom_128();


  }
}

以及LCD部分代码
在这里插入图片描述
FPGA部分
在这里插入图片描述

验证:
signaltap上的数据与显示屏上的一致,说明数据传输过程无误
在这里插入图片描述

在这里插入图片描述
在显示屏上打印rom表
在这里插入图片描述

在这里插入图片描述

应用

将频率计的数值送到单片机,并在LCD屏幕上显示

将频率计输出的频率分为高低十六位分别送进DIN0和DIN1,即可顺利传送数据,然后将高位数据×65536,+第十六位数据,得到最终结果,并在显示屏上显示

在这里插入图片描述
在这里插入图片描述

结果验证:
在这里插入图片描述
在这里插入图片描述

  嵌入式 最新文章
基于高精度单片机开发红外测温仪方案
89C51单片机与DAC0832
基于51单片机宠物自动投料喂食器控制系统仿
《痞子衡嵌入式半月刊》 第 68 期
多思计组实验实验七 简单模型机实验
CSC7720
启明智显分享| ESP32学习笔记参考--PWM(脉冲
STM32初探
STM32 总结
【STM32】CubeMX例程四---定时器中断(附工
上一篇文章      下一篇文章      查看所有文章
加:2021-07-26 12:14:17  更:2021-07-26 12:15:28 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年4日历 -2024/4/26 5:07:20-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码