GD32F130模拟IIC程序(读写功放芯片寄存器)

#define EE_SCL_PIN GPIO_PIN_0 //模拟IIC的SCL信号 
#define EE_SDA_PIN GPIO_PIN_1 //模拟IIC的SDA信号

#define EE_IIC_SCL(val) HAL_GPIO_WritePin(GPIOA, GPIO_PIN_0, val) //SCL
#define EE_IIC_SDA(val) HAL_GPIO_WritePin(GPIOA, GPIO_PIN_1, val) //SDA

uint8_t HAL_GPIO_ReadPin(uint32_t gpio_periph, uint32_t GPIO_PIN_x)
{
	return gpio_input_bit_get(gpio_periph,GPIO_PIN_x);
}

unsigned char EE_READ_SDA(void)
{
	return HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_1);
}

void EE_SDA_IN(void) //配置成输入
{

	rcu_periph_clock_enable(RCU_GPIOA);
	gpio_mode_set(GPIOA, GPIO_MODE_INPUT, GPIO_PUPD_PULLUP , GPIO_PIN_1);
}
void EE_SDA_OUT(void) //配置成输出
{
	rcu_periph_clock_enable(RCU_GPIOA);
	gpio_mode_set(GPIOA, GPIO_MODE_OUTPUT, GPIO_PUPD_NONE, GPIO_PIN_1);
	gpio_output_options_set(GPIOA,GPIO_OTYPE_PP,GPIO_OSPEED_50MHZ,GPIO_PIN_1);
}

void EE_SCK_OUT(void) //配置成输出
{
	rcu_periph_clock_enable(RCU_GPIOA);
	gpio_mode_set(GPIOA, GPIO_MODE_OUTPUT, GPIO_PUPD_NONE, GPIO_PIN_0);
	gpio_output_options_set(GPIOA,GPIO_OTYPE_PP,GPIO_OSPEED_50MHZ,GPIO_PIN_0);
}

/* 此函数移植 */
void HAL_GPIO_WritePin(uint32_t gpio_periph, uint32_t GPIO_PIN_x, uint32_t val)
{
	if (val == 1)
		gpio_bit_write(gpio_periph, GPIO_PIN_x,SET);
	else
		gpio_bit_write(gpio_periph, GPIO_PIN_x,RESET);
}



/******************************************************************************
*函  数:void EE_IIC_Delay(void)
*功 能:IIC延时ms
*参  数:无
*返回值:无
*备  注: 移植时只需要将EE_IIC_Delay()换成自己的延时即可
*******************************************************************************/
static void EE_IIC_Delay(int us)
{
	int i;
	while(us--)
	for (i = 0; i < 2*18; i++);
	
}
/******************************************************************************
*函  数:void IIC_Init(void)
*功 能:IIC初始化
*参  数:无
*返回值:无
*备  注:无
*******************************************************************************/

void EE_IIC_Init(void)
{
	EE_SCK_OUT();
	EE_SDA_OUT();
	EE_IIC_SCL(1);
	EE_IIC_SDA(1);
}
/******************************************************************************
*函  数:
*功 能:
*参  数:无
*返回值:无
*备  注:无
*******************************************************************************/
void EE_IIC_Start(void)
{
	EE_SDA_OUT(); //sda线输出
	EE_IIC_SDA(1);
	EE_IIC_SCL(1);
	EE_IIC_Delay(4);
	EE_IIC_SDA(0); //START:when CLK is high,DATA change form high to low
	EE_IIC_Delay(4);
	EE_IIC_SCL(0); //钳住I2C总线,准备发送或接收数据
}
/******************************************************************************
*函  数:
*功 能:
*参  数:无
*返回值:无
*备  注:无
*******************************************************************************/
void EE_IIC_Stop(void)
{
	EE_SDA_OUT(); //sda线输出
	EE_IIC_SCL(0);
	EE_IIC_SDA(0); //STOP:when CLK is high DATA change form low to high
	EE_IIC_Delay(4);
	EE_IIC_SCL(1);
	EE_IIC_SDA(1); //发送I2C总线结束信号
	EE_IIC_Delay(4);
}

/******************************************************************************
*函  数:
*功 能:
*参  数:无
*返回值:无
*备  注:无
*******************************************************************************/
uint8_t EE_IIC_WaitAck(void)
{
	uint16_t ucErrTime = 0;
	EE_IIC_SDA(1);
	EE_SDA_IN(); //SDA设置为输入  (从机给一个低电平做为应答)
	EE_IIC_Delay(1);
	EE_IIC_SCL(1);
	EE_IIC_Delay(1);
	;
	while (EE_READ_SDA())
	{
		ucErrTime++;
		if (ucErrTime > 250)
		{
			EE_IIC_Stop();
			return 1;
		}
	}
	EE_IIC_SCL(0); //时钟输出0
	return 0;
}

/******************************************************************************
*函  数:
*功 能:
*参  数:无
*返回值:无
*备  注:无
*******************************************************************************/

void EE_IIC_Ack(void)
{
	EE_IIC_SCL(0);
	EE_SDA_OUT();
	EE_IIC_SDA(0);
	EE_IIC_Delay(2);
	EE_IIC_SCL(1);
	EE_IIC_Delay(2);
	EE_IIC_SCL(0);
}
/******************************************************************************
*函  数:
*功 能:
*参  数:无
*返回值:无
*备  注:无
*******************************************************************************/
void EE_IIC_NAck(void)
{
	EE_IIC_SCL(0);
	EE_SDA_OUT();
	EE_IIC_SDA(1);
	EE_IIC_Delay(2);
	EE_IIC_SCL(1);
	EE_IIC_Delay(2);
	EE_IIC_SCL(0);
}
/******************************************************************************
*函  数:
*功 能:
*参  数:无
*返回值:无
*备  注:无
*******************************************************************************/
static void EE_IIC_Unlock()
{
	int i;
	for(i=0;i<10;i++)
	{
		EE_IIC_Delay(2);
		EE_IIC_SCL(1);
		EE_IIC_Delay(2);
		EE_IIC_SCL(0);
	}
	EE_IIC_SCL(1);
	EE_IIC_SDA(1);
}
/******************************************************************************
*函  数:
*功 能:
*参  数:无
*返回值:无
*备  注:无
*******************************************************************************/
void EE_IIC_SendByte(uint8_t data)
{
	uint8_t t;
	EE_IIC_SCL(0); //拉低时钟开始数据传输
	EE_SDA_OUT();
	EE_IIC_SCL(2);
	for (t = 0; t < 8; t++)
	{
		EE_IIC_SDA((data & 0x80) >> 7);
		EE_IIC_Delay(1);
		EE_IIC_SCL(1);
		data <<= 1;
		EE_IIC_Delay(1);
		EE_IIC_SCL(0);
	}
	EE_IIC_Delay(1);
}
/******************************************************************************
*函  数:void IIC_Init(void)
*功 能:IIC初始化
*参  数:无
*返回值:无
*备  注:无
*******************************************************************************/
uint8_t EE_IIC_ReadByte(uint8_t ack)
{
	uint8_t i, receive = 0;
	EE_SDA_IN(); //SDA设置为输入模式 等待接收从机返回数据
	for (i = 0; i < 8; i++)
	{
	//	EE_IIC_Delay(1);
		EE_IIC_SCL(0);
		EE_IIC_Delay(2);
		EE_IIC_SCL(1);
		receive <<= 1;
		if (EE_READ_SDA())
		{
			receive++; //从机发送的电平
		}
		EE_IIC_Delay(1);
	}
	if (ack)
		EE_IIC_Ack(); //发送ACK
	else
		EE_IIC_NAck(); //发送nACK
	return receive;
}
/******************************************************************************
*函  数:
*功 能:
*参  数:无
*返回值:无
*备  注:无
*******************************************************************************/
uint8_t EE_IIC_ReadByteFromSlave(uint8_t I2C_Addr, uint8_t reg, uint8_t *buf)
{
	EE_IIC_Start();
	EE_IIC_SendByte(I2C_Addr); //发送从机地址
	if (EE_IIC_WaitAck())	   //如果从机未应答则数据发送失败
	{
		printf("ER\n");
		EE_IIC_Stop();
		return 1;
	}
	EE_IIC_SendByte(reg); //发送寄存器地址
	EE_IIC_WaitAck();
	

	EE_IIC_Start();
	EE_IIC_SendByte(I2C_Addr + 1); //进入接收模式
	EE_IIC_WaitAck();
	*buf = EE_IIC_ReadByte(0);
	EE_IIC_Stop(); //产生一个停止条件
	return 0;
}
/******************************************************************************
*函  数:
*功 能:
*参  数:无
*返回值:无
*备  注:无
*******************************************************************************/
uint8_t EE_EE_IIC_SendByteToSlave(uint8_t I2C_Addr, uint8_t reg, uint8_t data)
{
	EE_IIC_Start();
	EE_IIC_SendByte(I2C_Addr); //发送从机地址
	if (EE_IIC_WaitAck())
	{
		EE_IIC_Stop();
		return 1; //从机地址写入失败
	}
	EE_IIC_SendByte(reg); //发送寄存器地址
	EE_IIC_WaitAck();
	EE_IIC_SendByte(data);
	if (EE_IIC_WaitAck())
	{
		EE_IIC_Stop();
		return 1; //数据写入失败
	}
	EE_IIC_Stop(); //产生一个停止条件
	EE_IIC_Delay(2);
	return 0;
}


/******************************************************************************
*函  数:
*功 能:
*参  数:无
*返回值:无
*备  注:无
*******************************************************************************/
uint8_t EE_EE_IIC_SendMultiByteToSlave(uint8_t I2C_Addr, unsigned char data[], uint8_t length)
{
	unsigned char index;
	EE_IIC_Start();
	EE_IIC_SendByte(I2C_Addr); //发送从机地址
	if (EE_IIC_WaitAck())
	{
		EE_IIC_Stop();
		return 1; //从机地址写入失败
	}
	EE_IIC_SendByte(data[0]); //发送寄存器地址
	EE_IIC_WaitAck();

	for(index = 1; index<length; index++)
	{
		EE_IIC_SendByte(data[index]); //发送数据
		EE_IIC_WaitAck();
		EE_IIC_Delay(2);
	}
	EE_IIC_Stop(); //产生一个停止条件
	EE_IIC_SDA(1);
	EE_IIC_Delay(50);
	return 0;
}

读取寄存器0x4c,返回值成功;

 将gpio_mode_set(GPIOA, GPIO_MODE_INPUT, GPIO_PUPD_PULLUP , GPIO_PIN_1);改成

gpio_mode_set(GPIOA, GPIO_MODE_INPUT,  GPIO_PUPD_NONE , GPIO_PIN_1);

此时读寄存器值不正确

 

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值