当前位置:   article > 正文

基于单片机与FPGA的SPI_fpga与单片机通过什么通信

fpga与单片机通过什么通信

1.SPI含义

SPI是串行外设接口(Serial Peripheral Interface)的缩写。SPI,是一种高速的,全双工,同步的通信总线,并且在芯片的管脚上只占用四根线,节约了芯片的管脚,同时为PCB的布局上节省空间,提供方便,正是出于这种简单易用的特性,如今越来越多的芯片集成了这种通信协议

 2.步骤

step1 stm32_3pin_to_fpga_input

 prj_fpga_spi_input

  由单片机传送数据到FPGA

prj_stm32_gpio_wave_3pin

  1. #include "stm32f10x.h"
  2. #include "usart.h"
  3. void Delay(u32 count)
  4. {
  5. u32 i=0;
  6. for(;i<count;i++);
  7. }
  8. void init_gpio_clk(){
  9. GPIO_InitTypeDef GPIO_InitStructure;
  10. //使能PE 端口时钟
  11. RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOE, ENABLE);
  12. //PE.10 端口配置
  13. GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;
  14. // 推挽输出
  15. GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
  16. //IO 口 速度50MHz
  17. GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  18. // 初始化GPIOE.10
  19. GPIO_Init(GPIOE, &GPIO_InitStructure);
  20. // PE.10 为高
  21. GPIO_SetBits(GPIOE,GPIO_Pin_10);
  22. GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12;
  23. GPIO_Init(GPIOE, &GPIO_InitStructure);
  24. GPIO_SetBits(GPIOE,GPIO_Pin_12);
  25. GPIO_InitStructure.GPIO_Pin = GPIO_Pin_14;
  26. GPIO_Init(GPIOE, &GPIO_InitStructure);
  27. GPIO_SetBits(GPIOE,GPIO_Pin_14);
  28. }
  29. void gpio_clk_loop(){
  30. while(1) {
  31. GPIO_SetBits (GPIOE,GPIO_Pin_10);
  32. GPIO_ResetBits(GPIOE,GPIO_Pin_10);
  33. GPIO_SetBits (GPIOE,GPIO_Pin_12);
  34. GPIO_ResetBits(GPIOE,GPIO_Pin_12);
  35. GPIO_SetBits (GPIOE,GPIO_Pin_14);
  36. GPIO_ResetBits(GPIOE,GPIO_Pin_14);
  37. }
  38. }
  39. void init_gpio_led(){
  40. GPIO_InitTypeDef GPIO_InitStructure;
  41. //使能PB,PE 端口时钟
  42. RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB| RCC_APB2Periph_GPIOE, ENABLE);
  43. //LED0-->PB.5 端口配置
  44. GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5;
  45. // 推挽输出
  46. GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
  47. //IO 口 速度50MHz
  48. GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  49. // 初始化GPIOB.5
  50. GPIO_Init(GPIOB, &GPIO_InitStructure);
  51. // PB.5 为低
  52. GPIO_ResetBits(GPIOB,GPIO_Pin_5);
  53. //LED1-->PE.5
  54. GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5;
  55. // 初始化 GPIO
  56. GPIO_Init(GPIOE, &GPIO_InitStructure);
  57. //PE.5 输出为低
  58. GPIO_ResetBits(GPIOE,GPIO_Pin_5);
  59. }
  60. void gpio_led_tick_loop(int n){
  61. int count = n;
  62. while(count)
  63. {
  64. if(n > 0){
  65. count = count - 1;
  66. }
  67. GPIO_SetBits(GPIOE,GPIO_Pin_5);
  68. GPIO_ResetBits(GPIOB,GPIO_Pin_5);
  69. Delay(2000000);
  70. GPIO_ResetBits(GPIOB,GPIO_Pin_5);
  71. GPIO_ResetBits(GPIOE,GPIO_Pin_5);
  72. Delay(2000000);
  73. GPIO_SetBits(GPIOE,GPIO_Pin_5);
  74. GPIO_ResetBits(GPIOB,GPIO_Pin_5);
  75. Delay(2000000);
  76. GPIO_ResetBits(GPIOB,GPIO_Pin_5);
  77. GPIO_ResetBits(GPIOE,GPIO_Pin_5);
  78. Delay(2000000);
  79. GPIO_SetBits(GPIOB,GPIO_Pin_5);
  80. GPIO_ResetBits(GPIOE,GPIO_Pin_5);
  81. Delay(1000000);
  82. GPIO_ResetBits(GPIOB,GPIO_Pin_5);
  83. GPIO_ResetBits(GPIOE,GPIO_Pin_5);
  84. Delay(1000000);
  85. GPIO_SetBits(GPIOB,GPIO_Pin_5);
  86. GPIO_ResetBits(GPIOE,GPIO_Pin_5);
  87. Delay(1000000);
  88. GPIO_ResetBits(GPIOB,GPIO_Pin_5);
  89. GPIO_ResetBits(GPIOE,GPIO_Pin_5);
  90. Delay(1000000);
  91. GPIO_SetBits(GPIOB,GPIO_Pin_5);
  92. GPIO_ResetBits(GPIOE,GPIO_Pin_5);
  93. Delay(1000000);
  94. GPIO_ResetBits(GPIOB,GPIO_Pin_5);
  95. GPIO_ResetBits(GPIOE,GPIO_Pin_5);
  96. Delay(4000000);
  97. }
  98. }
  99. int main(void)
  100. {
  101. init_gpio_clk();
  102. init_gpio_led();
  103. gpio_led_tick_loop(1);
  104. gpio_clk_loop();
  105. }

step2 stm32_SPI_to_fpga_input

prj_fpga_spi_input

  1. module spi_bus(
  2. I_CLK ,
  3. I_CS ,
  4. I_SCLK ,
  5. I_SDIN ,
  6. O_DOUT ,
  7. O_DOV ,
  8. O_TESTOUT1);
  9. input I_CLK ;
  10. input I_CS ;
  11. input I_SCLK ;
  12. input I_SDIN ;
  13. output O_TESTOUT1;
  14. reg R1_I_CS ,R2_I_CS ,R3_I_CS ;
  15. reg R1_I_SCLK ,R2_I_SCLK,R3_I_SCLK ;
  16. reg R1_I_SDIN ,R2_I_SDIN,R3_I_SDIN ;
  17. reg W_I_CS_up , W_I_CS_down, W_I_SCLK_up;
  18. reg [32-1:0] R_sdin_shift, R_out_buf;
  19. output [32-1:0] O_DOUT;
  20. output O_DOV ;
  21. reg O_DOV ;
  22. always @ (*) begin
  23. W_I_CS_up = ((R3_I_CS == 1'b0)&&( R2_I_CS == 1'b1)) ? 1'b1 : 1'b0;
  24. W_I_CS_down = ((R3_I_CS == 1'b1)&&( R2_I_CS == 1'b0)) ? 1'b1 : 1'b0;
  25. W_I_SCLK_up = ((R3_I_SCLK == 1'b0)&&( R2_I_SCLK == 1'b1)) ? 1'b1 : 1'b0;
  26. end
  27. always @ (posedge I_CLK) begin
  28. R1_I_CS <= I_CS ;
  29. R1_I_SCLK <= I_SCLK ;
  30. R1_I_SDIN <= I_SDIN ;
  31. R2_I_CS <= R1_I_CS ;
  32. R2_I_SCLK <= R1_I_SCLK ;
  33. R2_I_SDIN <= R1_I_SDIN ;
  34. R3_I_CS <= R2_I_CS ;
  35. R3_I_SCLK <= R2_I_SCLK ;
  36. R3_I_SDIN <= R2_I_SDIN ;
  37. end
  38. always @ (posedge I_CLK) begin
  39. if(W_I_CS_down)
  40. R_sdin_shift <= 0;
  41. else
  42. if(W_I_SCLK_up)
  43. R_sdin_shift <= {R_sdin_shift[30:0],R2_I_SDIN};
  44. if(W_I_CS_up)
  45. R_out_buf <= R_sdin_shift;
  46. O_DOV <= W_I_CS_up;
  47. end
  48. assign O_DOUT = R_out_buf;
  49. assign O_TESTOUT1 = W_I_SCLK_up ;
  50. endmodule

 这个程序是32位输出,SPI的数据传给FPGA。

prj_stm32_SPI_to_fpga_input

  1. #include "stm32f10x.h"
  2. #include "usart.h"
  3. void Delay(u32 count)
  4. {
  5. u32 i=0;
  6. for(;i<count;i++){
  7. __nop();
  8. }
  9. }
  10. #define PIN_MY_SPI_O_SCLK GPIO_Pin_10
  11. #define PIN_MY_SPI_O_CS GPIO_Pin_12
  12. #define PIN_MY_SPI_O_SDA GPIO_Pin_14
  13. #define PORT_MY_SPI_O_SCLK GPIOE
  14. #define PORT_MY_SPI_O_CS GPIOE
  15. #define PORT_MY_SPI_O_SDA GPIOE
  16. void init_spi_pin(){
  17. GPIO_InitTypeDef GPIO_InitStructure;
  18. RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOE, ENABLE); //使能PE 端口时钟
  19. GPIO_InitStructure.GPIO_Pin = PIN_MY_SPI_O_SCLK; //PE.PIN 端口配置
  20. GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; // 推挽输出
  21. GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; //IO 口 速度50MHz
  22. GPIO_Init(PORT_MY_SPI_O_SCLK, &GPIO_InitStructure); // 初始化GPIOE.PIN
  23. GPIO_SetBits(PORT_MY_SPI_O_SCLK,PIN_MY_SPI_O_SCLK); // PE.PIN 为高
  24. GPIO_InitStructure.GPIO_Pin = PIN_MY_SPI_O_CS;
  25. GPIO_Init(PORT_MY_SPI_O_CS, &GPIO_InitStructure);
  26. GPIO_SetBits(PORT_MY_SPI_O_CS,PIN_MY_SPI_O_CS);
  27. GPIO_InitStructure.GPIO_Pin = PIN_MY_SPI_O_SDA;
  28. GPIO_Init(GPIOE, &GPIO_InitStructure);
  29. GPIO_SetBits(PORT_MY_SPI_O_SDA,PIN_MY_SPI_O_SDA);
  30. }
  31. void spi_wr_cs(int val){
  32. GPIO_WriteBit(PORT_MY_SPI_O_CS,PIN_MY_SPI_O_CS ,(val&0x1)?Bit_SET:Bit_RESET );
  33. }
  34. void spi_wr_sck(int val){
  35. GPIO_WriteBit(PORT_MY_SPI_O_SCLK,PIN_MY_SPI_O_SCLK ,(val&0x1)?Bit_SET:Bit_RESET );
  36. }
  37. void spi_wr_sda_out(int val){
  38. GPIO_WriteBit(PORT_MY_SPI_O_SDA,PIN_MY_SPI_O_SDA ,(val&0x1)?Bit_SET:Bit_RESET );
  39. }
  40. void spi_wr_32bit_MSB_first(unsigned char B3,unsigned char B2,unsigned char B1,unsigned char B0){
  41. int delay_unit = 5;
  42. int i = 0, j = 0;
  43. unsigned char byte4[4] = {0};
  44. unsigned char buf = 0;
  45. byte4[3] = B3; byte4[2] = B2; byte4[1] = B1; byte4[0] = B0;
  46. spi_wr_cs(1);
  47. spi_wr_sck(1);
  48. spi_wr_sda_out(1);
  49. // drop down cs
  50. spi_wr_cs(0);
  51. Delay(1);
  52. // drop down sck
  53. spi_wr_sck(0);
  54. Delay(1);
  55. // put data
  56. for(j = 0; j < 4; j ++){
  57. buf = byte4[3-j];
  58. for(i = 0; i < 8; i ++){
  59. spi_wr_sda_out((buf&0x80) >> 7);
  60. buf = buf << 1;
  61. Delay(1);
  62. spi_wr_sck(1);
  63. Delay(1);
  64. spi_wr_sck(0);
  65. }
  66. }
  67. spi_wr_cs(1);
  68. spi_wr_sck(1);
  69. }
  70. void spi_wr_test_loop(){
  71. while(1) {
  72. spi_wr_cs(1);
  73. spi_wr_cs(0);
  74. spi_wr_sck(1);
  75. spi_wr_sck(1);
  76. spi_wr_sck(0);
  77. spi_wr_sck(0);
  78. spi_wr_sda_out(1);
  79. spi_wr_sda_out(1);
  80. spi_wr_sda_out(1);
  81. spi_wr_sda_out(0);
  82. spi_wr_sda_out(0);
  83. spi_wr_sda_out(0);
  84. }
  85. }
  86. void spi_wr_data_loop(){
  87. while(1) {
  88. spi_wr_32bit_MSB_first(0xA5, 0xA7, 0xA9, 0xAB);
  89. spi_wr_32bit_MSB_first(0x5A, 0x5B, 0x5C, 0x5D);
  90. }
  91. }
  92. void init_gpio_led(){
  93. GPIO_InitTypeDef GPIO_InitStructure;
  94. //使能PB,PE 端口时钟
  95. RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB| RCC_APB2Periph_GPIOE, ENABLE);
  96. //LED0-->PB.5 端口配置
  97. GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5;
  98. // 推挽输出
  99. GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
  100. //IO 口 速度50MHz
  101. GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  102. // 初始化GPIOB.5
  103. GPIO_Init(GPIOB, &GPIO_InitStructure);
  104. // PB.5 为低
  105. GPIO_ResetBits(GPIOB,GPIO_Pin_5);
  106. //LED1-->PE.5
  107. GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5;
  108. // 初始化 GPIO
  109. GPIO_Init(GPIOE, &GPIO_InitStructure);
  110. //PE.5 输出为低
  111. GPIO_ResetBits(GPIOE,GPIO_Pin_5);
  112. }
  113. void gpio_led_tick_loop(int n){
  114. int count = n;
  115. while(count)
  116. {
  117. if(n > 0){
  118. count = count - 1;
  119. }
  120. GPIO_SetBits(GPIOE,GPIO_Pin_5);
  121. GPIO_ResetBits(GPIOB,GPIO_Pin_5);
  122. Delay(2000000);
  123. GPIO_ResetBits(GPIOB,GPIO_Pin_5);
  124. GPIO_ResetBits(GPIOE,GPIO_Pin_5);
  125. Delay(2000000);
  126. GPIO_SetBits(GPIOE,GPIO_Pin_5);
  127. GPIO_ResetBits(GPIOB,GPIO_Pin_5);
  128. Delay(2000000);
  129. GPIO_ResetBits(GPIOB,GPIO_Pin_5);
  130. GPIO_ResetBits(GPIOE,GPIO_Pin_5);
  131. Delay(2000000);
  132. GPIO_SetBits(GPIOB,GPIO_Pin_5);
  133. GPIO_ResetBits(GPIOE,GPIO_Pin_5);
  134. Delay(1000000);
  135. GPIO_ResetBits(GPIOB,GPIO_Pin_5);
  136. GPIO_ResetBits(GPIOE,GPIO_Pin_5);
  137. Delay(1000000);
  138. GPIO_SetBits(GPIOB,GPIO_Pin_5);
  139. GPIO_ResetBits(GPIOE,GPIO_Pin_5);
  140. Delay(1000000);
  141. GPIO_ResetBits(GPIOB,GPIO_Pin_5);
  142. GPIO_ResetBits(GPIOE,GPIO_Pin_5);
  143. Delay(1000000);
  144. GPIO_SetBits(GPIOB,GPIO_Pin_5);
  145. GPIO_ResetBits(GPIOE,GPIO_Pin_5);
  146. Delay(1000000);
  147. GPIO_ResetBits(GPIOB,GPIO_Pin_5);
  148. GPIO_ResetBits(GPIOE,GPIO_Pin_5);
  149. Delay(4000000);
  150. }
  151. }
  152. int main(void)
  153. {
  154. init_spi_pin();
  155. init_gpio_led();
  156. gpio_led_tick_loop(1);
  157. // spi_wr_test_loop();
  158. spi_wr_data_loop();
  159. }

输出32位数据,要分成4次,每次8位。

step3 stm32_SPI_write_fpga_addr_decode

prj_fpga_spi_input_bus_addr_decode

 

prj_stm32_SPI_to_fpga_bus_addr_decode

stm32通过spi读取fpga的地址。

step4 stm32_SPI_read_select_write_fpga_addr_decode

prj_fpga_spi_input_bus_read_write

 实现fpga与单片机的互传,并在单片机的显示屏上显示

prj_stm32_SPI_to_fpga_bus_read_write 

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/Monodyee/article/detail/429345
推荐阅读
相关标签
  

闽ICP备14008679号