小v电子技术博文 上海鲤鲸网络科技 小v单片机
Stm32的io口模拟spi例程分析
  • 首页 > ARM-STM32系列
  • 作者:小v
  • 2014年12月25日 12:59 星期四
  • 浏览:20190
  • 字号:
  • 评论:2
  • 点击:串口电机驱动模块购买链接



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

    1.jpg

    贴上代码

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

      GPIO_InitTypeDef GPIO_InitStructure;
      RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_GPIOC, ENABLE);

      GPIO_InitStructure.GPIO_Pin = GPIO_Pin_7 | GPIO_Pin_9;//CS  CLK
      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_IN_FLOATING;   //MOSI要用模拟输入
        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;//MISO
        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); //    //SO=1 
            }
            else
            {
               GPIO_ResetBits(GPIOC, GPIO_Pin_7);//     //SO=0
            }
             byte <<= 1;  
             GPIO_ResetBits(GPIOC, GPIO_Pin_9);//    //sclk = 1; 拉低时钟
             SDI = GPIO_ReadInputDataBit(GPIOC, GPIO_Pin_8);//判断si是否有输入
             Temp<<=1;
            
    if(SDI)       //读到1时
    {
    Temp++;  //置1  即向右移动一位同时加1   因上边有<<=1
    }
             GPIO_SetBits(GPIOC, GPIO_Pin_9);//sclk = 0;//   拉高时钟 
      }
     
        return Temp; //返回读到miso输入的值     
     
    }          
    }
    //下面是以读写spi flash为例具体的实现
    //此函数中 时钟机时序很重要。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;
       }
    }




      您阅读这篇文章共花了:  
    二维码加载中...
    本文作者:小v      文章标题: Stm32的io口模拟spi例程分析
    本文地址:http://www.xiaovdiy.cn/?post=20
    版权声明:若无注明,本文皆为“”原创,转载请保留文章出处。

    关注本网站更多资源开放!开发工具软件会逐步在右侧分类中的【开发工具】栏中更新!
    该部分内容已经更新过
    返回顶部| 首页| 手气不错| 捐赠支持| 自定义链接| 自定义链接| 自定义链接| 手机版本|后花园

    Copyright © 2014-2017   京ICP备14059411 Copyright 2014-2015 上海鲤鲸网络科技工作室 版权所有 All Rights Reserved

    sitemap