打印
[方案相关]

HC32F460单片机写SPIFlash

[复制链接]
2765|2
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
zengxing3624|  楼主 | 2021-11-11 15:49 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
项目中需要用到一片SPIFlash,我用的是SST25VF016B,用单片机自带的SPI接口几天一直没弄通,索性就直接用IO来模拟,以下是代码,也欢迎用SPI接口弄通的兄弟指教。#include "hc32_ddl.h"



#define uchar unsigned char
#define uint unsigned int
#define ulong   unsigned long          
///////////引脚定义

#define  SPI_CLK_Port        (PortC)
#define  SPI_CLK_Pin         (Pin03)

#define  SPI_MISO_Port        (PortC)
#define  SPI_MISO_Pin         (Pin02)

#define  SPI_MISI_Port        (PortC)
#define  SPI_MISI_Pin         (Pin01)

#define  SPI_CS_Port        (PortC)
#define  SPI_CS_Pin         (Pin00)

#define  SPI_WR_Port        (PortC)
#define  SPI_WR_Pin         (Pin15)






char dat[10]={1,2,3,4,5,6,7,8,9,1};
char add[3]={1,0,1};
char R_dat[10];
char num;

void Flash_init()  ;          /* 程序功能:    用来将时钟线初始化为低. 必须在将设备设置为模式0之前调用*/
void Flash_WRSR(uchar byte)  ;//写状态寄存器
uchar Flash_Read_Status_Register(void);   //读状态寄存器的值
void Flash_WREN_Check(void)  ;                  /* 功能: 检查擦写操作前WEL位是否为1  */   
void  Flash_WREN(void) ;           //写使能命令
void Flash_Sector_Erase(ulong Dst) ;  /* 功能: Sector Erases the Chip.     4K         */
void Flash_Wait_Busy(void)  ;//等待 FLASH空闲
void Flash_Chip_Erase(void)   ;           /* 功能: 擦除整个芯片               */  
void Flash_Block_Erase_32K(ulong Dst) ;  /* 功能: Block Erases 32 KByte of the Chip.           */
void Flash_Block_Erase_64K(ulong Dst) ;
void Flash_EWSR(void) ; //;使能改写状态寄存器
void   Flash_WRDI(void)   ;//        禁止写使能

void Flash_Send_Byte(uchar dat) ;//发送一个数据char 型 的  从51到FLASH
uchar  Flash_Get_Byte(void);// 接收一个char型的数据         51接收
uchar  Flash_Read(ulong Dst);//读取一个措定地址内的一个数据  作为函数返回值
void Flash_Write(ulong Dst,uchar dat);        //向flash 内的一个地址内写入一个数据

void Flash_Write_data(uchar  add[],uchar dat[],uchar size);        //向flash 内的一个基地址 add[3],add[0]放地址高八位         内写入size个数据。

//向从flash 内的一个基地址 add[3],add[0]放地址高八位         内读出size个数据。           放到dat[]中
void Flash_Read_data(uchar  add[],uchar R_dat[],uchar size);

//向从flash 内的一个基地址 add,      内读出size个数据。           放到dat[]中
void Flash_Read_data_add(ulong Dst,uchar R_dat[],uchar size);
void Flash_Write_data_add(ulong Dst,uchar dat[],uchar size);//向flash 内的一个基地址 add   








////////////////////////////////////SPI读写驱动////////////////////////////////////////////////////////////////////////////////
void Flash_Send_Byte(uchar dat) //发送一个数据char 型 的  从51到FLASH
{
uchar i;
PORT_ResetBits(SPI_CLK_Port,SPI_CLK_Pin);
PORT_ResetBits(SPI_CS_Port,SPI_CS_Pin);
for(i=0;i<8;i++)
    {
      if(dat & 0x80)
         {
             PORT_SetBits(SPI_MISI_Port,SPI_MISI_Pin);
         }
      else
             PORT_ResetBits(SPI_MISI_Port,SPI_MISI_Pin);
        dat<<=1;
        PORT_SetBits(SPI_CLK_Port,SPI_CLK_Pin);           //信号拉高读进数据
        Ddl_Delay1us(1);

            PORT_ResetBits(SPI_CLK_Port,SPI_CLK_Pin);    //将信号拉低
        Ddl_Delay1us(1) ;   
      }
PORT_ResetBits(SPI_CLK_Port,SPI_CLK_Pin);
}

uchar Flash_Get_Byte(void)   //接收一个char型的数据
{
uchar i;
uchar one_data=0;
PORT_ResetBits(SPI_CS_Port,SPI_CS_Pin);
// PORT_SetBits(SPI_CLK_Port,SPI_CLK_Pin;
for(i=0;i<8;i++)
{         
        one_data=one_data<<1;
        PORT_ResetBits(SPI_CLK_Port,SPI_CLK_Pin);
        Ddl_Delay1us(1);
           Ddl_Delay1us(1);
         if(PORT_GetBit(SPI_MISO_Port,SPI_MISO_Pin)==1)
         {
         one_data=one_data | 0x01;
         }
    PORT_SetBits(SPI_CLK_Port,SPI_CLK_Pin);
    Ddl_Delay1us(1)        ;
}
PORT_ResetBits(SPI_CLK_Port,SPI_CLK_Pin);
//CS=1;
return one_data;
}

/************************************************************************/   
        /* 名称: Read                         */     
        /* 功能: 读取一个地址内一个字节的数据.返回读取的数据*/   
        /* 输入:      Dst:    Destination Address 000000H - 1FFFFFH       */   
        /* 返回:      byte                            */   
        /************************************************************************/   
uchar Flash_Read(ulong Dst)   
        {   
            uchar byte = 0;
               
                PORT_SetBits(SPI_CLK_Port,SPI_CLK_Pin);   
            PORT_ResetBits(SPI_CS_Port,SPI_CS_Pin);  
                        /* enable device */   
            Flash_Send_Byte(0x03);        /* read command */   
            Flash_Send_Byte(((Dst & 0xFFFFFF) >> 16));  /* send 3 address bytes */   
            Flash_Send_Byte(((Dst & 0xFFFF) >> 8));   
            Flash_Send_Byte(Dst & 0xFF);   
            byte = Flash_Get_Byte();   
            PORT_SetBits(SPI_CS_Port,SPI_CS_Pin);          /* disable device */   
            return byte;            /* return one byte read */   
        }   
////////////////////////////////////////////////////////////////////////////////////////////////
void Flash_Write(ulong Dst,uchar dat)        //向flash 内的一个地址内写入一个数据。
{
PORT_ResetBits(SPI_CS_Port,SPI_CS_Pin);
        Flash_Send_Byte(0x02);        /* read command */   
            Flash_Send_Byte(((Dst & 0xFFFFFF) >> 16));  /* send 3 address bytes */   
            Flash_Send_Byte(((Dst & 0xFFFF) >> 8));   
            Flash_Send_Byte(Dst & 0xFF);
        Flash_Send_Byte(dat);///secd data to flash
PORT_SetBits(SPI_CS_Port,SPI_CS_Pin);

}

void Flash_Write_data(uchar  add[],uchar dat[],uchar size)        //向flash 内的一个基地址 add[3],add[0]放地址高八位         内写入size个数据。
{
uchar i;
ulong Dst=0;
for(i=0;i<2;i++)
{
Dst|=add[i];
Dst=Dst<<8;
}
Dst|=add[2];
                for(i=0;i<size;i++)
                {
                 Flash_WREN();
                 PORT_ResetBits(SPI_CS_Port,SPI_CS_Pin)  ;
                  Flash_Send_Byte(0x02);        /* read command */   
                  Flash_Send_Byte(((Dst & 0xFFFFFF) >> 16));  /* send 3 address bytes */   
              Flash_Send_Byte(((Dst & 0xFFFF) >> 8));   
              Flash_Send_Byte(Dst & 0xFF);
          Flash_Send_Byte(dat[i]);///secd data to flash
                    Dst++;
                  PORT_SetBits(SPI_CS_Port,SPI_CS_Pin);
                  Flash_WRDI();
                }
//CS=1;

}

//向从flash 内的一个基地址 add[3],add[0]放地址高八位         内读出size个数据。           放到dat[]中
void Flash_Read_data(uchar  add[],uchar R_dat[],uchar size)
{
uchar i;
PORT_ResetBits(SPI_CS_Port,SPI_CS_Pin);
        Flash_Send_Byte(0x03);        /* read command */   
                for(i=0;i<3;i++)
                {
                  Flash_Send_Byte(add[i]);
                }
                for(i=0;i<size;i++)
                {
       R_dat[i]=Flash_Get_Byte();   ///secd data to flash
                }
PORT_SetBits(SPI_CS_Port,SPI_CS_Pin);

}



//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void Flash_init()            /* 程序功能:    用来将时钟线初始化为低. 必须在将设备设置为模式0之前调用*/
{   
            stc_port_init_t stcPortInit;

    /* configuration structure initialization */
    MEM_ZERO_STRUCT(stcPortInit);

    stcPortInit.enPinMode = Pin_Mode_Out;
    stcPortInit.enExInt = Enable;
    stcPortInit.enPullUp = Enable;
                PORT_Init(SPI_CLK_Port, SPI_CLK_Pin, &stcPortInit);
                PORT_Init(SPI_MISI_Port, SPI_MISI_Pin, &stcPortInit);
                PORT_Init(SPI_CS_Port, SPI_CS_Pin, &stcPortInit);
                PORT_Init(SPI_WR_Port, SPI_WR_Pin, &stcPortInit);
       
                    stc_port_init_t stcPortInit_in;

    /* configuration structure initialization */
    MEM_ZERO_STRUCT(stcPortInit_in);

    stcPortInit_in.enPinMode = Pin_Mode_In;
    stcPortInit_in.enExInt = Enable;
    stcPortInit_in.enPullUp = Enable;
        PORT_Init(SPI_MISO_Port, SPI_MISO_Pin, &stcPortInit_in);

            char i;   
           // P7 |= 0x7f; /* 设置SCK为低电平初始化状态 */   
           PORT_ResetBits(SPI_CLK_Port,SPI_CLK_Pin);
            for(i=255;i>0;i--);   
           // P7 &= 0x80;   
           PORT_SetBits(SPI_CLK_Port,SPI_CLK_Pin);
}   

void Flash_WREN_Check(void)                    /* 功能: 检查擦写操作前WEL位是否为1  */   
{   
            uchar byte;   
            byte = Flash_Read_Status_Register();  /* 读取状态register */   
            if ((byte&0x02) != 0x02)        /* 检查WEL位置位 */   
            {   
                Flash_WREN();   
                    //如果未置1进行相应处理,如对其进行写使得操作   
            }   
}   

void Flash_Chip_Erase(void)              /* 功能: 擦除整个芯片               */  
{     
        Flash_EWSR();
        Flash_WRSR(0);//(Read_Status_Register())&0x83 );


            Flash_WREN_Check();   
            PORT_ResetBits(SPI_CS_Port,SPI_CS_Pin);         
            Flash_Send_Byte(0xc7);            /* 发送 Chip Erase命令 (60h or C7h) */   
                  PORT_SetBits(SPI_CS_Port,SPI_CS_Pin);
            Flash_Wait_Busy();      
            //CE =1;               
}   

void Flash_Sector_Erase(ulong Dst)   /* 功能: Sector Erases the Chip.     4K         */
{   
            uchar i;   
            Flash_WREN_Check();   
            Flash_init();   
            PORT_ResetBits(SPI_CS_Port,SPI_CS_Pin);                 
            Flash_Send_Byte(0x20);            /* 发送Sector Erase 命令 */   
            Flash_Send_Byte(((Dst & 0xFFFFFF) >> 16));  /* 发送地址 */   
            Flash_Send_Byte(((Dst & 0xFFFF) >> 8));   
            Flash_Send_Byte(Dst & 0xFF);   
            for(i=100;i>0;i--);   
            PORT_SetBits(SPI_CS_Port,SPI_CS_Pin);   
            Flash_Wait_Busy();
        //        CS=1;              
}   




使用特权

评论回复
沙发
天天向善| | 2022-9-15 11:30 | 只看该作者
看代码的样子应该没问题,所以读写成功了吧?

使用特权

评论回复
板凳
Bowclad| | 2022-9-16 19:01 | 只看该作者
读写成功了吗

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

8

主题

17

帖子

2

粉丝