SPI读取EEPROM用的比较少,这个程序可以借鉴一下
单片机源程序如下:
- #include "stm32f10x.h"
- #include "25LC512.h"
- #include "delay.h"
- #include "led.h"
- //PB5-mosi;PB3-clk;PA15-cs;PB4-miso;//
- void LC512_Init(void)
- {
- GPIO_InitTypeDef GPIO_InitStructure;
- RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB|RCC_APB2Periph_GPIOA, ENABLE);
-
- /*PB3默认JTAG,需要先禁用再作为普通IO*/
- RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE);
- GPIO_PinRemapConfig(GPIO_Remap_SWJ_JTAGDisable, ENABLE);
- DBGMCU->CR &= ~((uint32_t)1<<5);
- AFIO->MAPR = (AFIO->MAPR & ~((uint32_t)0x7 << 24)) | (2 << 24); /* PA15 PB3 PB4 */
-
- GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5;
- GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;//推挽输出
- GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;//50MHz
- GPIO_Init(GPIOB, &GPIO_InitStructure);//初始化
-
- GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3;
- GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;//推挽输出
- GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;//50MHz
- GPIO_Init(GPIOB, &GPIO_InitStructure);//初始化
-
- GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4;//PB4
- GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPD;//输入
- GPIO_Init(GPIOB, &GPIO_InitStructure);//初始化
-
- GPIO_InitStructure.GPIO_Pin = GPIO_Pin_15;//PA15
- GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;//复用推挽输出
- GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;//50MHz
- GPIO_Init(GPIOA, &GPIO_InitStructure);//初始化
-
-
- }
- //初始化芯片
- void init(void) // void main(void)第一个void表示函数没有返回值,第二个表示不带任何有实际意义的参数
- {
- cs = 1;
- // miso = 0;
- mosi = 1;
- clk = 1;
- }
- void delay(u8 t) //延时
- {
- u8 i,j;
- for(i = t;i > 0;i --)
- for(j =0 ;j < 10;j ++)
- {;;}
- }
- //write commend enable or disable signal
- void spi_wren(u8 wren_com) //write enable wren_com=0x06 设置写使能0000 0110
- {
- u8 i;
- u8 dig;
- cs=0;
- delay_us(10);
-
- for(i=0;i<8;i++)
- {
- clk=0;
- delay_us(10);
- dig=wren_com>>7;
- if(dig)
- { mosi=1;}
- else
- {mosi=0;}
- wren_com=wren_com<<1;
- clk=1;
- delay_us(10);
- }
-
- delay_us(10);
- //mosi = 0; //mosi=0,scl=0,when 8 bit data move over
- clk = 1;
- cs = 1;
- delay_us(10);
-
- }
-
-
- void spi_wrdi(u8 wrdi_com) //write disable wr_com=0x04 设置写不使能0000 0100
- {
- u8 i;
- u8 dig;
- cs=0;
- delay_us(10);
-
- for(i=0;i<8;i++)
- {
- clk=0;
- delay_us(10);
- dig=wrdi_com>>7;
- if(dig)
- { mosi=1;}
- else
- {mosi=0;}
- wrdi_com=wrdi_com<<1;
- clk=1;
- delay_us(10);
- }
- delay_us(10);
- //mosi = 0; //mosi=0,scl=0,when 8 bit data move over
- clk = 1;
- cs = 1;
- delay_us(10);
- }
- //byte write 0000 0010
- void spi_byte_write(u8 wr_byte_com,u16 wr_addr,u8 wr_dat) //write 1 btye data
- {
- u8 i,dig;
- u16 j;
- cs=0;
- //delay_us(10);
-
- for(i=0;i<8;i++)
- {
- clk=0;
- //delay_us(10);
- dig=wr_byte_com>>7;
- if(dig)
- { mosi=1;}
- else
- {mosi=0;}
- wr_byte_com=wr_byte_com<<1;
- clk=1;
- delay_us(1);
- }
- delay_us(1);
- clk = 1;
-
-
- for(j=0;j<16;j++)
- {
- clk=0;
- //delay_us(10);
- dig=wr_addr>>15; // output instruction code "0x02"
- if(dig)
- { mosi=1;}
- else
- {mosi=0;}
- wr_addr=wr_addr<<1;
- clk=1;
- delay_us(1);
- }
- delay_us(1);
- clk = 1;
-
-
- for(i=0;i<8;i++)
- {
- clk=0;
- //delay_us(10);
- dig=wr_dat>>7;
- if(dig)
- { mosi=1;}
- else
- {mosi=0;}
- wr_dat=wr_dat<<1;
- clk=1;
- delay_us(1);
- }
- delay_us(1);
- // mosi = 0;
- clk = 1;
- cs = 1;
- // check_wip(); //要有检测写入是否结束函数
- }
- /*
- function name:spi_page write
- //write 8 btye data
- */
- void spi_page_write(u8 wr_page_com,u16 wr_addr,u8 len,u8 *pwr_dat)
- {
- u8 i,dig,n;
- u16 j;
- cs=0;
- //delay_us(10);
- for(i=0;i<8;i++)
- {
- clk=0;
- //delay_us(10);
- dig=wr_page_com&0x80;
- if(dig)
- {mosi=1;}
- else
- {mosi=0;}
- wr_page_com=wr_page_com<<1;
- clk=1;
- delay_us(1);
- }
- delay_us(1);
- clk = 1;
-
-
- for(j=0;j<16;j++)
- {
- clk=0;
- // delay_us(10);
- dig=wr_addr>>15; // output instruction code "0x02"
- if(dig)
- { mosi=1;}
- else
- {mosi=0;}
- wr_addr=wr_addr<<1;
- clk=1;
- delay_us(1);
- }
- delay_us(1);
- clk = 1;
-
- for(n=0;n<len;n++)
- {
- for(i=0;i<8;i++)
- {
- clk=0;
- // delay_us(10);
- dig= pwr_dat[n]&0x80;
- if(dig)
- { mosi=1;}
- else
- {mosi=0;}
- pwr_dat[n]=pwr_dat[n]<<1;
- clk=1;
- delay_us(1);
- }
- delay_us(1);
- clk=1;
-
- }
- delay_us(1);
- //mosi = 0;
- clk = 1;
- cs = 1;
- check_wip(); //要有检测写入是否结束函数
-
- }
-
- //read a byte data 0000 0011
- u8 spi_byte_read(u8 read_com,u16 read_addr)
- {
- u8 read_dat,i,dig;
- u16 j;
- cs=0;
- //delay_us(10);
- for(i=0;i<8;i++)
- {
- clk=0;
- //delay_us(10);
- dig=read_com>>7;
- if(dig)
- { mosi=1;}
- else
- {mosi=0;}
- read_com=read_com<<1;
- clk=1;
- delay_us(1);
- }
-
- delay_us(1);
- clk = 1;
-
- for(j=0;j<16;j++)
- {
- clk=0;
- //delay_us(10);
- dig=read_addr>>15; // output instruction code "0x02"
- if(dig)
- { mosi=1;}
- else
- {mosi=0;}
- read_addr=read_addr<<1;
- clk=1;
- delay_us(1);
- }
- delay_us(1);
- clk = 1;
-
-
- for(i=0;i<8;i++)
- {
- clk=1;
- //delay_us(10);
- read_dat = read_dat << 1;
- clk=0;
- //delay_us(10);
- //moso2=GPIO_ReadInputDataBit(GPIOE,GPIO_Pin_15); //读取输出口电平高低
- read_dat|=moso;
- delay_us(1);
- }
-
- delay_us(1);
- clk = 1;
- cs = 1;
-
- return read_dat;
-
- }
- // page read
- u8* spi_page_read(u8 read_com,u8 len,u16 wr_addr)
- {
-
- u8 rd_page_dat,i,dig,n,read_dat[128]={0},*read_out;
- u16 j;
- // miso=0;
- cs=0;
- // delay_us(10);
- for(i=0;i<8;i++)
- {
- clk=0;
- // delay_us(10);
- dig=read_com>>7;
- if(dig)
- { mosi=1;}
- else
- {mosi=0;}
- read_com=read_com<<1;
- clk=1;
- delay_us(1);
- }
- clk = 1;
- delay_us(1);
- //mosi=0;
- for(j=0;j<16;j++)
- {
- clk=0;
- // delay_us(10);
- dig=wr_addr>>15;
- if(dig)
- { mosi=1;}
- else
- {mosi=0;}
- wr_addr=wr_addr<<1;
- clk=1;
- delay_us(1);
- }
- //mosi=0;
- clk = 1;
- delay_us(1);
-
- for(n = 0;n < len;n ++)
- {
- rd_page_dat = read_dat[n];
- for(i=0;i<8;i++)
- {
- clk=1;
- delay_us(1);
- rd_page_dat = rd_page_dat<< 1;
- clk=0;
- //delay_us(10);
- //moso2=GPIO_ReadInputDataBit(GPIOE,GPIO_Pin_15);//读取输出口电平高低
- rd_page_dat|=moso;
- delay_us(1);
- }
- read_dat[n]=rd_page_dat;
- }
-
- clk = 1;
- cs = 1;
- delay_us(1);
- read_out=read_dat;
- return read_out;
-
- }
- //write status 写入状态 设置status register状态寄存器写入0000 0001以及要写入的数据wrsr-dat
- void spi_wrsr(u8 wrsr_com,u8 wrsr_dat)
- {
- u8 i;
- u8 dig;
- cs=0;
- delay_us(10);
- for(i=0;i<8;i++)
- {
- clk=0;
- delay_us(10);
- dig=wrsr_com>>7; //write status instruction is 0x01
- if(dig)
- { mosi=1;}
- else
- {mosi=0;}
- wrsr_com=wrsr_com<<1;
- clk=1;
- delay_us(10);
- }
-
- clk = 1;
- delay_us(10);
- for(i=0;i<8;i++)
- {
- clk=0;
- delay_us(10);
- dig=wrsr_dat>>7;
- if(dig)
- { mosi=1;}
- else
- {mosi=0;}
- wrsr_dat=wrsr_dat<<1;
- clk=1;
- delay_us(10);
- }
-
- //mosi = 0;
- clk = 1;
- cs = 1;
- delay_us(10);
- }
-
- //read status 0000 0101
- u8 spi_rdsr(u8 wdsr_com)
- {
- u8 dig;
- u8 read_status,i;
-
- cs=0;
- delay_us(10);
- for(i=0;i<8;i++)
- {
- clk=0;
- delay_us(10);
- dig=wdsr_com>>7; // first write instruction to mosi 0x05
- if(dig)
- { mosi=1;}
- else
- {mosi=0;}
- wdsr_com=wdsr_com<<1;
- clk=1;
- delay_us(10);
- }
- clk = 1;
- delay_us(10);
- for(i=0;i<8;i++)
- {
- clk=1;
- delay_us(10);
- read_status = read_status << 1;
- clk=0;
- delay_us(10);
- //moso2=GPIO_ReadInputDataBit(GPIOE,GPIO_Pin_15); //读取输出口电平高低
- read_status|=moso;
- delay_us(10);
- }
-
- clk = 1;
- cs = 1;
- delay_us(10);
- return read_status;
- }
- // check status register wip bit
- void check_wip(void)
- {
- u8 temp,wip;
- do{
- temp=spi_rdsr(0x05);
- wip = temp <<7;
- }while(wip);
- }
-
- // page erase only used to 512K EEPROM spi PE擦除,0100 0010,以及地址
- void spi_page_erase(u8 page_erase_com,u16 wr_addr)
- {
- u8 i,dig;
- u16 j;
- cs=0;
-
- for(i=0;i<8;i++)
- {
- clk=0;
- dig=page_erase_com&0x80;
- if(dig)
- { mosi=1;}
- else
- {mosi=0;}
- page_erase_com=page_erase_com<<1;
- clk=1;
- delay_us(1);
- }
- delay_us(1);
- clk = 0;
-
- for(j=0;j<16;j++)
- {
- clk=0;
- dig=wr_addr&0x8000; //write address high 16 bit 0x0000
- if(dig)
- { mosi=1;}
- else
- {mosi=0;}
- wr_addr=wr_addr<<1;
- clk=1;
- delay_us(1);
- }
- delay_us(1);
- mosi = 0;
- clk = 0;
- cs = 1;
- check_wip(); //要有检测写入是否结束函数
- }
- //sector erase 扇区擦除 SE擦除1101 1000,以及地址
- void spi_sector_erase(u8 sector_erase_com,u16 wr_addr)
- {
- u8 i,dig;
- u16 j;
- cs=0;
-
- for(i=0;i<8;i++)
- {
- clk=0;
- dig=sector_erase_com&0x80;
- if(dig)
- { mosi=1;}
- else
- {mosi=0;}
- sector_erase_com=sector_erase_com<<1;
- clk=1;
- delay_us(1);
- }
- delay_us(1);
- clk = 0;
-
- for(j=0;j<16;j++)
- {
- clk=0;
- dig=wr_addr&0x8000;
- if(dig)
- { mosi=1;}
- else
- {mosi=0;}
- wr_addr=wr_addr<<1;
- clk=1;
- delay_us(1);
- }
- delay_us(1);
- mosi = 0;
- clk = 0;
- cs = 1;
- check_wip(); //要有检测写入是否结束函数
- }
- //chip erase 芯片擦除 CE擦除1100 0111
- void spi_chip_erase(u8 chip_com)
- {
- u8 i;
- u8 dig;
- cs=0;
-
- for(i=0;i<8;i++)
- {
- clk=0;
- dig=chip_com&0x80;
- if(dig)
- ……………………
- …………限于本文篇幅 余下代码请从51黑下载附件…………
复制代码
- //#include "led.h"
- #include "delay.h"
- //#include "key.h"
- #include "sys.h"
- //#include "lcd.h"
- #include "usart.h"
- #include "25LC512.h"
- //#include "spi.h"
- int main(void)
- {
- u8 pw_dat[8]={0xFF,0x00,0x01,0x09,0x10,0x01,0x00,0xDD},*pwr_dat1,*pwr_dat2;
- u8 i=0;
- u8 rxbuf[8]={0};
- u8 rxbuf1[4]={0};
- u8 rxbuf2[4]={0};
- NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);//设置系统中断优先级分组2
- delay_init(); //初始化延时函数
- uart_init(115200); //初始化串口波特率为115200
- // RS485_Init(9600); //初始化RS485串口2
- LC512_Init();
- init();
- //spi_wrsr(0x01,0x03);
-
- printf("Data to Send:\r\n");
- for(i=0;i<8;i++)
- {
- printf("%x\t", pw_dat[i]);
- }
- printf("\r\n");
- spi_wren(0x06); //write enable 0x06
- spi_page_write(write,0x0001,8,pw_dat);
- // spi_wrsr(0x01,0x01); //write status register 0x01 no write protect 0x00
- // spi_byte_write(write,0x0010,0x10); //write address1 0x00 address 0x00 and data 0x55
- // spi_byte_write(write,0x0009,0x55);
- // delay_ms(1000);
- // spi_wren(0x06);
- // spi_byte_write(write,0x000a,0x0a);
- // delay_ms(1000);
- // spi_wren(0x06);
- // spi_byte_write(write,0x000b,0x0b);
- // spi_wren(0x06);
- // delay_ms(1000);
-
- // *rs485buf=*pw_dat;
- // spi_wrdi(wrdi); // write disable 0x04
- // spi_page_read(0x01,0x01);
- // P1 = spi_byte_read(read,0x0009);
- // spi_page_erase(pe,0x0001);
- // spi_sector_erase(se,addr);
- // spi_chip_erase(ce);
- // spi_deep_power_down_mode(dpd);
- pwr_dat1=spi_page_read(read,4,0x0001);
- for(i=0;i<4;i++)
- {
- rxbuf1[i]=*(pwr_dat1+i);
- rxbuf[i]=rxbuf1[i];
- }
-
- pwr_dat2=spi_page_read(read,4,0x0005);
- for(i=0;i<4;i++)
- {
- rxbuf2[i]=*(pwr_dat2+i);
- rxbuf[i+4]=rxbuf2[i];
- }
- printf("Read Data:\r\n");
- for(i=0;i<8;i++)
- {
- printf("%x\t",rxbuf[i]);
- }
- printf("\r\n");
- // rs485buf[0]=spi_byte_read(read,0x0020);
- // rs485buf[0]=spi_byte_read(read,0x0001);
- // rs485buf[1]=spi_byte_read(read,0x0002);
- // rs485buf[2]=spi_byte_read(read,0x0003);
- delay_ms(1000);
- }
复制代码
所有资料51hei提供下载:
SPI读取EEPROM.zip
(374.46 KB, 下载次数: 75)
|