这里是单片机做主机,FPGA做从机
SPI_写(由单片机写入FPGA)
在此之前,先介绍基本的读写函数spi_wr_32bit_MSB_first(B1,B2,B3,B4) 和spi_wr_1bit_cmd_read_16bit()
void spi_wr_32bit_MSB_first(unsigned char B3,unsigned char B2,unsigned char B1,unsigned char B0){
int i = 0, j = 0;
unsigned char byte4[4] = {0};
unsigned char buf = 0;
byte4[3] = B3; byte4[2] = B2; byte4[1] = B1; byte4[0] = B0;
spi_wr_cs(1);
spi_wr_sck(1);
spi_wr_sda_out(1);
spi_wr_cs(0);
Delay(1);
spi_wr_sck(0);
Delay(1);
for(j = 0; j < 4; j ++){
buf = byte4[3-j];
for(i = 0; i < 8; i ++){
spi_wr_sda_out((buf&0x80) >> 7);
buf = buf << 1;
Delay(1);
spi_wr_sck(1);
Delay(1);
spi_wr_sck(0);
}
}
spi_wr_cs(1);
spi_wr_sck(1);
}
- 写时序(16位)
unsigned int spi_wr_1bit_cmd_read_16bit(){
int i = 0;
unsigned int rd_val = 0; unsigned char sda_in = 0;
unsigned char buf = 0xaa;
unsigned char rd16[16] = {0};
spi_wr_cs(1);
spi_wr_sck(1);
spi_wr_sda_out(1);
spi_wr_cs(0);
Delay(1);
spi_wr_sck(0);
Delay(1);
spi_wr_sda_out(1);
Delay(1);
spi_wr_sck(1);
Delay(1);
spi_wr_sck(0);
for(i = 0; i < 16; i ++){
spi_wr_sda_out(0);
buf = buf << 1;
Delay(1);
spi_wr_sck(1);
Delay(1);
spi_wr_sck(0);
sda_in = spi_rd_sda_in();
rd_val = (rd_val << 1)| (sda_in&0x01);
rd16[i] = sda_in;
}
spi_wr_cs(1);
spi_wr_sck(1);
#if 0
for(i = 0; i < 16; i ++){
printf("rd16[%d] = %x \r\n",i, rd16[i]);
}
#endif
return rd_val;
}
写单个数据
写数据当然要先告诉地址,这里的FPGA会将spi_wr_32bit_MSB_first(B1,B2,B3,B4)的前两位当成地址,后两位当成写入的数据
**这表示分别往0x0000和0x0001写入了16位的数据**
spi_wr_32bit_MSB_first(0x00, 0x00, 0x02, 0x02);
spi_wr_32bit_MSB_first(0x00, 0x01, 0x01, 0x01);
写大量数据(如RAM)
void spi_wr_addr_7b_data_16b_ram_128(){
int i = 0, wa = 0, wd = 0, wa_H, wa_L, wd_H, wd_L;
for (i = 0 ; i < 128; i ++){
wa = i&(128-1); wa_H = (wa >> 8) & 0xff; wa_L = wa & 0xff;
wd = wa*255 ; wd_H = (wd >> 8) & 0xff; wd_L = wd & 0xff;
spi_wr_32bit_MSB_first(0x00, 0x00, wa_H, wa_L);
spi_wr_32bit_MSB_first(0x00, 0x01, wd_H, wd_L);
}
}
**这表示向128位的ram里写入了一组从0到28560,步进为255的递增的值
SPI读(从FPGA到单片机)
读数据之前需要先告知FPGA,应该把地址读到哪里去。所以读数据之前需要先写
读单个数据
写函数 先告知FPGA:单片机需要读取地址为0x0007(总线选择器)处的DIN0口数据 之后读函数 再将数据读出
spi_wr_32bit_MSB_first(0x00, 0x07, 0x00, 0x00);
rd_val = spi_wr_1bit_cmd_read_16bit();
读大量数据
void spi_rd_addr_7b_data_8_rom_128(){
unsigned int rom_addr = 0, rd_val = 0;
spi_wr_32bit_MSB_first(0x00, 0x07, 0x00, 0x01);
****要读的ROM连在总线选择器(0x0007)的DIN1口(0x0001)***********
for(rom_addr = 0; rom_addr < 128; rom_addr ++){
spi_wr_32bit_MSB_first(0x00, 0x08, 0x00, rom_addr&0xFF);
****要读的ROM地址为0x0008,循环读取其中的128位数据)*************
rd_val = spi_wr_1bit_cmd_read_16bit();
rom_rd[rom_addr] = (unsigned short) rd_val & 0xFFFF;
}
}
总体框图
|