模拟SPI程序
SPI编程说明

3:划分FOV(点击创建FOV,然后选择 是 或者 否 即可)。
4:调整原点(点击手动添加,通过控制和调整板子原点,使钢网文件盒板子实际重叠即可。控制移动时调节视野的,调整板子原点才是移动坐标的。)
8:添加拼板(点击开始和结束,选择对应的两个焊盘)
8:添加拼板(选择对应的焊盘点之后,如果需要选择角度的选择角度,之后点击添加即可完成)。
9:编辑基准点(找到基准点,右键点击注册基准点,弹出对话框,点击OK即可完成第一个基准点的注册,再找到另外一个基准点以相同的办法完成即可。如果第二个基准点是粉红色,那就回到选择设定焊盘区域那,再注册一次)。
5:基准点设定(打开编辑基准点,选择基准点列表,双击数字1,即可切换到板子对应的基准点。基准点完成之后,保存基准点也是在这下面)。
5:基准点调节(先把曝光时间设置在3-7之间,点击二值化,再点击拍照,将基准点彻底的与周边颜色区分开来;并保证那个绿色的十字架在MARK点的正中间,以相同的手法,完成另一个基准点的制作,并保存)。
2:当你连续测试几块板子都觉得你这个程序没有问题的话,那么你就到文件选项将这个程序保存;第一次做的时候保存不了,你可以选择点击导出程序。
3:这就是我们的程序制作大概步骤,剩下的一些都是需要自己的摸索的。
10:创建FOV(点击创建,弹出对话框选择是或者否都可以完成FOV的创建)。
11:OK NG(点出OK NG来,然后直接点击生成即可,注意两个都要点击生成的)。
12:程序到此已经做完,剩下的是在SPI软件的调试,所以将做好的程序导出即可。
二:SPI软件调试
1:加载检测程序(打到手动模式,选择文件选项,点击打开程序,选择加载程序,选择所需要打开的程序,双击或者选择再打开。)
51单片机模拟 SPI 总线的方法

51单片机模拟 SPI 总线的方法1 引言SPI(Serial Peripheral Interface--串行外设接口)总线系统是一种同步串行外设接口,它可以使MCU与各种外围设备以串行方式进行通信以交换信息。
外围设置FLASHRAM、网络控制器、LCD显示驱动器、A/D转换器和MCU等。
SPI总线系统可直接与各个厂家生产的多种标准外围器件直接接口,该接口一般使用4条线:串行时钟线(SCK)、主机输入/从机输出数据线MISO、主机输出/从机输入数据线MOSI和低电平有效的从机选择线SS(有的SPI接口芯片带有中断信号线INT或INT、有的SPI接口芯片没有主机输出/从机输入数据线MOSI)。
由于SPI系统总线一共只需3~4位数据线和控制即可实现与具有SPI总线接口功能的各种I/O器件进行接口,而扩展并行总线则需要8根数据线、8~16位地址线、2~3位控制线,因此,采用SPI总线接口可以简化电路设计,节省很多常规电路中的接口器件和I/O口线,提高设计的可靠性。
由此可见,在MCS51系列等不具有SPI接口的单片机组成的智能仪器和工业测控系统中,当传输速度要求不是太高时,使用SPI总线可以增加应用系统接口器件的种类,提高应用系统的性能。
2 SPI总线的组成利用SPI总线可在软件的控制下构成各种系统。
如1个主MCU和几个从MCU、几个从MCU 相互连接构成多主机系统(分布式系统)、1个主MCU和1个或几个从I/O设备所构成的各种系统等。
在大多数应用场合,可使用1个MCU作为控机来控制数据,并向1个或几个从外围器件传送该数据。
从器件只有在主机发命令时才能接收或发送数据。
其数据的传输格式是高位(MSB)在前,低位(LSB)在后。
SPI总线接口系统的典型结构。
当一个主控机通过SPI与几种不同的串行I/O芯片相连时,必须使用每片的允许控制端,这可通过MCU的I/O端口输出线来实现。
但应特别注意这些串行I/O芯片的输入输出特性:首先是输入芯片的串行数据输出是否有三态控制端。
51单片机模拟spi串行接口程序

{
unsigned char BitCounter;
for(BitCounter=8; BiCounter!=0; BitCounter--)
{ CLK=0;
DataI=0; // write
if(val&0x80) DataI=1;
val<<=1;
CLK=1;
if(DataO)val|=1; // read
}
CLK=0;
return val;
}
sbit CLK= P1^5;
sbit DataI=P1^7;
sbiபைடு நூலகம் DataO=P1^6;
#define SD_Disable() CS=1 //片选关
#define SD_Enable() CS=0 //片选开
val<<=1;
CLK=1;
if(DataO)val|=1; // read
}
CLK=0;
return val;
}
sbit CLK= P1^5;
sbit DataI=P1^7;
sbit DataO=P1^6;
#define SD_Disable() CS=1 //片选关
#define SD_Enable() CS=0 //片选开
unsigned char SPI_TransferByte(unsigned char val)
{
unsigned char BitCounter;
for(BitCounter=8; BiCounter!=0; BitCounter--)
{ CLK=0;
Linux下SPI驱动测试程序

Linux下的SPI总线驱动(一)2013-04-12 15:08:46分类:LINUX版权所有,转载请说明转自一.SPI理论介绍SPI总线全名,串行外围设备接口,是一种串行的主从接口,集成于很多微控制器内部。
和I2C使用2根线相比,SPI总线使用4根线:MOSI (SPI 总线主机输出/ 从机输入)、MISO (SPI总线主机输入/从机输出)、SCLK(时钟信号,由主设备产生)、CS(从设备使能信号,由主设备控制)。
由于SPI总线有专用的数据线用于数据的发送和接收,因此可以工作于全双工,当前市面上可以找到的SPI外围设备包括RF芯片、智能卡接口、E2PROM、RTC、触摸屏传感器、ADC。
SCLK信号线只由主设备控制,从设备不能控制信号线。
同样,在一个基于SPI的设备中,至少有一个主控设备。
这样传输的特点:这样的传输方式有一个优点,与普通的串行通讯不同,普通的串行通讯一次连续传送至少8位数据,而SPI允许数据一位一位的传送,甚至允许暂停,因为SCLK 时钟线由主控设备控制,当没有时钟跳变时,从设备不采集或传送数据。
也就是说,主设备通过对SCLK时钟线的控制可以完成对通讯的控制。
SPI还是一个数据交换协议:因为SPI的数据输入和输出线独立,所以允许同时完成数据的输入和输出。
不同的SPI 设备的实现方式不尽相同,主要是数据改变和采集的时间不同,在时钟信号上沿或下沿采集有不同定义,具体请参考相关器件的文档。
在点对点的通信中,SPI接口不需要进行寻址操作,且为全双工通信,显得简单高效。
在多个从设备的系统中,每个从设备需要独立的使能信号,硬件上比I2C 系统要稍微复杂一些。
二.SPI驱动移植我们下面将的驱动的移植是针对Mini2440的SPI驱动的移植Step1:在Linux Source Code中修改arch/arm/mach-s3c2440/文件,加入头文件:#include <linux/spi/>#include <../mach-s3c2410/include/mach/>然后加入如下代码:static struct spi_board_info s3c2410_spi0_board[] ={[0] = {.modalias = "spidev", us_num = 0, hip_select = 0, rq = IRQ_EINT9, ax_speed_hz = 500 * 1000,in_cs = S3C2410_GPG(2),.num_cs = 1, us_num = 0, pio_setup = s3c24xx_spi_gpiocfg_bus0_gpe11_12_13, odalias = "spidev",.bus_num = 1,.chip_select = 0,.irq = IRQ_EINT2,.max_speed_hz = 500 * 1000,}};static struct s3c2410_spi_info s3c2410_spi1_platdata = {.pin_cs = S3C2410_GPG(3),.num_cs = 1,.bus_num = 1,.gpio_setup = s3c24xx_spi_gpiocfg_bus1_gpg5_6_7,};Step2:在mini2440_devices[]平台数组中添加如下代码:&s3c_device_spi0,&s3c_device_spi1,Step3:最后在mini2440_machine_init函数中加入如下代码:&s3c2410_spi0_platdata;spi_register_board_info(s3c2410_spi0_board, ARRAY_SIZE(s3c2410_spi0_board)); &s3c2410_spi1_platdata;spi_register_board_info(s3c2410_spi1_board, ARRAY_SIZE(s3c2410_spi1_board)); Step4:最后需要修改arch/arm/plat-s3c24xx/KConfig文件找到config S3C24XX_SPI_BUS0_GPE11_GPE12_GPE13boolhelpSPI GPIO configuration code for BUS0 when connected toGPE11, GPE12 and GPE13.config S3C24XX_SPI_BUS1_GPG5_GPG6_GPG7boolhelpSPI GPIO configuration code for BUS 1 when connected toGPG5, GPG6 and GPG7.修改为config S3C24XX_SPI_BUS0_GPE11_GPE12_GPE13bool "S3C24XX_SPI_BUS0_GPE11_GPE12_GPE13"helpSPI GPIO configuration code for BUS0 when connected toGPE11, GPE12 and GPE13.config S3C24XX_SPI_BUS1_GPG5_GPG6_GPG7bool "S3C24XX_SPI_BUS1_GPG5_GPG6_GPG7"helpSPI GPIO configuration code for BUS 1 when connected toGPG5, GPG6 and GPG7.Step5:最后make menuconfig配置,选中System Type和SPI support相应文件Step6:执行make生成zInage,将编译好的内核导入开发板,并且编译测试程序运行即可。
运用4个普通IO口模拟SPI程序等

运用 4 个普通 I/O 口模拟 SPI 程序源代码
/******************************************************************** 函 数 名:uchar SpiReadWrite(uchar dat) 功 能:SPI 发送接收一个数据 说 明: 调 用: 入口参数: 出口参数: ***********************************************************************/ uchar SpiReadWrite(uchar dat) { uchar i,temp; temp=0; SCK=0; _nop_(); for(i=0;i<8;i++) { if(dat & 0x80) { MOSI=1; }
单片机IO口模拟SPI四种模式的程序

单⽚机IO⼝模拟SPI四种模式的程序#include "iom8535v.h"#define _CPOL 1#define _CPHA 0#define SCK_IO DDRA|=0X01#define MOSI_IO DDRA|=0X02#define MISO_IO DDRA&=0XFB#define SSEL_IO DDRA|=0X08#define SCK_D(X) (X?(PORTA|=0X01):(PORTA&=0XFE))#define MOSI_D(X) (X?(PORTA|=0X02):(PORTA&=0XFD))#define SSEL_D(X) (X?(PORTA|=0X08):(PORTA&=0XF7))#define MISO_I() (PINA&0X04)void delay(){unsigned char m,n;for(n=0;n<5;n++);for(m=0;m<100;m++);}void SPI_Init(void){SCK_IO ;MOSI_IO ;MISO_IO ;SSEL_IO ;SSEL_D(1);MOSI_D(1);#if _CPOL==0SCK_D(0);#elseSCK_D(1);#endif}#if _CPOL==0&&_CPHA==0 //MODE 0 0void SPI_Send_Dat(unsigned char dat){unsigned char n;for(n=0;n<8;n++){SCK_D(0);if(dat&0x80)MOSI_D(1);else MOSI_D(0);dat<<=1;SCK_D(1);}SCK_D(0);}unsigned char SPI_Receiver_Dat(void){unsigned char n ,dat,bit_t;for(n=0;n<8;n++){SCK_D(0);dat<<=1;if(MISO_I())dat|=0x01;else dat&=0xfe;SCK_D(1);}SCK_D(0);return dat;}#endif#if _CPOL==1&&_CPHA==0 //MODE 1 0 void SPI_Send_Dat(unsigned char dat){unsigned char n;for(n=0;n<8;n++){SCK_D(1);if(dat&0x80)MOSI_D(1);else MOSI_D(0);dat<<=1;SCK_D(0);}SCK_D(1);}unsigned char SPI_Receiver_Dat(void){unsigned char n ,dat,bit_t;for(n=0;n<8;n++){SCK_D(1);dat<<=1;if(MISO_I())dat|=0x01;else dat&=0xfe;SCK_D(0);}SCK_D(1);return dat;}#endif#if _CPOL==0&&_CPHA==1 //MODE 0 1 void SPI_Send_Dat(unsigned char dat){unsigned char n;SCK_D(0);for(n=0;n<8;n++){SCK_D(1);if(dat&0x80)MOSI_D(1);else MOSI_D(0);dat<<=1;SCK_D(0);}}unsigned char SPI_Receiver_Dat(void){unsigned char n ,dat,bit_t;for(n=0;n<8;n++){SCK_D(1);dat<<=1;if(MISO_I())dat|=0x01;else dat&=0xfe;SCK_D(0);}SCK_D(0);return dat;}#endif//////////////////////////////////////////////////////////////////////////////////////////////////////////////#if _CPOL==1&&_CPHA==1 //MODE 1 1 void SPI_Send_Dat(unsigned char dat){unsigned char n;SCK_D(1);for(n=0;n<8;n++){SCK_D(0);if(dat&0x80)MOSI_D(1);else MOSI_D(0);dat<<=1;SCK_D(1);}}unsigned char SPI_Receiver_Dat(void){unsigned char n ,dat,bit_t;SCK_D(0);for(n=0;n<8;n++){ SCK_D(0);dat<<=1;if(MISO_I())dat|=0x01;else dat&=0xfe;SCK_D(1);}SCK_D(1);return dat;}#endifvoid main(){SPI_Init();DDRB = 0XFF;//#if _CPOL//SCK_D(0);//#endifwhile(1){//SSEL_D(0);//SPI_Send_Dat(0x01);//SPI_Send_Dat(0x31);//SSEL_D(1);SSEL_D(0);SPI_Send_Dat(0x81);PORTB =SPI_Receiver_Dat();SSEL_D(1);//delay();}}。
SPI完整程序

SPI接口源程序module simple_spi_top(// 8bit WISHBONE bus slave interfaceinput wire clk_i, // clockinput wire rst_i, // reset (asynchronous active low)input wire cyc_i, // cycleinput wire stb_i, // strobeinput wire [1:0] adr_i, // addressinput wire we_i, // write enableinput wire [7:0] dat_i, // data inputoutput reg [7:0] dat_o, // data outputoutput reg ack_o, // normal bus terminationoutput reg inta_o, // interrupt output// SPI portoutput reg sck_o, // serial clock outputoutput wire mosi_o, // MasterOut SlaveINinput wire miso_i // MasterIn SlaveOut);//// Module body//reg [7:0] spcr; // Serial Peripheral Control Register ('HC11 naming) wire [7:0] spsr; // Serial Peripheral Status register ('HC11 naming)reg [7:0] sper; // Serial Peripheral Extension registerreg [7:0] treg, rreg; // Transmit/Receive register// fifo signalswire [7:0] rfdout;reg wfre, rfwe;wire rfre, rffull, rfempty;wire [7:0] wfdout;wire wfwe, wffull, wfempty;// misc signalswire tirq; // transfer interrupt (selected number of transfers done) wire wfov; // write fifo overrun (writing while fifo full)reg [1:0] state; // statemachine statereg [2:0] bcnt;//// Wishbone interfacewire wb_acc = cyc_i & stb_i; // WISHBONE accesswire wb_wr = wb_acc & we_i; // WISHBONE write access// dat_ialways @(posedge clk_i or negedge rst_i)if (~rst_i)beginspcr <= #1 8'h10; // set master bitsper <= #1 8'h00;endelse if (wb_wr)beginif (adr_i == 2'b00)spcr <= #1 dat_i | 8'h10; // always set master bitif (adr_i == 2'b11)sper <= #1 dat_i;end// write fifoassign wfwe = wb_acc & (adr_i == 2'b10) & ack_o & we_i; assign wfov = wfwe & wffull;// dat_oalways @(posedge clk_i)case(adr_i) // synopsys full_case parallel_case2'b00: dat_o <= #1 spcr;2'b01: dat_o <= #1 spsr;2'b10: dat_o <= #1 rfdout;2'b11: dat_o <= #1 sper;endcase// read fifoassign rfre = wb_acc & (adr_i == 2'b10) & ack_o & ~we_i;// ack_oalways @(posedge clk_i or negedge rst_i)if (~rst_i)ack_o <= #1 1'b0;elseack_o <= #1 wb_acc & !ack_o;// decode Serial Peripheral Control Registerwire spie = spcr[7]; // Interrupt enable bitwire spe = spcr[6]; // System Enable bitwire dwom = spcr[5]; // Port D Wired-OR Mode Bit wire mstr = spcr[4]; // Master Mode Select Bit wire cpol = spcr[3]; // Clock Polarity Bitwire cpha = spcr[2]; // Clock Phase Bitwire [1:0] spr = spcr[1:0]; // Clock Rate Select Bits// decode Serial Peripheral Extension Registerwire [1:0] icnt = sper[7:6]; // interrupt on transfer countwire [1:0] spre = sper[1:0]; // extended clock rate selectwire [3:0] espr = {spre, spr};// generate status registerwire wr_spsr = wb_wr & (adr_i == 2'b01);reg spif;always @(posedge clk_i)if (~spe)spif <= #1 1'b0;elsespif <= #1 (tirq | spif) & ~(wr_spsr & dat_i[7]);reg wcol;always @(posedge clk_i)if (~spe)wcol <= #1 1'b0;elsewcol <= #1 (wfov | wcol) & ~(wr_spsr & dat_i[6]);assign spsr[7] = spif;assign spsr[6] = wcol;assign spsr[5:4] = 2'b00;assign spsr[3] = wffull;assign spsr[2] = wfempty;assign spsr[1] = rffull;assign spsr[0] = rfempty;// generate IRQ output (inta_o)always @(posedge clk_i)inta_o <= #1 spif & spie;//// hookup read/write buffer fifofifo4 #(8)rfifo(.clk ( clk_i ),.rst ( rst_i ),.clr ( ~spe ),.din ( treg ),.we ( rfwe ),.dout ( rfdout ),.re ( rfre ),.full ( rffull ),.empty ( rfempty )),wfifo(.clk ( clk_i ),.rst ( rst_i ),.clr ( ~spe ),.din ( dat_i ),.we ( wfwe ),.dout ( wfdout ),.re ( wfre ),.full ( wffull ),.empty ( wfempty ));//// generate clk dividerreg [11:0] clkcnt;always @(posedge clk_i)if(spe & (|clkcnt & |state))clkcnt <= #1 clkcnt - 11'h1;elsecase (espr) // synopsys full_case parallel_case4'b0000: clkcnt <= #1 12'h0; // 2 -- original M68HC11 coding 4'b0001: clkcnt <= #1 12'h1; // 4 -- original M68HC11 coding 4'b0010: clkcnt <= #1 12'h3; // 16 -- original M68HC11 coding 4'b0011: clkcnt <= #1 12'hf; // 32 -- original M68HC11 coding4'b0100: clkcnt <= #1 12'h1f; // 84'b0101: clkcnt <= #1 12'h7; // 644'b0110: clkcnt <= #1 12'h3f; // 1284'b0111: clkcnt <= #1 12'h7f; // 2564'b1000: clkcnt <= #1 12'hff; // 5124'b1001: clkcnt <= #1 12'h1ff; // 10244'b1010: clkcnt <= #1 12'h3ff; // 20484'b1011: clkcnt <= #1 12'h7ff; // 4096endcase// generate clock enable signalwire ena = ~|clkcnt;// transfer statemachinealways @(posedge clk_i)if (~spe)beginstate <= #1 2'b00; // idlebcnt <= #1 3'h0;treg <= #1 8'h00;wfre <= #1 1'b0;rfwe <= #1 1'b0;sck_o <= #1 1'b0;endelsebeginwfre <= #1 1'b0;rfwe <= #1 1'b0;case (state) //synopsys full_case parallel_case2'b00: // idle statebeginbcnt <= #1 3'h7; // set transfer countertreg <= #1 wfdout; // load transfer registersck_o <= #1 cpol; // set sckif (~wfempty) beginwfre <= #1 1'b1;state <= #1 2'b01;if (cpha) sck_o <= #1 ~sck_o;endend2'b01: // clock-phase2, next dataif (ena) beginsck_o <= #1 ~sck_o;state <= #1 2'b11;end2'b11: // clock phase1if (ena) begintreg <= #1 {treg[6:0], miso_i};bcnt <= #1 bcnt -3'h1;if (~|bcnt) beginstate <= #1 2'b00;sck_o <= #1 cpol;rfwe <= #1 1'b1;end else beginstate <= #1 2'b01;sck_o <= #1 ~sck_o;endend2'b10: state <= #1 2'b00;endcaseendassign mosi_o = treg[7];// count number of transfers (for interrupt generation)reg [1:0] tcnt; // transfer countalways @(posedge clk_i)if (~spe)tcnt <= #1 icnt;else if (rfwe) // rfwe gets asserted when all bits have been transferedif (|tcnt)tcnt <= #1 tcnt - 2'h1;elsetcnt <= #1 icnt;assign tirq = ~|tcnt & rfwe;endmodule******************************************************************************* // 4 entry deep fast fifomodule fifo4(clk, rst, clr, din, we, dout, re, full, empty);parameter dw = 8;input clk, rst;input clr;input [dw:1] din;input we;output [dw:1] dout;input re;output full, empty;reg [dw:1] mem[0:3];reg [1:0] wp;reg [1:0] rp;wire [1:0] wp_p1;wire [1:0] wp_p2;wire [1:0] rp_p1;wire full, empty;reg gb;always @(posedge clk or negedge rst)if(!rst) wp <= #1 2'h0;elseif(clr) wp <= #1 2'h0;elseif(we) wp <= #1 wp_p1;assign wp_p1 = wp + 2'h1;assign wp_p2 = wp + 2'h2;always @(posedge clk or negedge rst)if(!rst) rp <= #1 2'h0;elseif(clr) rp <= #1 2'h0;elseif(re) rp <= #1 rp_p1; assign rp_p1 = rp + 2'h1;// Fifo Outputassign dout = mem[ rp ];// Fifo Inputalways @(posedge clk)if(we) mem[ wp ] <= #1 din;// Statusassign empty = (wp == rp) & !gb;assign full = (wp == rp) & gb;// Guard Bit ...always @(posedge clk)if(!rst) gb <= #1 1'b0;elseif(clr) gb <= #1 1'b0;elseif((wp_p1 == rp) & we) gb <= #1 1'b1;elseif(re) gb <= #1 1'b0; endmodule。
AT45DB161(中文)

关于模拟SPI总线读写A TDB161一、芯片概述DataFlash-A T45DB161 B是美国Atmel公司推出的大容量串行Flash存储器产品,采用NOR技术制造,可用于存储数据或程序代码,其产品型号为A T 4 5一DBxxxx,容量从lM 到256M。
A T45DB161B是DataFlash系列中的中档产品,单片容量为1 6Mb,其引脚及功能分别为:/CS:片选信号,SCK:串行时钟输入信号;SI:串行输入。
SO:串行输出。
/wP:写保护引脚,/RESET:复位引脚。
RDY/BUSY:准备好/忙信号。
NC:未用引脚。
A T45 DB 1 61B的内部逻辑结构分为三个部分:存储页阵列(主存)、缓存与I/O接口。
A T45DB161B的存储页面大小为52 8字节,整个存储器共分为409 6页,片内集成了两个52 8字节的SRAM 缓存。
A TDB161系列存储器可以按地址从低到高顺序读写,也可以随机读写任一字节的数据。
对于顺序读数据,可以使用连续读主存页阵列命令(操作码6 8 H 或E 8 H)从给定的起始地址开始连续读出数据,中间不需用户干预。
也可使用读单页主存命令(操作码5 2 H 或D2H),自行提供页地址读取数据。
对于顺序写数据,可以使用通过缓存写主存页命令(操作码82H 或85H ),直接将数据写人主存。
也可以先使用写缓存命令(操作码84H 或8 7H),将数据写入缓存,在适当的时刻再使用缓存写主存页命令(操作码8 3H 或86H),将缓存中的数据写入主存。
因此可以灵活的选择不同的读写方式对存储器进行读写操作。
在这里使用顺序读写Fla sh操作命令,并配合SPI模式0时序对Flash进行读写。
A TDB161具有16M的存储空间,可以存储较大的数据,而且是通过SPI总线来访问的,所以不占用什么资源。
A TDB161有16M的存储空间,有三个区域,4092页,每页有528(512)BYTE,还有两个缓冲区。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
写程序:void SPIx_WriteByte(u8 TxData){u8 j=0;SPI_FLASH_CLK_LOW(); //clk=0if(TxData&0x80){SPI_FLASH_DI_HIGH();} //mosi=1else{SPI_FLASH_DI_LOW();} //mosi=0for(j=0;j<3;j++); //延时SPI_FLASH_CLK_HIGH(); //clk=1,一个上升沿写入一位for(j=0;j<5;j++); //延时SPI_FLASH_CLK_LOW(); //clk=0if(TxData & 0x40){SPI_FLASH_DI_HIGH();} //mosi=1else{SPI_FLASH_DI_LOW();} //mosi=0for(j=0;j<3;j++); //延时SPI_FLASH_CLK_HIGH();for(j=0;j<5;j++);SPI_FLASH_CLK_LOW();if(TxData&0x20){SPI_FLASH_DI_HIGH();} //mosi=1else{SPI_FLASH_DI_LOW();} //mosi=0for(j=0;j<3;j++); //延时SPI_FLASH_CLK_HIGH();for(j=0;j<5;j++);SPI_FLASH_CLK_LOW();if(TxData&0x10){SPI_FLASH_DI_HIGH();} //mosi=1else{SPI_FLASH_DI_LOW();} //mosi=0for(j=0;j<3;j++); //延时SPI_FLASH_CLK_HIGH();for(j=0;j<5;j++);SPI_FLASH_CLK_LOW();if(TxData&0x08){SPI_FLASH_DI_HIGH();} //mosi=1else{SPI_FLASH_DI_LOW();} //mosi=0for(j=0;j<3;j++); //延时SPI_FLASH_CLK_HIGH();for(j=0;j<5;j++);SPI_FLASH_CLK_LOW();if(TxData&0x04){SPI_FLASH_DI_HIGH();} //mosi=1else{SPI_FLASH_DI_LOW();} //mosi=0for(j=0;j<3;j++); //延时SPI_FLASH_CLK_HIGH();for(j=0;j<5;j++);SPI_FLASH_CLK_LOW();if(TxData&0x02){SPI_FLASH_DI_HIGH();} //mosi=1else{SPI_FLASH_DI_LOW();} //mosi=0for(j=0;j<3;j++); //延时SPI_FLASH_CLK_HIGH();for(j=0;j<5;j++);SPI_FLASH_CLK_LOW(); //clk=0if(TxData&0x01){SPI_FLASH_DI_HIGH();}else{SPI_FLASH_DI_LOW();}for(j=0;j<3;j++); //延时SPI_FLASH_CLK_HIGH(); //clk=1for(j=0;j<3;j++); //延时SPI_FLASH_CLK_LOW(); //clk=0}读程序0x80==0x80u8 SPIx_ReadByte(void){u8 i=0,j=0;for(j=0;j<3;j++); //延时SPI_FLASH_CLK_HIGH(); //clk=1if(GPIOC->IDR&0x80==0x80){i=i+0x80;}for(j=0;j<3;j++); //延时SPI_FLASH_CLK_LOW(); //clk=0,下降沿读数for(j=0;j<5;j++);SPI_FLASH_CLK_HIGH();if(GPIOC->IDR&0x80==0x80){i=i+0x40;}for(j=0;j<3;j++); //延时SPI_FLASH_CLK_LOW();for(j=0;j<5;j++);SPI_FLASH_CLK_HIGH();if(GPIOC->IDR&0x80==0x80){i=i+0x20;}for(j=0;j<3;j++); //延时SPI_FLASH_CLK_LOW();for(j=0;j<5;j++);SPI_FLASH_CLK_HIGH();if(GPIOC->IDR&0x80==0x80){i=i+0x10;}for(j=0;j<3;j++); //延时SPI_FLASH_CLK_LOW();for(j=0;j<5;j++);SPI_FLASH_CLK_HIGH();if(GPIOC->IDR&0x80==0x80){i=i+0x08;}for(j=0;j<3;j++); //延时SPI_FLASH_CLK_LOW();for(j=0;j<5;j++);SPI_FLASH_CLK_HIGH();if(GPIOC->IDR&0x80==0x80){i=i+0x04;}for(j=0;j<3;j++); //延时SPI_FLASH_CLK_LOW();for(j=0;j<5;j++);SPI_FLASH_CLK_HIGH();if(GPIOC->IDR&0x80==0x80){i=i+0x02;}for(j=0;j<3;j++); //延时SPI_FLASH_CLK_LOW();for(j=0;j<5;j++);SPI_FLASH_CLK_HIGH();if(GPIOC->IDR&0x80==0x80){i=i+0x01;}for(j=0;j<3;j++); //延时SPI_FLASH_CLK_LOW();return i;}读程序0x40==0x40u8 SPIx_ReadByte(void){u8 i=0,j=0;for(j=0;j<3;j++); //延时SPI_FLASH_CLK_HIGH(); //clk=1if(GPIOC->IDR&0x40==0x40){i=i+0x80;}for(j=0;j<3;j++); //延时SPI_FLASH_CLK_LOW(); //clk=0,下降沿读数for(j=0;j<5;j++);SPI_FLASH_CLK_HIGH();if(GPIOC->IDR&0x40==0x40){i=i+0x40;}for(j=0;j<3;j++); //延时SPI_FLASH_CLK_LOW();for(j=0;j<5;j++);SPI_FLASH_CLK_HIGH();if(GPIOC->IDR&0x40==0x40){i=i+0x20;}for(j=0;j<3;j++); //延时SPI_FLASH_CLK_LOW();for(j=0;j<5;j++);SPI_FLASH_CLK_HIGH();if(GPIOC->IDR&0x40==0x40){i=i+0x10;}for(j=0;j<3;j++); //延时SPI_FLASH_CLK_LOW();for(j=0;j<5;j++);SPI_FLASH_CLK_HIGH();if(GPIOC->IDR&0x40==0x40){i=i+0x08;}for(j=0;j<3;j++); //延时SPI_FLASH_CLK_LOW();for(j=0;j<5;j++);SPI_FLASH_CLK_HIGH();if(GPIOC->IDR&0x40==0x40){i=i+0x04;}for(j=0;j<3;j++); //延时SPI_FLASH_CLK_LOW();for(j=0;j<5;j++);SPI_FLASH_CLK_HIGH();if(GPIOC->IDR&0x40==0x40){i=i+0x02;}for(j=0;j<3;j++); //延时SPI_FLASH_CLK_LOW();for(j=0;j<5;j++);SPI_FLASH_CLK_HIGH();if(GPIOC->IDR&0x40==0x40){i=i+0x01;}for(j=0;j<3;j++); //延时SPI_FLASH_CLK_LOW();return i;}读程序0x20==0x20u8 SPIx_ReadByte(void){u8 i=0,j=0;for(j=0;j<3;j++); //延时SPI_FLASH_CLK_HIGH(); //clk=1if(GPIOC->IDR&0x20==0x20){i=i+0x80;}for(j=0;j<3;j++); //延时SPI_FLASH_CLK_LOW(); //clk=0,下降沿读数for(j=0;j<5;j++);SPI_FLASH_CLK_HIGH();if(GPIOC->IDR&0x20==0x20){i=i+0x40;}for(j=0;j<3;j++); //延时SPI_FLASH_CLK_LOW();for(j=0;j<5;j++);SPI_FLASH_CLK_HIGH();if(GPIOC->IDR&0x20==0x20){i=i+0x20;}for(j=0;j<3;j++); //延时SPI_FLASH_CLK_LOW();for(j=0;j<5;j++);SPI_FLASH_CLK_HIGH();if(GPIOC->IDR&0x20==0x20){i=i+0x10;}for(j=0;j<3;j++); //延时SPI_FLASH_CLK_LOW();for(j=0;j<5;j++);SPI_FLASH_CLK_HIGH();if(GPIOC->IDR&0x20==0x20){i=i+0x08;}for(j=0;j<3;j++); //延时SPI_FLASH_CLK_LOW();for(j=0;j<5;j++);SPI_FLASH_CLK_HIGH();if(GPIOC->IDR&0x20==0x20){i=i+0x04;}for(j=0;j<3;j++); //延时SPI_FLASH_CLK_LOW();for(j=0;j<5;j++);SPI_FLASH_CLK_HIGH();if(GPIOC->IDR&0x20==0x20){i=i+0x02;}for(j=0;j<3;j++); //延时SPI_FLASH_CLK_LOW();for(j=0;j<5;j++);SPI_FLASH_CLK_HIGH();if(GPIOC->IDR&0x20==0x20){i=i+0x01;}for(j=0;j<3;j++); //延时SPI_FLASH_CLK_LOW();return i;}读程序0x10==0x10读程序0x08==0x08读程序0x04==0x04读程序0x02==0x02u8 SPIx_ReadByte(void){u8 i=0,j=0;for(j=0;j<3;j++); //延时SPI_FLASH_CLK_HIGH(); //clk=1if(GPIOC->IDR&0x02==0x02){i=i+0x80;}for(j=0;j<3;j++); //延时SPI_FLASH_CLK_LOW(); //clk=0,下降沿读数for(j=0;j<5;j++);SPI_FLASH_CLK_HIGH();if(GPIOC->IDR&0x02==0x02){i=i+0x40;}for(j=0;j<3;j++); //延时SPI_FLASH_CLK_LOW();for(j=0;j<5;j++);SPI_FLASH_CLK_HIGH();if(GPIOC->IDR&0x02==0x02){i=i+0x20;}for(j=0;j<3;j++); //延时SPI_FLASH_CLK_LOW();for(j=0;j<5;j++);SPI_FLASH_CLK_HIGH();if(GPIOC->IDR&0x02==0x02){i=i+0x10;}for(j=0;j<3;j++); //延时SPI_FLASH_CLK_LOW();for(j=0;j<5;j++);SPI_FLASH_CLK_HIGH();if(GPIOC->IDR&0x02==0x02){i=i+0x08;}for(j=0;j<3;j++); //延时SPI_FLASH_CLK_LOW();for(j=0;j<5;j++);SPI_FLASH_CLK_HIGH();if(GPIOC->IDR&0x02==0x02){i=i+0x04;}for(j=0;j<3;j++); //延时SPI_FLASH_CLK_LOW();for(j=0;j<5;j++);SPI_FLASH_CLK_HIGH();if(GPIOC->IDR&0x02==0x02){i=i+0x02;}for(j=0;j<3;j++); //延时SPI_FLASH_CLK_LOW();for(j=0;j<5;j++);SPI_FLASH_CLK_HIGH();if(GPIOC->IDR&0x02==0x02){i=i+0x01;}for(j=0;j<3;j++); //延时SPI_FLASH_CLK_LOW();return i;}读程序0x01==0x01u8 SPIx_ReadByte(void){u8 i=0,j=0;for(j=0;j<3;j++); //延时SPI_FLASH_CLK_HIGH(); //clk=1if(GPIOC->IDR&0x01==0x01){i=i+0x80;}for(j=0;j<3;j++); //延时SPI_FLASH_CLK_LOW(); //clk=0,下降沿读数for(j=0;j<5;j++);SPI_FLASH_CLK_HIGH();if(GPIOC->IDR&0x01==0x01){i=i+0x40;}for(j=0;j<3;j++); //延时SPI_FLASH_CLK_LOW();for(j=0;j<5;j++);SPI_FLASH_CLK_HIGH();if(GPIOC->IDR&0x01==0x01){i=i+0x20;}for(j=0;j<3;j++); //延时SPI_FLASH_CLK_LOW();for(j=0;j<5;j++);SPI_FLASH_CLK_HIGH();if(GPIOC->IDR&0x01==0x01){i=i+0x10;}for(j=0;j<3;j++); //延时SPI_FLASH_CLK_LOW();for(j=0;j<5;j++);SPI_FLASH_CLK_HIGH();if(GPIOC->IDR&0x01==0x01){i=i+0x08;}for(j=0;j<3;j++); //延时SPI_FLASH_CLK_LOW();for(j=0;j<5;j++);SPI_FLASH_CLK_HIGH();if(GPIOC->IDR&0x01==0x01){i=i+0x04;}for(j=0;j<3;j++); //延时SPI_FLASH_CLK_LOW();for(j=0;j<5;j++);SPI_FLASH_CLK_HIGH();if(GPIOC->IDR&0x01==0x01){i=i+0x02;}for(j=0;j<3;j++); //延时SPI_FLASH_CLK_LOW();for(j=0;j<5;j++);SPI_FLASH_CLK_HIGH();if(GPIOC->IDR&0x01==0x01){i=i+0x01;}for(j=0;j<3;j++); //延时SPI_FLASH_CLK_LOW();return i;}。