记录开发过程中的问题和功能。毕se代做,小家电开发。 收徒带做企业级项目,帮助毕业生和转行人员顺利找到工作。

LiSun

记录开发过程中的问题和功能。毕se代做,小家电开发。 收徒带做企业级项目,帮助毕业生和转行人员顺利找到工作。

  博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理
/*************笔记****************
1、CubeMX 定义任意两个引脚,作为通讯脚,并对引脚作出如下配置:
   GPlO output level       --High
   GPIO mode               --Output open drai
   GPIO Pull-up/Pull-down  --No pull-up and no pull-down
   Maximum output speed    --LOW
   User label              --IIC_SCL/IIC_SDA

   IIC_SCL--PB6 IIC_SDA--PB7
   ---------------------------------------------------------
***********************************/
#include "hal_iic.h"

/**********************************************************************/
// 功能描述:用于IIC通讯时延时,以满足IIC对时序的要求(内部使用)
// 输入参数:cnt 延时记数器 (定义成volatile防止被优化掉)
// 返 回 值:无
// 编写时间:2014.11.21
// 作    者:
// 修改记录:
/**********************************************************************/
//#pragma optimize= none
void IIC_Delay(volatile uint32_t cnt)
{
    while(cnt--);
}
/**********************************************************************/
// 功能描述: IIC使能初始化
// 输入参数:I:结构体,定义IIC使用的PIN管脚
// 返 回 值:无
// 编写时间:2014.11.21
// 作    者:
// 修改记录:
/**********************************************************************/
void IIC_Init(const IIC_PIN *I)
{
    GPIO_WRITE_PIN(I->SCL_PORT, I->SCL_PIN, 1); //SCL = 1
    GPIO_WRITE_PIN(I->SDA_PORT, I->SDA_PIN, 1); //SDA = 1
}

/**********************************************************************/
// 功能描述: IIC通讯开始
// 输入参数:I:结构体,定义IIC使用的PIN管脚
// 返 回 值:无
// 编写时间:2014.11.21
// 作    者:胡安勤
// 修改记录:
/**********************************************************************/
void IIC_Start (const IIC_PIN *I)//
{

    GPIO_WRITE_PIN(I->SDA_PORT, I->SDA_PIN, 1);   //SDA = 1
    IIC_Delay(I->DelayTick);
    GPIO_WRITE_PIN(I->SCL_PORT, I->SCL_PIN, 1);   //SCL = 1
    IIC_Delay(I->DelayTick);
    GPIO_WRITE_PIN(I->SDA_PORT, I->SDA_PIN, 0);   //SDA = 0
    IIC_Delay(I->DelayTick);
    GPIO_WRITE_PIN(I->SCL_PORT, I->SCL_PIN, 0);   //SCL = 0
    IIC_Delay(I->DelayTick);

}
/**********************************************************************/
// 功能描述: IIC通讯结束
// 输入参数:I:结构体,定义IIC使用的PIN管脚
// 返 回 值:无
// 编写时间:2014.11.21
// 作    者:
// 修改记录:
/**********************************************************************/
void IIC_Stop (const IIC_PIN *I)
{
    GPIO_WRITE_PIN(I->SDA_PORT, I->SDA_PIN, 0);   //SDA = 0
    IIC_Delay(I->DelayTick);
    GPIO_WRITE_PIN(I->SCL_PORT, I->SCL_PIN, 1);   //SCL = 1
    IIC_Delay(I->DelayTick);
    GPIO_WRITE_PIN(I->SDA_PORT, I->SDA_PIN, 1);   //SDA = 1
    IIC_Delay(I->DelayTick);
}


/**********************************************************************/
// 功能描述: IIC从设备应答
// 输入参数:I:结构体,定义IIC使用的PIN管脚
// 返 回 值:0: 设备应答正常  1: 设备无应答
// 编写时间:2014.11.21
// 作    者:
// 修改记录:
/**********************************************************************/
IIC_STATUS IIC_Wait_ACK(const IIC_PIN *I)
{
    uint8_t s1;
    uint8_t i = 0;

    GPIO_WRITE_PIN(I->SCL_PORT, I->SCL_PIN, 1);           //SCL = 1
    IIC_Delay(I->DelayTick);

    s1 = GPIO_READ_PIN(I->SDA_PORT, I->SDA_PIN);
    while (s1 && i++ < 100) //判断是否应答 0应答,1无答
    {
        s1 = GPIO_READ_PIN(I->SDA_PORT, I->SDA_PIN);
    }

    GPIO_WRITE_PIN(I->SCL_PORT, I->SCL_PIN, 0);           //SCL = 0
    IIC_Delay(I->DelayTick);

    if(s1)
    {
        return(IIC_WAIT_ACK_ERR);
    }
    else
    {
        return(IIC_OK);
    }
}


/**********************************************************************/
// 功能描述: 主设备应答
// 输入参数:I:结构体,定义IIC使用的PIN管脚
// 返 回 值:无
// 编写时间:2014.11.21
// 作    者:
// 修改记录:
/**********************************************************************/
void IIC_ACK(const IIC_PIN *I)
{

    GPIO_WRITE_PIN(I->SDA_PORT, I->SDA_PIN, 0);       //SDA = 0
    IIC_Delay(I->DelayTick);
    GPIO_WRITE_PIN(I->SCL_PORT, I->SCL_PIN, 1);       //SCL = 1
    IIC_Delay(I->DelayTick);
    GPIO_WRITE_PIN(I->SCL_PORT, I->SCL_PIN, 0);       //SCL = 0
    IIC_Delay(I->DelayTick);
    GPIO_WRITE_PIN(I->SDA_PORT, I->SDA_PIN, 1);       //SDA = 1
}

/**********************************************************************/
// 功能描述: 主设备非应答
// 输入参数:I:结构体,定义IIC使用的PIN管脚
// 返 回 值:无
// 编写时间:2014.11.21
// 作    者:
// 修改记录:
/**********************************************************************/
void IIC_NACK(const IIC_PIN *I)
{

    GPIO_WRITE_PIN(I->SDA_PORT, I->SDA_PIN, 1);   //SDA = 1
    IIC_Delay(I->DelayTick);
    GPIO_WRITE_PIN(I->SCL_PORT, I->SCL_PIN, 1);   //SCL = 1
    IIC_Delay(I->DelayTick);
    GPIO_WRITE_PIN(I->SCL_PORT, I->SCL_PIN, 0);   //SCL = 0
    IIC_Delay(I->DelayTick);
}

/**********************************************************************/
// 功能描述: 发送一个字节
// 输入参数:I:结构体,定义IIC使用的PIN管脚  data: 待发送字节
// 返 回 值:无
// 编写时间:2014.11.21
// 作    者:
// 修改记录:
/**********************************************************************/
void IIC_WriteByte(const IIC_PIN *I, uint8_t data)
{
    uint16_t i;

    for(i = 0; i < 8; i++)
    {
        if((data & 0x80) == 0x80)
        {
            GPIO_WRITE_PIN(I->SDA_PORT, I->SDA_PIN, 1);  //SDA = 1
        }
        else
        {
            GPIO_WRITE_PIN(I->SDA_PORT, I->SDA_PIN, 0);  //SDA = 0
        }
        data = data << 1;
        IIC_Delay(I->DelayTick);
        GPIO_WRITE_PIN(I->SCL_PORT, I->SCL_PIN, 1);      //SCL = 1
        IIC_Delay(I->DelayTick);
        GPIO_WRITE_PIN(I->SCL_PORT, I->SCL_PIN, 0);      //SCL = 0
        //IIC_Delay(I->DelayTick);
    }
    IIC_Delay(I->DelayTick);
    GPIO_WRITE_PIN(I->SDA_PORT, I->SDA_PIN, 1);          //SDA = 1
}

/**********************************************************************/
// 功能描述: 从从设备接收一个字节
// 输入参数:I:结构体,定义IIC使用的PIN管脚
// 输出参数:data:读取到的字节
// 返 回 值:无
// 编写时间:2014.11.21
// 作    者:
// 修改记录:
/**********************************************************************/
void IIC_ReadByte(const IIC_PIN *I, uint8_t *data)
{
    uint8_t tmp = 0;
    uint8_t i;

    IIC_Delay(I->DelayTick);
    for(i = 0; i < 8; i++)
    {
        tmp = tmp << 1;
        GPIO_WRITE_PIN(I->SCL_PORT, I->SCL_PIN, 1);     //SCL = 1
        IIC_Delay(I->DelayTick);
        if (GPIO_READ_PIN(I->SDA_PORT, I->SDA_PIN))     //读数据脚
        {
            tmp = tmp | 0x01;
        }
        else
        {
            tmp = tmp & 0xfe;
        }
        GPIO_WRITE_PIN(I->SCL_PORT, I->SCL_PIN, 0);     //SCL = 0
        IIC_Delay(I->DelayTick);
    }
    *data = tmp;
}




#ifndef __IIC_Configuration_HEAD_
#define __IIC_Configuration_HEAD_

#include "main.h"
#define		GPIO_WRITE_PIN(PORT,PIN,VALUE)	HAL_GPIO_WritePin(PORT,PIN,(VALUE)?GPIO_PIN_SET:GPIO_PIN_RESET)
#define		GPIO_READ_PIN(PORT,PIN)					HAL_GPIO_ReadPin(PORT,PIN)

typedef enum  {
  IIC_OK           = 0x00,    //IIC工作正常
  IIC_WAIT_ACK_ERR = 0x01,    //slave设备返回ACK错误
  IIC_WRITE_ERR    = 0x02,    //向slave设备写入错误
  IIC_READ_ERR     = 0x04     //从slave设备读取错误
} IIC_STATUS;

typedef struct
{
  GPIO_TypeDef	*SCL_PORT;		//定义IIC时钟使用的端口
  uint16_t			SCL_PIN;			//定义IIC时钟使用的PIN脚
  GPIO_TypeDef	*SDA_PORT;   	//定义IIC数据使用的端口
  uint16_t			SDA_PIN;			//定义IIC数据使用的PIN脚
  uint32_t			DelayTick;   	//定义延时,以适应不同器件对速率的不同要求,具体值要在调试中确定
  uint8_t				ADDR;        	//器件地址
}IIC_PIN;

void IIC_Init(const IIC_PIN *I);
void IIC_Start (const IIC_PIN *I);
void IIC_Stop (const IIC_PIN *I);
IIC_STATUS IIC_Wait_ACK(const IIC_PIN *I);
void IIC_WriteByte(const IIC_PIN *I,uint8_t data);
void IIC_ReadByte(const IIC_PIN *I,uint8_t *data);
void IIC_ACK(const IIC_PIN *I);
void IIC_NACK(const IIC_PIN *I);

#endif

posted on 2022-08-13 11:01  嵌入式单片机实验室  阅读(160)  评论(0)    收藏  举报
记录开发过程中的问题和功能。毕se代做,小家电开发。 收徒带做企业级项目,帮助毕业生和转行人员顺利找到工作。