新聞中心

        EEPW首頁 > 嵌入式系統(tǒng) > 設(shè)計應(yīng)用 > Stm32的io口模擬spi例程分析

        Stm32的io口模擬spi例程分析

        作者: 時間:2016-11-27 來源:網(wǎng)絡(luò) 收藏
        以下是硬件電路圖,主芯片為stm32rbt6.

        本文引用地址:http://www.104case.com/article/201611/322268.htm

        貼上代碼

        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);

        //關(guān)鍵在讀取函數(shù)
        //包括讀取和發(fā)送
        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為例具體的實(shí)現(xiàn)
        //此函數(shù)中 時鐘機(jī)時序很重要。Cs在讀寫中只能出現(xiàn)一次,不能在sendwrite
        //讀寫里邊有,被調(diào)用時還出現(xiàn),就肯定不行了。
        //其它函數(shù)宏定義
        #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系列的讀寫函數(shù)
        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);

        }
        寫函數(shù)
        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;
        }
        }



        關(guān)鍵詞: Stm32io口模擬sp

        評論


        技術(shù)專區(qū)

        關(guān)閉
        主站蜘蛛池模板: 临汾市| 德兴市| 堆龙德庆县| 普格县| 黄冈市| 塘沽区| 交口县| 鱼台县| 靖远县| 博野县| 台南县| 开原市| 宁海县| 灵丘县| 木兰县| 颍上县| 额尔古纳市| 兰西县| 买车| 得荣县| 东台市| 鹿泉市| 汤阴县| 铁岭县| 宁陕县| 德兴市| 会宁县| 永城市| 志丹县| 五常市| 荣成市| 洛扎县| 连江县| 驻马店市| 桓仁| 新宾| 临汾市| 抚松县| 太仓市| 永康市| 左权县|