分享

Stm32的io口模拟spi例程分析

 筱肆 2015-05-31

以下是硬件电路图,主芯片为stm32rbt6.

1.jpg

贴上代码

void SPI_FLASH_Init1(void)//io初始化配置

{

  //  SPI_InitTypeDef  SPI_InitStructure;

    GPIO_InitTypeDef GPIO_InitStructure;

    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_GPIOC, ENABLE);

   GPIO_InitStructure.GPIO_Pin = GPIO_Pin_7 | GPIO_Pin_9;

    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;

    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;

    GPIO_Init(GPIOC, &GPIO_InitStructure);

   GPIO_InitStructure.GPIO_Pin =  GPIO_Pin_8 ;

  //         GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;

  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;   //miso要用模拟输入

    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;                                              

    GPIO_Init(GPIOC, &GPIO_InitStructure);

 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8;

    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;

         GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;

    GPIO_Init(GPIOA, &GPIO_InitStructure);

   

关键在读取函数

u8 SPIx_FLASH_SendByte(u8 byte)

{

 uint8_t i; 

    u8 Temp=0x00;

          unsigned char SDI; 

    for (i = 0; i < 8; i++)

    {

       GPIO_SetBits(GPIOC, GPIO_Pin_9);//sclk = 0;//先将时钟拉低

        if (byte&0x80)      

        {

          GPIO_SetBits(GPIOC, GPIO_Pin_7); //    //mosi=1 

        }

        else

        {

           GPIO_ResetBits(GPIOC, GPIO_Pin_7);//     //smosi=0

        }

         byte <<= 1;  

         GPIO_ResetBits(GPIOC, GPIO_Pin_9);//    //sclk = 1; 拉高时钟

                     SDI = GPIO_ReadInputDataBit(GPIOC, GPIO_Pin_8);//判断miso是否有输出

                     Temp<<=1;

        

                if(SDI)       //读到1

                                     {

                                     Temp++;  // 即向右移动一位同时加  因上边有<<=1

                           }

          GPIO_SetBits(GPIOC, GPIO_Pin_9);//sclk = 0;//   拉低时钟 

 }

 

            return Temp; //返回读到miso输入的值     

 

         

}

此函数中 时钟机时序很重要。Cs在读写中只能出现一次,不能在sendwrite读写里边有,被调用时还出现,就肯定不行了。

其它函数

宏定义

#define BUFFER_1_WRITE 0x84                 // buffer 1 write

#define BUFFER_2_WRITE 0x87                 // buffer 2 write

#define BUFFER_1_READ  0x54                          // buffer 1 read (change to 0xD4 for SPI mode 0,3)

#define BUFFER_2_READ  0x56                          // buffer 2 read (change to 0xD6 for SPI mode 0,3)

#define B1_TO_PAGE_WITH_ERASE 0x83                   // buffer 1 to main memory page program with built-in erase

#define B2_TO_PAGE_WITH_ERASE 0x86                   // buffer 2 to main memory page program with built-in erase

#define B1_TO_PAGE_WITHOUT_ERASE 0x88          // buffer 1 to main memory page program without built-in erase

#define B2_TO_PAGE_WITHOUT_ERASE 0x89          // buffer 2 to main memory page program without built-in erase

#define PAGE_PROG_THROUGH_B1 0x82                  // main memory page program through buffer 1

#define PAGE_PROG_THROUGH_B2 0x85                  // main memory page program through buffer 2

#define AUTO_PAGE_REWRITE_THROUGH_B1 0x58   // auto page rewrite through buffer 1

#define AUTO_PAGE_REWRITE_THROUGH_B2 0x59   // auto page rewrite through buffer 2

#define PAGE_TO_B1_COMP 0x60                     // main memory page compare to buffer 1

#define PAGE_TO_B2_COMP 0x61                     // main memory page compare to buffer 2

#define PAGE_TO_B1_XFER 0x53             // main memory page to buffer 1 transfer

#define PAGE_TO_B2_XFER 0x55             // main memory page to buffer 2 transfer

#define STATUS_REGISTER 0x57               

#define MAIN_MEMORY_PAGE_READ 0x52          // main memory page read (change to 0xD2 for SPI mode 0,3)

#define PAGE_ERASE 0x81                     // erase a 264 byte page

#define BULK_ERASE 0x50                     // erase 8 pages

#define WIP_Flag   0x80                    

#define Dummy_Byte 0xA5

AT45DB系列的读写函数

void AT45xxReadx(uint32_t Num,uint32_t PageAddr, uint32_t ByteAddr, uint8_t *Data, uint32_t ByteNum)

{

 

    SPIx_FLASH_PageToBuffer2(Num,PageAddr);

   

    SPIx_FLASH_Buffer2Read(Num,Data, ByteAddr, ByteNum);

          

}

写函数

void AT45xxWritex(uint32_t Num,uint32_t PageAddr, uint32_t ByteAddr, u8 *Data, uint32_t ByteNum)

{

    uint32_t i; 

         u8 aa[100];     

   

    if((ByteNum <= (528 - ByteAddr))&&(ByteNum > 0))

    {

        SPIx_FLASH_WaitForWriteEnd(Num);

         //  while(!(Rat45_status()& 0x80 )); //判断是否忙

       

        SPIx_FLASH_CS_LOW(Num);

       

        SPIx_FLASH_SendByte(Num,0x82);

         //      SPIx_ReadWriteByte(0x82);

                  

         //      SPIx_ReadWriteByte((uint8_t)(PageAddr>>6));

         //      SPIx_ReadWriteByte((uint8_t)((PageAddr<<2)|(ByteAddr>>8)));

         //      SPIx_ReadWriteByte((uint8_t)ByteAddr);

        SPIx_FLASH_SendByte(Num,(uint8_t)(PageAddr>>6));

        SPIx_FLASH_SendByte(Num,(uint8_t)((PageAddr<<2)|(ByteAddr>>8)));

        SPIx_FLASH_SendByte(Num,(uint8_t)ByteAddr);

       

       

        for(i = 0; i < ByteNum; i++)

        {

            SPIx_FLASH_SendByte(Num,Data[i]);

                   //      SPIx_ReadWriteByte(Data[i]);

         //      SPIx_FLASH_SendByte(Num,Data[i]);

        }

       

        SPIx_FLASH_CS_HIGH(Num);                    

    }

}

 

 

void SPIx_FLASH_WaitForWriteEnd(uint32_t Num)

{

  unsigned char FLASH_Status = 0;

 

 

  SPIx_FLASH_CS_LOW(Num);

 

 

  SPIx_FLASH_SendByte(Num,STATUS_REGISTER);

 

 

  do

  {

   

    FLASH_Status = SPIx_FLASH_SendByte(Num,Dummy_Byte);

 

  }

  while ((FLASH_Status & WIP_Flag) == RESET);

 

 

  SPIx_FLASH_CS_HIGH(Num);

}

 

 

void SPIx_FLASH_Buffer2Read(uint32_t Num,u8* pBuffer, u32 ReadAddr, u16 NumByteToRead)

{

 

  SPIx_FLASH_WaitForWriteEnd(Num);

 // while(!(Rat45_status()& 0x80 )); //判断是否忙

 

 

  SPIx_FLASH_CS_LOW(Num);

 

 

  SPIx_FLASH_SendByte(Num,BUFFER_2_READ);

 

 

  SPIx_FLASH_SendByte(Num,Dummy_Byte);

 

  SPIx_FLASH_SendByte(Num,(ReadAddr& 0xFF00) >> 8);

 

  SPIx_FLASH_SendByte(Num,ReadAddr & 0xFF);

 

  SPIx_FLASH_SendByte(Num,Dummy_Byte);//

 

 

  while (NumByteToRead--)

  {

   

    *pBuffer = SPIx_FLASH_SendByte(Num,Dummy_Byte);

   

    pBuffer++;

  }

 

 

  SPIx_FLASH_CS_HIGH(Num);

  

 

 

void SPIx_FLASH_CS_LOW(uint32_t Num)

{

   switch(Num)

   {

     case 0:  GPIO_ResetBits(GPIOB, GPIO_Pin_12); break;

     case 1: GPIO_ResetBits(GPIOA, GPIO_Pin_8); break;  //U6

          case 2: GPIO_ResetBits(GPIOA, GPIO_Pin_7);     break;   //U7

      case 3: GPIO_ResetBits(GPIOA, GPIO_Pin_3);     break;       //U8

      case 4: GPIO_ResetBits(GPIOC, GPIO_Pin_3); break;          //U9

          default:break;

   }

 

}

 

void SPIx_FLASH_CS_HIGH(uint32_t Num)

{

   switch(Num)

   {

     case 0:  GPIO_SetBits(GPIOB, GPIO_Pin_12);  break;

     case 1: GPIO_SetBits(GPIOA, GPIO_Pin_8); break;       //U6

          case 2: GPIO_SetBits(GPIOA, GPIO_Pin_7); break;   //U7

      case 3: GPIO_SetBits(GPIOA, GPIO_Pin_3); break;       //U8

      case 4: GPIO_SetBits(GPIOC, GPIO_Pin_3); break;     //U9

          default:break;

   }

}

标签: stm32 io口模拟spi程序 程序分析 SPI_FLASH_Buffer2Read

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多