|
51单片机读写25X16程序,简单昨懂
全部源码下载:
51读写W25X16程序.rar
(45.03 KB, 下载次数: 54)
预览:
- #include <intrins.h> //包含位移和_nop_();
- #include "STC12C5A60S2.H"
- //***************************************************************
- void WriteDisable (void); //写禁止
- void WriteEnable (void); //写允许
- unsigned char W25X_BUSY_OrNot (void); //判忙碌
- void W25X_ChipErase(void); //片擦除
- void W25X_BlockErase(unsigned long Addre24);
- void W25X_SectorErase(unsigned long Addre24); //擦除资料图示的4KB空间
- //读数据可以无限次,这里是由缓冲决定的大小
- void W25X_Flash_Byte_Read (unsigned long Addre24,unsigned char Quantity);//多字节读FLASH(1~256) -W25X32-000000-3FFF00(4M)-
- void W25X_Flash_Byte_Write(unsigned long Addre24,unsigned char Quantity); //往FLASH里写一个或多个字节(小于256字节)
- unsigned char Read_OneByte(void); //从SPI收8位数
- void Send_OneByte(unsigned char DATA8);
- void InitSerial(void); //串行口初始化.通信速率9600bps 在22.1184MHz晶振频率
- void Delay100ms(unsigned int _100ms); //100ms级延时
- //进度: 发一个指令OK 写允许OK 读状态OK 读写一个字节OK
- unsigned char xdata Send_DATA[256]; //要发送的数据
- unsigned char xdata Recv_DATA[256]; //已接收的数据, 如2个数,则为Recv_DATA[0] Recv_DATA[1]
- unsigned char * Send_Pionter;
- unsigned char * Recv_Pionter;
- void main()
- {
- unsigned char BUSY; //判忙碌
- unsigned long Addre24; //24位的Flash地址
- unsigned char x=0;
- unsigned char A;
- unsigned char B;
- unsigned char C;
- unsigned long D;
- //************************
- A=0; B=0; C=0; D=0;
- Delay100ms(2);
- if(x)
- {
- WriteDisable (); //写禁止
- W25X_ChipErase(); //片擦除
- W25X_SectorErase(Addre24); //4K擦除
- W25X_BlockErase (Addre24); //64K块擦除
- BUSY=W25X_BUSY_OrNot(); //判忙碌
- W25X_Flash_Byte_Read (Addre24,21); //读FLASH
- W25X_Flash_Byte_Write(Addre24,21); //写入
- }
- //*************************
- P1M0=0xB0;
- InitSerial(); //串行口初始化.通信速率9600bps 在22.1184MHz晶振频率
- Send_Pionter = &Send_DATA[0]; //发送指针取地址
- Recv_Pionter = &Recv_DATA[0]; //接收指针取地址
- for (D=0;D<256;D++)
- {
- Send_DATA[D]=D;
- Recv_DATA[D]=0;
- }
- W25X_SectorErase(Addre24); Delay100ms (4); //4K擦除
-
- //**************************
-
- W25X_Flash_Byte_Write(0x000000,255); //写N个数
- W25X_Flash_Byte_Read (0x000000,255); //读X个数
-
- while(1)
- {
- SBUF =A;
- while(TI==0);
- TI=0;
- SBUF =Recv_DATA[A] ;
- while(TI==0);
- TI=0;
- Delay100ms(1);
- A++;
- }
- } // End of Main
- //*******************END of Main****************************
- // ----W25X系统Flash读写---SUNYA注----
- //sbit CS = P1^4; //选通
- //sbit DIO = P1^5; //单片机输出
- //sbit DO = P1^6; //FLASH输出
- //sbit SCLK = P1^7; //时钟
- //读写SPI口模拟模式3,时钟平时为高电平
- //#define W25X_ReadStatus 0x05 //读状态寄存器
- //#define W25X_WriteStatus 0x01 //写状态寄存器
- //#define W25X_ReadDATA8 0x03 //普读_数据
- //#define W25X_FastRead 0x0B //快读_数据
- //#define W25X_DualOutput 0x3B //快读_双输出
- //#define W25X_Write 0x02 //写_数据_0~255个字节
- //#define W25X_S_Erase 0x20 //扇区擦除4KB
- //#define W25X_B_Erase 0xD8 //块区擦除64KB
- //#define W25X_C_Erase 0xC7 //整片格式化
- //#define W25X_PowerDown 0xB9 //待机
- //#define W25X_PowerON_ID 0xAB //开机或是读ID
- //#define W25X_JEDEC_ID 0x9F //十六位的JEDEC_ID
- //#define W25X_WriteEnable 0x06 //写充许
- //#define W25X_WriteDisable 0x04 //写禁止
- //#define W25X_BUSY 0x01 //FLASH忙
- //#define W25X_NotBUSY 0x00 //FLASH闲 这是自定义的
- //***************判BUSY********************************
- unsigned char W25X_BUSY_OrNot (void) //在读和写之前得先判断FLASH是否BUSY
- { //BUSY的原因是擦除,或是连续读写
- unsigned char k; //如果没有以上方式,不必判定可以写读
- SCLK=1;
- _nop_();
- CS=0;
- Send_OneByte(W25X_ReadStatus); //读状态寄存器
- k=Read_OneByte(); //读一个字节
- k=k&0x01;
- CS=1;_nop_();
- SCLK=1;
- if(k)return (W25X_BUSY);
- else return (W25X_NotBUSY);
- } //end of check BUSY
- //***********************************************
- void W25X_Flash_Byte_Write(unsigned long Addre24,unsigned char Quantity) //往FLASH里写一个或多个字节(小于255)
- { //连续写的时候,地址最后八位必须从00开始写 *如果256个字节都读满或写满,三字节地址最后一个字节必须为0*
- unsigned char Addre3; //否则当地址越过分面时,会从本页的00从新开始,造成错写
- unsigned char Addre2; //^^现在本函数没启用连写连读
- unsigned char Addre1;
- unsigned char J; //计字节数
- unsigned char x;
- while(W25X_BUSY_OrNot ()); //判BUSY 等到Flash闲才能操作
- WriteEnable(); //写允许
- SCLK=1;
- Addre1=Addre24;
- Addre24=Addre24>>8;
- Addre2=Addre24;
- Addre24=Addre24>>8;
- Addre3=Addre24; //把地址拆开来
-
- CS=0;
- Send_OneByte(W25X_Write); //命令
- Send_OneByte(Addre3);
- Send_OneByte(Addre2);
- Send_OneByte(Addre1);
- for (J=0;J<Quantity;J++)
- {
- Send_OneByte(Send_DATA[J]); //写字节
- }
- CS=1;
- _nop_();_nop_();
- SCLK=1;
- for(x=0;x<200;x++) //延时一点点
- {
- _nop_();_nop_();
- }
- Addre24=0; //地址清0
- } //写FLASH结束
- //***********************************************
- void W25X_Flash_Byte_Read (unsigned long Addre24,unsigned char Quantity) //从Flash里读出小于256字节数
- {
- unsigned char xdata DATA8[256]; //要返回的字节
- unsigned char * DATA; //定义一个指针
- unsigned char J; //计字节数
- unsigned char Addre3;
- unsigned char Addre2;
- unsigned char Addre1;
-
- while(W25X_BUSY_OrNot ()); //判BUSY
- DATA=&DATA8[0]; //指针指向DATA8[256]
- Addre1=Addre24;
- Addre24=Addre24>>8;
- Addre2=Addre24;
- Addre24=Addre24>>8;
- Addre3=Addre24; //把地址拆开来
-
- CS=0;
- Send_OneByte(W25X_ReadDATA8);//命令读
- Send_OneByte(Addre3);
- Send_OneByte(Addre2);
- Send_OneByte(Addre1);
- for (J=0;J<Quantity;J++)
- {
- Recv_DATA[J]=Read_OneByte(); //读一个字节
- }
- CS=1;
- _nop_();_nop_();
- SCLK=1;
- _nop_();_nop_();
- Addre24=0; //地址清0
- } //读FLASH结束
- //*********************************************** OK
- void Send_OneByte(unsigned char DATA8) //从SPI发8位数
- { //上升沿写入
- unsigned char x;
-
- for (x=0;x<8;x++)
- {
- SCLK=0;
- if(DATA8&0x80)DIO=1;
- else DIO=0;
- SCLK=1;
- DATA8=DATA8<<1;
- }
- //发完后SCLK为1
- } //end of Send_OneByte
- //*********************************************** OK
- unsigned char Read_OneByte(void) //从SPI收8位数
- { //下降沿输出
- unsigned char DATA8;
- unsigned char x;
- SCLK=1;
- DATA8=0x00;
- for (x=0;x<8;x++)
- {
- _nop_();
- SCLK=0;
- DATA8=DATA8<<1;
- if(DO)DATA8=DATA8|0x01;
- SCLK=1;
- }
- return (DATA8);
- //完成后SCLK=1
- }//end of Read_OneByte
- //**************片擦除 (MAX_80S)****************** OK
- void W25X_ChipErase(void)
- {
- //BUSY ?
- WriteEnable(); //写允许
- SCLK=1;
- CS=0;
- Send_OneByte(W25X_C_Erase);//整片擦除命令
- CS=1; //从CS=1时开始执行擦除
- SCLK=1;
- }
- //*************** 4K扇擦除************************ OK
- void W25X_SectorErase(unsigned long Addre24) //擦除资料图示的4KB空间
- {
- //判BUSY或许放这里
- unsigned char Addre3;
- unsigned char Addre2;
- unsigned char Addre1;
- WriteEnable(); //写允许
- Addre1=Addre24;
- Addre24=Addre24>>8;
- Addre2=Addre24;
- Addre24=Addre24>>8;
- Addre3=Addre24; //把地址拆开来
- SCLK=1;
- CS=0;
- Send_OneByte(W25X_S_Erase);//整扇擦除命令
- Send_OneByte(Addre3);
- Send_OneByte(Addre2);
- Send_OneByte(Addre1);
- CS=1;
- _nop_();
- SCLK=1;
- _nop_();_nop_();
- Addre24=0; //地址清0
- }
- //*************** 64K页/块擦除************************* OK
- void W25X_BlockErase(unsigned long Addre24) //擦除资料图示的64KB空间
- {
- //判BUSY或许放这里
- unsigned char Addre3;
- unsigned char Addre2;
- unsigned char Addre1;
- WriteEnable(); //写允许
- Addre1=Addre24;
- Addre24=Addre24>>8;
- Addre2=Addre24;
- Addre24=Addre24>>8;
- Addre3=Addre24; //把地址拆开来
- SCLK=1;
- CS=0;
- Send_OneByte(W25X_B_Erase);//整扇擦除命令
- Send_OneByte(Addre3);
- Send_OneByte(Addre2);
- Send_OneByte(Addre1);
- CS=1;
- _nop_();_nop_();
- SCLK=1;
- _nop_();_nop_();
- Addre24=0; //地址清0
- }
- //*************** 写允许 **************************** OK
- void WriteEnable (void)
- {
- SCLK=1;
- CS=0;
- Send_OneByte(W25X_WriteEnable);
- CS=1;
- SCLK=1;
- }
- //*************** 写禁止 **************************** OK
- void WriteDisable (void)
- {
- SCLK=1;
- CS=0;
- Send_OneByte(W25X_WriteDisable);
- CS=1;
- SCLK=1;
- }
- //******************************************************** OK
- void Delay100ms(unsigned int _100ms) //100ms级延时
- {
- unsigned char n,i,ms,loop;
- for(loop=12;loop>0;loop--) //STC12C5412AD为快速单片机,此100ms延时要快6倍
- { ms=_100ms; //晶体为11.0592MHz
- for(;ms>0;ms--)
- for(n=145;n>0;n--)
- for(i=251;i>0;i--)_nop_();
- }
- }
- //***************************************//串行口初始化 OK
- void InitSerial(void) //串行口初始化.通信速率9600bps 在22.1184MHz晶振频率
- {
- SCON = 0x50;
- BRT = 250;
- AUXR = 0x11; //使用独立波特率发生器
- AUXR1= 0x80;
- ES=1;
- EA=1;
- /*
- TR1=0;
- ET1=0; //定时器1禁止中断
- TMOD=TMOD&0xCF;
- TMOD=TMOD|0x20; //通信方式2
- TH1=0xFF; //波特率:bps
- TL1=0xFF; //1位起始位,8位数据位,2位停止位,无校验
- SCON=0xD8;
- PCON=0x80;
- TR1=1; //开启定时
- ES=1;
- */
- //IE=IE|0x90; //开中断,允许串口中断
- }
- //***************************************************************
复制代码
|
评分
-
查看全部评分
|