打印
[其他ST产品]

(分享)STM32单片机AT45DB642D驱动程序

[复制链接]
460|13
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
cr315|  楼主 | 2023-8-3 16:59 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
* File Name          : AT45DB642D.c
* Author             : XiaoShm       
* Version            : V1.0
* Date               : 8/29/2012
* Description                 :
* Last Modefly Date         : 8/31/2012
*******************************************************************************/
#include "stm32f10x.h"
#include "stm32f10x_gpio.h"
#include "InitDevice.h"
#include"at45db642d.h"

//AT45DB有两个缓冲区Buffer1和Buffer2 (SRAM),此处只使用buffer1
/******************************
*opcode-操作码
******************************/
//读取状态的操作码
#define Status_Register_Opcode                          0xD7
//读取ID的操作码
#define Device_ID_Opcode                                0x9F
//Write to buffer
#define Write_Data_to_Buffer1                           0x84//0x84,0x87
//Write buffer to page
#define Write_Buffer1_to_Page_whin_Erase           0x83
//Continuous Array Read
#define Continuous_Array_Read_Command           0xe8//0x03//0x0b//0xe8
#define Deep_Power_Down                                                0xb9
#define Resume_from_Deep_Power_Down                        0xab
#define Main_MemoryPage_to_Buffer1_Transfer        0x53
#define Auto_Page_Rewrite_through_Buffer1        0x58
#define Main_Memory_Page_Pro_Through_Buff1        0x82

#define DF_FullSize                                                        0x7fffff//8M byte
#define DF_PageSize                                                        0x400//页大小

#ifdef TEST_AT45DB
#define TESTBASE        0X2000
u32 TestAddr = TESTBASE;               
u8 TestBuffer[256] ={0};
#endif
//======================================================================
//函数名称:DF_SpiRxByte(void)
//输入:
//输出:
//函数功能:通过SPI接从AT45DB读一字节数据
//======================================================================
u8 DF_SpiRxByte(void)
{
        u8 i = 0, rdat = 0;
       
        for(i = 0; i < 8; i ++)
        {
                rdat <<= 1;
                GPIO_SetBits(GPIOC, FSCK);
                if(GPIO_ReadInputDataBit(GPIOC, FSDO))
                {
                        rdat |= 0x01;
                }
                GPIO_ResetBits(GPIOC, FSCK);
               
        }
       
        return rdat;
}
//======================================================================
//函数名称:DF_SpiTxByte(u8 dat)
//输入:data待写入的数据
//输出:
//函数功能:通过SPI接口向AT45DB写入一字节数据
//======================================================================
void DF_SpiTxByte(u8 dat)
{
          u8 i = 0, sdat = 0;
       
        sdat = dat;
        for(i = 0; i < 8; i ++)
        {
                if(sdat & 0x80)
                {
                        GPIO_SetBits(GPIOC, FSDI);
                }
                else
                {
                        GPIO_ResetBits(GPIOC, FSDI);
                }
                GPIO_SetBits(GPIOC, FSCK);
                sdat <<= 1;
                GPIO_ResetBits(GPIOC, FSCK);
        }
}
//======================================================================
//函数名称:Enable_DFLASH(void)
//输入:
//输出:
//函数功能:使能FLASH(低电平使能)
//======================================================================
void Enable_DFLASH(void)
{
           u8 i = 5;

          GPIO_ResetBits(GPIOC, FCS);
          while(i --);       
}

使用特权

评论回复
沙发
cr315|  楼主 | 2023-8-3 16:59 | 只看该作者
//======================================================================
//函数名称:Disable_DFLASH(void)
//输入:
//输出:
//函数功能:禁止FLASH(高电平禁止)
//======================================================================
void Disable_DFLASH(void)
{
          u8 i = 5;
       
          GPIO_SetBits(GPIOC, FCS);
          while(i --);                        //延长上一次高电平时间
}
//=========================================================================================
//*Status Register Format:                                   *
//*   -----------------------------------------------------------------------  
//* bit7 bit6 bit5 bit4 bit3 bit2 bit1 bit0 *
//* -------- -------- -------- -------- -------- -------- -------- -------- *
//* RDY/BUSY COMP   0     1     1     1     X     X   *
//*   ----------------------------------------------------------------------- *
//* bit7 - 忙标记,0为忙1为不忙。                               *
//*       当Status Register的位0移出之后,接下来的时钟脉冲序列将使SPI器件继续*
//*       将最新的状态字节送出。                               */
//* bit6 - 标记最近一次Main Memory Page和Buffer的比较结果,0相同,1不同。   *
//* bit5                                               *
//* bit4                                               *
//* bit3                                               *
//* bit2 - 这4位用来标记器件密度,对于AT45DB041B,这4位应该是0111,一共能标记
//*       16种不同密度的器件。                              
//* bit1                                               
//* bit0 - 这2位暂时无效                                    
//=======================================================================================
u8 DF_ReadStatus(void)
{
    u8 i = 0;      
       
    Enable_DFLASH();   
    DF_SpiTxByte(Status_Register_Opcode);
        i = DF_SpiRxByte();/////////////////****************//////////////////
    Disable_DFLASH();
       
    return i;   
}
//======================================================================
//函数名称:DF_Check_Busy_State(void)
//输入:
//输出:
//函数功能:读取FLASH忙标志位(最多判断255次,不行还是返回且返回0)
//======================================================================
u8 DF_Check_Busy_State(void)
{
          u8 state = 0;
          u8 i = 255;
       
          while(i)
          {
               state = DF_ReadStatus();
                   if(state & 0x80) break;                //读取的最高位0时器件忙
                   --i;
                DelayNInstruct(100);
        }
          return i;
}
//************************************************************
//*读取FLASH的页大小
//*返回1表示每一页的大小为1024 bytes,否则为1056 bytes
//************************************************************
u8 DF_Check_Page_Size(void)
{
          u8 Page_Size = 0;
       
          Page_Size = DF_ReadStatus();
       
          if(Page_Size & 0x01) return 1;
       
          return 0;
}
//======================================================================
//函数名称:DF_Deep_Power_Down(void)
//输入:
//输出:
//函数功能:使FLASH进入DeepPowerDown模式
//======================================================================
void DF_Deep_Power_Down(void)
{
        Enable_DFLASH();   
        DF_SpiTxByte(Deep_Power_Down);
        Disable_DFLASH();
}
//======================================================================
//函数名称:DFLASH_Resume_from_Deep_Power_Down(void)
//输入:
//输出:
//函数功能:将FLASH从DeepPowerDown模式唤醒
//======================================================================

使用特权

评论回复
板凳
cr315|  楼主 | 2023-8-3 17:00 | 只看该作者
void DF_Resume_from_Deep_Power_Down(void)
{
        Enable_DFLASH();   
        DF_SpiTxByte(Resume_from_Deep_Power_Down);
        Disable_DFLASH();
}
//************************************************************
//*配置FLASH页大小为1024bytes
//************************************************************
void DF_Configer_Binary_Page_Size(void)
{
        u8 i = 0, j = 0;
        u8 Power_of_Two_Page_Size_Command[4]={0x3d,0x2a,0x80,0xa6};
        while(j < 5)
        {
                if(!DF_Check_Page_Size())
                {//如果页大小为1056 bytes,则配置为1024 bytes
                        DF_Check_Busy_State();
                          Enable_DFLASH();
                          for(i=0;i<4;i++)
                          {
                                  DF_SpiTxByte(Power_of_Two_Page_Size_Command[i]);//
                          }
                         
                          Disable_DFLASH();       
                        DelayNmsTime(10);
                        DF_Check_Busy_State();
                        DelayNmsTime(5);
                        DF_Deep_Power_Down();
                        DelayNmsTime(5);
                        DF_Resume_from_Deep_Power_Down();
                        DelayNmsTime(1);
                }
                else
                {//已经为1024则不用再配置
                        break;
                }
                j ++;
        }
}
//************************************************************
//*使能扇区保护
//************************************************************
void DF_Enable_Sector_Protection(void)
{
          u8 Enable_Sector_Protection_Command[4]={0x3D,0x2A,0x7F,0xA9}; //使能扇区保护操作码
          u8 i;

          DF_Check_Busy_State();
          Enable_DFLASH();
          for(i=0;i<4;i++)
          {
                  DF_SpiTxByte(Enable_Sector_Protection_Command[i]);//写使能扇区保护操作码
          }
          Disable_DFLASH();
}
//======================================================================
//函数名称:
//输入:
//输出:
//函数功能:禁止扇区保护
//======================================================================
void DF_Disable_Sector_Protection(void)
{
          u8 Disable_Sector_Protection_Command[4]={0x3D,0x2A,0x7F,0x9A};//禁止扇区保护操作码
          u8 i;

          DF_Check_Busy_State();
          Enable_DFLASH();
          for(i=0;i<4;i++)
          {
              DF_SpiTxByte(Disable_Sector_Protection_Command[i]);//写禁止扇区保护操作码
          }
          Disable_DFLASH();
}
//======================================================================
//函数名称:
//输入:各扇区保护字0---unprotected 0xff---protected,32byte refer to 32 sector
//输出:
//函数功能:设置扇区保护  注意:会改变BUFFER1中的内容
//======================================================================
void DF_Program_Sector_Protection_Register(u8 *Sector_Protection_Register)
{
          u8 Program_Sector_Protection_Command[4]={0x3D,0x2A,0x7F,0xFC};//设置扇区保护操作码
          u8 i;

          DF_Check_Busy_State();
          Enable_DFLASH();
          for(i=0;i<4;i++)
          {
              DF_SpiTxByte(Program_Sector_Protection_Command[i]);//写设置扇区保护操作码
          }
          for(i=0;i<32;i++)
          {
              DF_SpiTxByte(Sector_Protection_Register[i]);//写设置扇区保护数据
          }
          Disable_DFLASH();
}

//======================================================================
//函数名称:
//输入:
//输出:
//函数功能:读取扇区保护寄存器内容(返回32个字节,对应32个扇区的情况)
//======================================================================
void DF_Read_Sector_Protection_Register(u8 *Sector_Protection_Register)
{
          u8 Read_Sector_Protection_Register_Command[4]={0x32,0,0,0};
          u8 i;
       
          DF_Check_Busy_State();
          Enable_DFLASH();

          for(i=0;i<4;i++)//write
          {
            DF_SpiTxByte(Read_Sector_Protection_Register_Command[i]);
          }
          for(i=0;i<32;i++)//read
          {
            Sector_Protection_Register[i] = DF_SpiRxByte();
          }
          Disable_DFLASH();
}
//************************************************************
//*取消所有扇区保护
//*返回1表示成功取消扇区所以保护
//************************************************************
u8 DF_Cancel_Sector_Protection(void)
{
          u8 Sector_Protection_Register_for_Write[32]={0,0,0,0,0,0,0,0};//写入0为去保护
          u8 Sector_Protection_Register_for_Read[32]={1,1,1,1,1,1,1,1};//防止默认值为0
          u16 i;
          u8 j=1;
  //使能扇区保护
          DF_Enable_Sector_Protection();
  //设置扇区保护

          DF_Program_Sector_Protection_Register(Sector_Protection_Register_for_Write);
  //读取扇区保护寄存器内容
          DF_Read_Sector_Protection_Register(Sector_Protection_Register_for_Read);
  //判断扇区保护寄存器内容
          for(i=0;i<8;i++)
          {
            if(Sector_Protection_Register_for_Read[i] != 0) j++;
          }
  //禁止扇区保护
          DF_Disable_Sector_Protection();

          return j;
}
//=============================================================================
//函数名称:DF_ContinusArrayRead(UIN32 readaddr,u8 *readbuff,u16 len)
//输入:readaddr指定数据在FLASH中的存储地址,指定数据的首地址,指定数据的长度
//输出:readbuf指定数据暂存区的首地址
//函数功能:从FLASH主存readaddr地址处连续读取len字节数据
//=============================================================================
void DF_ContinusArrayRead(u32 readaddr,u8 *readbuff,u16 len)
{
    u16 i;
       
    DF_Check_Busy_State();
    Enable_DFLASH();
    DF_SpiTxByte(Continuous_Array_Read_Command);
    DF_SpiTxByte((u8)((readaddr >> 16) & 0xff));
    DF_SpiTxByte((u8)((readaddr >> 8) & 0xff));
    DF_SpiTxByte((u8)(readaddr & 0xff));

    for(i = 0 ; i < 4 ; i ++)
    {
        DF_SpiTxByte(0x00);
    }
    for(i = 0 ; i < len ; i ++)
    {
        readbuff[i] = DF_SpiRxByte();
    }
    Disable_DFLASH();
}
//=============================================================================
//函数名称:DF_BufferWrite(u8 bufferaddr,u8 *writebuff,u16 len)
//输入:BUFFER中的起始地址, 待存数据的头指针,待存数据的长度1~1024
//输出:
//函数功能:将指定数据写入从某个地址(0~1023)开始的BUFFER1中
//=============================================================================
void DF_BufferWrite(u16 bufferaddr,u8 *writebuff,u16 len)
{
    u16 i;
       
    DF_Check_Busy_State();
    Enable_DFLASH();
    DF_SpiTxByte(Write_Data_to_Buffer1);
    DF_SpiTxByte(0x00);
    DF_SpiTxByte((u8)((bufferaddr >> 8) & 0x03));
    DF_SpiTxByte((u8)(bufferaddr & 0xff));
    for(i = 0 ; i < len ; i ++ )
    {
         DF_SpiTxByte(writebuff[i]);
    }
    Disable_DFLASH();   
}
//=============================================================================
//函数名称:DF_BufferToMainMemoryWithErase(u16 pageaddr,u8 buffaddr,u8 *writebuff,u16 len)
//输入:BUFFER中的起始地址, 待存数据的头指针,待存数据的长度1~1024
//输出:
//函数功能:将指定数据写入从某个地址(0~1023)开始的BUFFER1中:包含2个动作,首先将
//指定数据写入到BUFFER 1中,其中可以指定BUFFER中的起始写入地址,此写入动作不影响
//BUFFER中其它地址中的数据,然后再将BUFFER中的整个数据写入到某指定页中(带预擦除)。                                      
//=============================================================================
void DF_BufferToMainMemoryWithErase(u16 pageaddr,u16 buffaddr,u8 *writebuff,u16 len)
{
    DF_BufferWrite(buffaddr,writebuff,len);
        DF_Check_Busy_State();
    Enable_DFLASH();
    DF_SpiTxByte(Write_Buffer1_to_Page_whin_Erase);
    DF_SpiTxByte((u8)((pageaddr >> 8) & 0x7f));
    DF_SpiTxByte((u8)(pageaddr & 0xfc));
    DF_SpiTxByte(0x00);
        DelayNmsTime(40);
    Disable_DFLASH();
}
//======================================================================
//函数名称:DF_MainMemoryPageProgramThroughBuffer(u32 writeaddr, u8 *writebuff, u16 len)
//输入:riteaddr---待写入地址,writebuff数据指针,len数据长度
//输出:
//函数功能:通过BUF1写主存,包含动作:先将1-1024字节数据写入BUF1,然后进行
//BUF1到主存的带擦除编程
//==================================================================
void DF_MainMemoryPageProgramThroughBuffer(u32 writeaddr, u8 *writebuff, u16 len)
{
        u16 i = 0;
       
        DF_Check_Busy_State();
        Enable_DFLASH();
        DF_SpiTxByte(Main_Memory_Page_Pro_Through_Buff1);
    DF_SpiTxByte((u8)((writeaddr >> 16) & 0xff));
    DF_SpiTxByte((u8)((writeaddr >> 8) & 0xff));
    DF_SpiTxByte((u8)(writeaddr & 0xff));
    for(i = 0 ; i < len ; i ++ )
    {
         DF_SpiTxByte(writebuff[i]);
    }
        DelayNmsTime(40);
        Disable_DFLASH();

}
//========================================================================================
//函数名称:DF_MainMemoryPagetoBufferTransfer(u16 pageaddr)
//输入:pageaddr
//输出:
//函数功能:
//==========================================================================================
void DF_MainMemoryPagetoBufferTransfer(u16 pageaddr)
{
        DF_Check_Busy_State();
        Enable_DFLASH();
        DF_SpiTxByte(Main_MemoryPage_to_Buffer1_Transfer);
    DF_SpiTxByte((u8)((pageaddr >> 8) & 0x7f));
    DF_SpiTxByte((u8)(pageaddr & 0xfc));
    DF_SpiTxByte(0x00);
        Disable_DFLASH();       
}
//========================================================================================
//函数名称:
//输入:
//输出:
//函数功能:
//==========================================================================================
void DF_AutoPageRewriteThroughBuffer(u16 pageaddr)
{
        DF_Check_Busy_State();
        Enable_DFLASH();
        DF_SpiTxByte(Auto_Page_Rewrite_through_Buffer1);
    DF_SpiTxByte((u8)((pageaddr >> 8) & 0x7f));
    DF_SpiTxByte((u8)(pageaddr & 0xfc));
    DF_SpiTxByte(0x00);
        Disable_DFLASH();

        DelayNmsTime(18);
}
//=========================================================================================
//函数名称:DF_Chip_Erase(void)
//输入:
//输出:
//函数功能:整片擦除FLASH全部内容
//==========================================================================================
void DF_Chip_Erase(void)
{
           u8 Chip_Erase_Command[4] = {0xC7,0x94,0x80,0x9A};//整片擦除操作码
           u8 i;
           DF_Check_Busy_State();
           Enable_DFLASH();
           for(i = 0 ; i < 4 ; i ++)
           {
             DF_SpiTxByte(Chip_Erase_Command[i]);
         }
           Disable_DFLASH();
}
//=========================================================================================
//函数名称:
//输入:
//输出:
//函数功能:读取制造ID,确认是否有DATAFLASH存在,存在返回1,否则返回0
//==========================================================================================
u8 DF_ReadManufactureIDInformation(void)
{
        u8 i = 0;
        u8 Idbuff[4] = {0};
       
        DF_Check_Busy_State();
    Enable_DFLASH();
    DF_SpiTxByte(Device_ID_Opcode);
    for(i = 0 ; i < 4 ; i ++)
    {
        Idbuff[i] = DF_SpiRxByte();
    }
    Disable_DFLASH();       
        if((Idbuff[0] == 0x1f) && (Idbuff[1] == 0x28))
        {
                return 1;
        }
        else
        {
                return 0;
        }
}
//=========================================================================================
//函数名称:
//输入:
//输出:
//函数功能:初始化DataFlash,检查制造ID,配置为1024字节每page,禁止扇区保护
//==========================================================================================

使用特权

评论回复
地板
cr315|  楼主 | 2023-8-3 17:00 | 只看该作者
void DF_Init(void)
{
        u8 i = 0;
        GPIO_SetBits(GPIOC, FCS);
        GPIO_ResetBits(GPIOC, FSCK);//AT45DB选择SPI方式0
        GPIO_ResetBits(GPIOC, FSDI);

        i = DF_Check_Busy_State();
        if(DF_ReadManufactureIDInformation())
        {
                DF_Configer_Binary_Page_Size();
                i = DF_Cancel_Sector_Protection();
        }
        else
        {//未检测到DF,则给出提示报警信息
                i = 0;
                while(i < 50)
                {
                        i ++;
                }
                BeepTim = 100;
        }       
}

//=========================================================================================
//函数名称:SaveDataToFlash(u32 *pBuffer, u32 cnt, u32 addr)
//输入:pBuffer-数据缓冲区首址,cnt-写入字节数,WriteAddr-保存地址
//输出:保存成功与否
//函数功能:将任意字节(小于0X800000)数据保存入FLASH任意地址
//==========================================================================================
u8 SaveDataToFlash(u8 *pBuffer, u32 sizlen, u32 WriteAddr)
{
        u32 NumOfPage = 0, NumOfSingle = 0, Addr = 0, count = 0;
        u16 paddr = 0;
       
        if(WriteAddr + sizlen >= DF_FullSize)
        {//如果 超出地址
                return 0;
        }
          Addr = WriteAddr % DF_PageSize;
          count = DF_PageSize - Addr;
          NumOfPage =  sizlen / DF_PageSize;
          NumOfSingle = sizlen % DF_PageSize;
        /* If WriteAddr is DF_PageSize aligned  */
          if(Addr == 0)
          {//地址为整页起始地址
    /* If sizlen < DF_PageSize */
            if(NumOfPage == 0)
            {//不够一页
                      paddr = (u16)((WriteAddr >> 8) & 0xfffc);//查找页地址
                        DF_MainMemoryPagetoBufferTransfer(paddr);
                        DF_MainMemoryPageProgramThroughBuffer(WriteAddr,pBuffer,NumOfSingle);
                        DF_AutoPageRewriteThroughBuffer(paddr);       
            }
    /* If sizlen > DF_PageSize */
            else  
            {//超出一页
                      while(NumOfPage--)
                      {//先写整页
                        paddr = (u16)((WriteAddr >> 8) & 0xfffc);//查找页地址
                                DF_MainMemoryPagetoBufferTransfer(paddr);
                                DF_MainMemoryPageProgramThroughBuffer(WriteAddr,pBuffer,DF_PageSize);
                                DF_AutoPageRewriteThroughBuffer(paddr);       
                        WriteAddr +=  DF_PageSize;
                        pBuffer += DF_PageSize;
                      }//再写余下部分
                      if(NumOfSingle!=0)
                      {
                        paddr = (u16)((WriteAddr >> 8) & 0xfffc);//查找页地址
                                DF_MainMemoryPagetoBufferTransfer(paddr);
                                DF_MainMemoryPageProgramThroughBuffer(WriteAddr,pBuffer,NumOfSingle);
                                DF_AutoPageRewriteThroughBuffer(paddr);       
                      }
            }
          }
          /* If WriteAddr is not DF_PageSize aligned  */
          else
          {//起始地址非整页地址
            /* If sizlen < DF_PageSize */       
            if(NumOfPage== 0)
            {//不超过一页
                        if(NumOfSingle > count)
                        {//产生跨页
                                paddr = (u16)((WriteAddr >> 8) & 0xfffc);//查找页地址
                                DF_MainMemoryPagetoBufferTransfer(paddr);
                                DF_MainMemoryPageProgramThroughBuffer(WriteAddr,pBuffer,count);
                                DF_AutoPageRewriteThroughBuffer(paddr);       
                                NumOfSingle -= count;
                                WriteAddr += count;
                                pBuffer += count;
                                   paddr = (u16)((WriteAddr >> 8) & 0xfffc);//查找页地址
                                DF_MainMemoryPagetoBufferTransfer(paddr);
                                DF_MainMemoryPageProgramThroughBuffer(WriteAddr,pBuffer,NumOfSingle);
                                DF_AutoPageRewriteThroughBuffer(paddr);       
                        }
                        else
                        {//不产生跨页
                              paddr = (u16)((WriteAddr >> 8) & 0xfffc);//查找页地址
                                DF_MainMemoryPagetoBufferTransfer(paddr);
                                DF_MainMemoryPageProgramThroughBuffer(WriteAddr,pBuffer,NumOfSingle);
                                DF_AutoPageRewriteThroughBuffer(paddr);       
                        }
            }
            /* If sizlen > DF_PageSize */
            else
            {//超过一页
                      sizlen -= count;
                      NumOfPage =  sizlen / DF_PageSize;
                      NumOfSingle = sizlen % DF_PageSize;       
                        if(count != 0)
                      {  
                        paddr = (u16)((WriteAddr >> 8) & 0xfffc);//查找页地址
                                DF_MainMemoryPagetoBufferTransfer(paddr);
                                DF_MainMemoryPageProgramThroughBuffer(WriteAddr,pBuffer,count);
                                DF_AutoPageRewriteThroughBuffer(paddr);       
                        WriteAddr += count;
                        pBuffer += count;
                      }
                      while(NumOfPage--)
                      {
                        paddr = (u16)((WriteAddr >> 8) & 0xfffc);//查找页地址
                                DF_MainMemoryPagetoBufferTransfer(paddr);
                                DF_MainMemoryPageProgramThroughBuffer(WriteAddr,pBuffer,DF_PageSize);
                                DF_AutoPageRewriteThroughBuffer(paddr);       
                        WriteAddr +=  DF_PageSize;
                        pBuffer += DF_PageSize;  
                      }
                      if(NumOfSingle != 0)
                      {
                        paddr = (u16)((WriteAddr >> 8) & 0xfffc);//查找页地址
                                DF_MainMemoryPagetoBufferTransfer(paddr);
                                DF_MainMemoryPageProgramThroughBuffer(WriteAddr,pBuffer,NumOfSingle);
                                DF_AutoPageRewriteThroughBuffer(paddr);       
                      }
              }
          }
        return 1;
}
//=========================================================================================
//函数名称:GetFlashData(u32 readdr, u8 *pBuffer, u16 sizlen)
//输入:readdr-读取地址,pBuffer-读取数据缓存地址,sizlen-数据字节数
//输出:
//函数功能:从FLASH任意(0-0X7FFFFF)地址读取任意字节(0-65535)数据
//==========================================================================================
u8 GetFlashData(u32 readdr, u8 *pBuffer, u16 sizlen)
{
        if(readdr + sizlen >= DF_FullSize)
        {//如果 超出地址
                return 0;
        }
        DF_ContinusArrayRead(readdr,pBuffer,sizlen);

        return 1;
}
//=========================================================================================
//函数名称:
//输入:
//输出:
//函数功能:测试读写DATAFLASH
//==========================================================================================
void Test_At45db642d(void)
{
#ifdef TEST_AT45DB

        u16 paddr = 0;
        u8 i = 0;
       
           if(TestAddr < TESTBASE + 0x2000)
        {
                for(i = 0; i < 32; i ++)
                {
                        TestBuffer[i] = i;
                }
                paddr = (u16)((TestAddr >> 8) & 0xfffc);
       
                DF_MainMemoryPagetoBufferTransfer(paddr);
                DF_MainMemoryPageProgramThroughBuffer(TestAddr,TestBuffer,32);

                DF_AutoPageRewriteThroughBuffer(paddr);
                   for(i = 0; i < 250; i ++)
                {
                        TestBuffer[i] = 0;
                }
                DF_ContinusArrayRead(TestAddr-32,TestBuffer,96);
                TestAddr += 32;
        }
#endif
}

使用特权

评论回复
5
Wordsworth| | 2024-3-1 07:05 | 只看该作者

主从定时的方式占用CPU资源少

使用特权

评论回复
6
Clyde011| | 2024-3-1 08:08 | 只看该作者

主从定时器门控的方式

使用特权

评论回复
7
公羊子丹| | 2024-3-1 09:01 | 只看该作者

主定时器为TIM1,通道2配置为PWM输出

使用特权

评论回复
8
万图| | 2024-3-1 10:04 | 只看该作者

中断计数的方式实现简

使用特权

评论回复
9
Uriah| | 2024-3-1 11:07 | 只看该作者

当PWM频率较高时,频繁的中断将影响程序运行的效率

使用特权

评论回复
10
帛灿灿| | 2024-3-1 13:03 | 只看该作者

都可以产生指定个数的PWM脉冲

使用特权

评论回复
11
Bblythe| | 2024-3-1 14:06 | 只看该作者

输出了5个频率为10KHz的PWM脉冲

使用特权

评论回复
12
周半梅| | 2024-3-1 16:02 | 只看该作者

从定时器为TIM2,从模式选择为门控模式,触发源选择ITR0,开启定时器2中断。

使用特权

评论回复
13
Pulitzer| | 2024-3-1 17:05 | 只看该作者

根据实际需求选择用哪种方式

使用特权

评论回复
14
童雨竹| | 2024-3-1 19:01 | 只看该作者

使能主从模式,触发事件选择为更新事件,不需要开启中断。

使用特权

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

本版积分规则

1327

主题

3832

帖子

0

粉丝