软件模拟SPI基础函数--以及一些框架思想

/*
编辑框架:
  基础层===》隔离层===》驱动层===》应用层

基础层:包含管脚初始化,配置管脚输入输出脚的基础函数到隔离层
   例如:void FM25_IOInit(void);
        void FM25_CS(u8 IO);
        void FM25_CLK(u8 IO);
        void FM25_MOSI(u8 IO);
        u8 FM25_MISO(void);
隔离层:操作隔离
   例如:
   //隔离初始化
   SPI_Type FM25_SPI = {
	.CS   = FM25_CS,
	.CLK  = FM25_CLK,
	.MOSI = FM25_MOSI,
	.MISO = FM25_MISO};
   最好再添加一个函数包裹着 u8 Soft_SPI_RW(SPI_Type *BaseSPI, u8 dat)函数,减少FM25_SPI 耦合
    eg:
    u8 SPI_Send_Byte( u8 WRDat )
    {
        return Soft_SPI_RW( FM25_SPI, WRDat ); //软件模拟读写一字节
    }
驱动层:就是芯片的时序读写
应用层: 驱动层提供芯片封装好的应用函数给永辉

*/
typedef struct _SPI
{
    //SPI管脚
    void (*CS)(u8)   ;      //片选脚输出
    void (*CLK)(u8)  ;      //时钟脚输出
    void (*MOSI)(u8) ;      //输出
    u8(*MISO)(void)  ;      //输入
} SPI_Type;

/**
  * @Name    soft_SPI_Write
  * @brief   模拟SPI读写一字节
  * @param   BaseSPI: [输入]
  **               dat: [输入]
  * @retval
  * @author   https://blog.csdn.net/Wekic
  * @Data    2020-03-29
 **/
u8 Soft_SPI_RW(SPI_Type BaseSPI, u8 dat)
{
	u8 i    = 0;
	u8 temp = 0;
	for(i = 0; i < 8; i++) {
		if(BaseSPI.CLK) {BaseSPI.CLK(0);}    //上升沿移送数据
		if((dat << i) & 0x80) {                //数据输出
			if(BaseSPI.MOSI) {BaseSPI.MOSI(1);}
		} else {
			if(BaseSPI.MOSI) {BaseSPI.MOSI(0);}
		}
		if(BaseSPI.CLK) {BaseSPI.CLK(1);}    //移送数据
		temp<<=1;
		if(BaseSPI.MISO && BaseSPI.MISO())   //数据输入
		{
			temp |=1;
		}
	}
	return (temp);  //返回数据
}

----------------------------------------------------------------------------------------------------------------------------

2020-03-30:增加软件模拟SPI应用文件----FM25CL64芯片操作

FM25CL64.h

/**
  ************************************* Copyright ******************************   
  *                 (C) Copyright 2020,Wenkic,China, GCU.
  *                            All Rights Reserved
  *                              
  *                     By(Wenkic)
  *                    https://blog.csdn.net/Wekic
  *      
  * FileName   : FM25CL64.h   
  * Version    : v1.0		
  * Author     : Wenkic			
  * Date       : 2020-03-30         
  * Description:    
  * Function List:  

  ******************************************************************************
 */
#ifndef __FM25CL64_H
#define __FM25CL64_H

#include "stm32f10x.h"
 //================================================
 //           基础层
 //================================================
void FM25_IOInit(void); //管脚初始化
 //================================================
 //           应用层
 //================================================
 u8   FM25ReadByte(u16 Addr);             //单数据写入
 void FM25WriteByte(u16 Addr,u8 Wdat);    //单数据读取
void FM25WriteString(u16 WAddr, u8 *WDat ,u16 len);  //写入一串数据
void FM25ReadString(u16 WAddr, u8 *RDat ,u16 len);   //读出一串数据

#endif

FM25CL64.c

/*
************************************* Copyright ******************************
*
*                 (C) Copyright 2020,Wenkic,China, GCU.
*                            All Rights Reserved
*
*                     By(Wenkic)
*                      https://blog.csdn.net/Wekic
*
* FileName   : FM25CL64.c
* Version    : v1.0
* Author     : Wenkic
* Date       : 2020-03-29
* Description: FM25CL64 铁电存储驱动
* Function List:
******************************************************************************
*/
/********************************End of Head************************************/
#include "sys.h"
#include "FM25CL64.h"
#include "Soft_SPI.h"
//基础层函数声明============
void FM25_IOInit(void);
void FM25_CS(u8 IO);
void FM25_CLK(u8 IO);
void FM25_MOSI(u8 IO);
u8 FM25_MISO(void);
//==========================
//管脚定义宏================
#define FM_CS     PAout(4)
#define FM_CLK    PAout(5)
#define FM_MOSI   PAout(7)
#define FM_MISO   PAin(6)
//================================================
//           接口隔离层
//================================================
SPI_Type FM25_SPI = {
	.CS   = FM25_CS,
	.CLK  = FM25_CLK,
	.MOSI = FM25_MOSI,
	.MISO = FM25_MISO,
};
//SPI写
void FM25_WriteSPIByte(u8 dat)
{
	Soft_SPI_RW( FM25_SPI, dat);        //软件模拟读写一字节
}
//SPI读
u8 FM25_ReadSPIByte(void)
{
    return Soft_SPI_RW( FM25_SPI, 0xFF); //软件模拟读写一字节
}
//CS片选隔离
void FM25_CS_Out(u8 IO)
{
	IO?(FM25_SPI.CS(1)):(FM25_SPI.CS(0));
}

//==================================================
//          基础层
//==================================================
void FM25_IOInit(void)
{
	GPIO_InitTypeDef GPIO_InitStruct;
	FM_CS    = 1;
	FM_CLK   = 1;
	FM_MOSI  = 1;
	//CS,CLK,MOSI
	GPIO_InitStruct.GPIO_Mode = GPIO_Mode_Out_PP;
	GPIO_InitStruct.GPIO_Pin  = GPIO_Pin_4|GPIO_Pin_5|GPIO_Pin_7;
	GPIO_InitStruct.GPIO_Speed= GPIO_Speed_50MHz;
	GPIO_Init(GPIOA,&GPIO_InitStruct);


	//MISO
	GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IPU;
	GPIO_InitStruct.GPIO_Pin  = GPIO_Pin_6;
	GPIO_InitStruct.GPIO_Speed= GPIO_Speed_50MHz;
	GPIO_Init(GPIOA,&GPIO_InitStruct);


	FM_CS    = 1;
	FM25_ReadSPIByte();  //试读一次
}

//片选IO控制
void FM25_CS(u8 IO)
{
	FM_CS = IO?1:0;
}
//片选IO控制
void FM25_CLK(u8 IO)
{
	FM_CLK = IO?1:0;
}
//片选IO控制
void FM25_MOSI(u8 IO)
{
	FM_MOSI = IO?1:0;
}
//片选IO控制
u8 FM25_MISO(void)
{
	return (FM_MISO?1:0);
}


//================================================
//           驱动层
//================================================
#define    FM25_DELAY_CNT      10
//FM25L16B命令
#define     FM25_WREN       0x06   //写使能
#define     FM25_WRDI       0x04   //写禁止
#define     FM25_RDSR       0x05   //读状态寄存器
#define     FM25_WRSR       0x01   //写状态寄存器
#define     FM25_READ       0x03   //读存储器数据
#define     FM25_WRITE      0x02   //写存储器数据

/**
  * @Name    FM25CL_WriteEnable
  * @brief   FM25写使能
 **/
void FM25CL_WriteEnable(void)
{
	FM25_CS_Out(0);  //拉低CS
	FM25_WriteSPIByte(FM25_WREN); 
	FM25_CS_Out(1);  //拉高CS

}
/**
  * @Name    FM25CL_WriteDisable
  * @brief   FM25写禁止
 **/
void FM25CL_WriteDisable(void)
{
	FM25_CS_Out(0);  //拉低CS
	FM25_WriteSPIByte(FM25_WRDI); 
	FM25_CS_Out(1);  //拉高CS
}
/**
  * @Name    FM25CL_ReadReg
 * @brief   读取状态寄存器命令
 **/
u8 FM25CL_ReadReg(void)
{
	u8 temp;
	FM25_CS_Out(0);  //拉低CS
	FM25_WriteSPIByte(FM25_RDSR); //0x05命令
	temp = FM25_ReadSPIByte();    //读出数据
	FM25_CS_Out(1);  //拉高CS
	return temp;
}
/**
 * @Name    FM25CL_WriteReg
* @brief   写状态寄存器命令
**/
void FM25CL_WriteReg(u8 reg)
{
	FM25_CS_Out(0);  //拉低CS
	FM25_WriteSPIByte(FM25_WRSR); //0x01命令
	FM25_WriteSPIByte(reg);       //写入数据
	FM25_CS_Out(1);  //拉高CS
}
/**
 * @Name   FM25CL_ReadByte
* @brief   读取数据
**/
u8 FM25CL_ReadByte(u16 Addr)
{
	u8 temp;
	FM25_CS_Out(0);  //拉低CS
	FM25_WriteSPIByte(FM25_READ);      //0x03命令
	FM25_WriteSPIByte((Addr>>8)&0xFF); //地址高位
	FM25_WriteSPIByte((Addr>>0)&0xFF); //地址低位
	temp = FM25_ReadSPIByte();         //读取数据
	FM25_CS_Out(1);  //拉高CS
	return temp;
}

/**
* @Name   FM25CL_WriteByte
* @brief   写入数据
**/
void FM25CL_WriteByte(u16 Addr,u8 dat)
{
	FM25CL_WriteEnable();  //写使能
	FM25_CS_Out(0);   //拉低CS
	FM25_WriteSPIByte(FM25_WRITE);     //0x02命令
	FM25_WriteSPIByte((Addr>>8)&0xFF); //地址高位
	FM25_WriteSPIByte((Addr>>0)&0xFF); //地址低位
	FM25_WriteSPIByte(dat);            //写入数据
	FM25_CS_Out(1);  //拉高CS
}
/**
 * @Name   FM25CL_ReadString
* @brief   连续读取数据
**/
void FM25CL_ReadString(u16 Addr,u8 *dat,u16 len)
{
	FM25_CS_Out(0);  //拉低CS
	FM25_WriteSPIByte(FM25_READ);      //0x03命令
	FM25_WriteSPIByte((Addr>>8)&0xFF); //地址高位
	FM25_WriteSPIByte((Addr>>0)&0xFF); //地址低位
	while(len--)
	{
	 *dat = FM25_ReadSPIByte();         //读取数据	
	 dat++;
	}
	FM25_CS_Out(1);  //拉高CS
}

/**
* @Name   FM25CL_WriteString
* @brief   连续写入数据
**/
void FM25CL_WriteString(u16 Addr,u8 *dat,u16 len)
{
	FM25CL_WriteEnable();  //写使能
	FM25_CS_Out(0);   //拉低CS
	FM25_WriteSPIByte(FM25_WRITE);     //0x02命令
	FM25_WriteSPIByte((Addr>>8)&0xFF); //地址高位
	FM25_WriteSPIByte((Addr>>0)&0xFF); //地址低位
	while(len--)
	{
		FM25_WriteSPIByte(*dat);            //写入数据	
		dat++;
	}
	FM25_CS_Out(1);  //拉高CS
}

//================================================
//           应用层
//================================================
/**
* @Name   FM25WriteByte
* @brief   写入单数据
**/
void FM25WriteByte(u16 Addr,u8 Wdat)
{
  FM25CL_WriteByte( Addr, Wdat);
}
/**
* @Name   FM25ReadByte
* @brief   读取单数据
**/
u8 FM25ReadByte(u16 Addr)
{
  return FM25CL_ReadByte(Addr);
}
/**
* @Name   FM25CL_WriteString
* @brief   连续写入数据
**/
void FM25WriteString(u16 WAddr, u8 *WDat,u16 len)
{
void FM25WriteString(u16 WAddr, u8 *WDat,u16 len)
{
	FM25CL_WriteString( WAddr, WDat, len);
}
}
/**
* @Name   FM25ReadString
* @brief   连续写入数据
**/
void FM25ReadString(u16 WAddr, u8 *RDat,u16 len)
{
   FM25CL_ReadString( WAddr, RDat, len);
}

/********************************End of File************************************/

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章