STM32下的 AS5600的IIC驱动

最近在学习AS5600的使用,在STM32F4上,便记录一下。如有问题欢迎指出。

AS5600是一个易于编程的磁性旋转位置传感器,具有高分辨率的12位模拟或PWM输出。这种非接触式系统测量一个直径磁化的轴上磁铁的绝对角度。该AS5600是为非接触式电位计的应用而设计的,其稳健的设计消除了任何均匀的外部杂散磁场的影响。

行业标准的I²C接口支持简单的非易失性参数的用户编程。

默认情况下,输出表示从0到360度的范围。还可以通过编程零角度(起始位置)和最大角度(停止位置)来定义更小的输出范围。

AS5600还配备了智能低功耗模式功能,以自动降低功耗。

输入引脚(DIR)根据旋转方向选择输出的极性。如果DIR连接到地面,则输出值随顺时针旋转而增加。如果DIR连接到VDD,则输出值随逆时针旋转而增加。

Functional Blocks of AS5600
SOIC-8 Pin-Out

#define  AS5600_Address  0x36
#define  RAW_Angle_Hi    0x0C


uint16_t ReadAS5600(void)
{
	unsigned char dh,dl;		  	    																 
	IIC_Start(IIC1);
	IIC_Send_Byte(IIC1,AS5600_Address<<1);
	IIC_Wait_Ack(IIC1);
	IIC_Send_Byte(IIC1,RAW_Angle_Hi);
	IIC_Wait_Ack(IIC1);
	IIC_Start(IIC1);
	IIC_Send_Byte(IIC1,(AS5600_Address<<1)+1);
	IIC_Wait_Ack(IIC1);
	dh=IIC_Read_Byte(IIC1,1);  
	dl=IIC_Read_Byte(IIC1,0);   
	IIC_Stop(IIC1);
	return ((dh<<8)+dl);
}


    value = ReadAS5600() & 0x0FFF;//打印即可
#define SDA0_IN()                        \
	{                                    \
		GPIOC->MODER &= ~(3 << (6 * 2)); \
		GPIOC->MODER |= 0 << (6 * 2);    \
	}
#define READ_SDA0 (GPIOC->IDR & (1 << 6))

void IIC_Start(uint8_t iic_num)
{
	if (iic_num == IIC0){
		SDA0_OUT();
		IIC0_SDA_H;
		IIC0_SCL_H;
		delay_s(IIC_DELAY_CNT); //延时8
		IIC0_SDA_L;
		delay_s(IIC_DELAY_CNT);
		IIC0_SCL_L;
	}else if (iic_num == IIC1){
		SDA1_OUT();
		IIC1_SDA_H;
		IIC1_SCL_H;
		delay_s(IIC_DELAY_CNT); //延时8
		IIC1_SDA_L;
		delay_s(IIC_DELAY_CNT);
		IIC1_SCL_L;
	}
}

void IIC_Stop(uint8_t iic_num)
{
	if (iic_num == IIC0){
		SDA0_OUT();
		IIC0_SCL_L;
		IIC0_SDA_L;
		delay_s(IIC_DELAY_CNT);
		IIC0_SCL_H;
		IIC0_SDA_H;
		delay_s(IIC_DELAY_CNT);
	}else if (iic_num == IIC1){
		SDA1_OUT();
		IIC1_SCL_L;
		IIC1_SDA_L;
		delay_s(IIC_DELAY_CNT);
		IIC1_SCL_H;
		IIC1_SDA_H;
		delay_s(IIC_DELAY_CNT);
	}
}

unsigned char IIC_Wait_Ack(uint8_t iic_num)
{
	unsigned char ucErrTime = 0;

	if (iic_num == IIC0){
		IIC0_SDA_H;
		delay_s(1);
		SDA0_IN();
		IIC0_SCL_H;
		delay_s(IIC_DELAY_CNT >> 1);
		while (READ_SDA0 != 0){
			if (++ucErrTime > 250){
				IIC_Stop(iic_num);
				return 1;
			}
		}
		IIC0_SCL_L;
	}else if (iic_num == IIC1){
		IIC1_SDA_H;
		delay_s(1);
		SDA1_IN();
		IIC1_SCL_H;
		delay_s(IIC_DELAY_CNT >> 1);
		while (READ_SDA1 != 0){
			if (++ucErrTime > 250){
				IIC_Stop(iic_num);
				return 1;
			}
		}
		IIC1_SCL_L;
	}
	return 0;
}

void IIC_Ack(uint8_t iic_num)
{
	if (iic_num == IIC0){
		IIC0_SCL_L;
		SDA0_OUT();
		IIC0_SDA_L;
		delay_s(IIC_DELAY_CNT);
		IIC0_SCL_H;
		delay_s(IIC_DELAY_CNT);
		IIC0_SCL_L;
	}else if (iic_num == IIC1){
		IIC1_SCL_L;
		SDA1_OUT();
		IIC1_SDA_L;
		delay_s(IIC_DELAY_CNT);
		IIC1_SCL_H;
		delay_s(IIC_DELAY_CNT);
		IIC1_SCL_L;
	}
}

void IIC_NAck(uint8_t iic_num)
{
	if (iic_num == IIC0){
		IIC0_SCL_L;
		SDA0_OUT();
		IIC0_SDA_H;
		delay_s(IIC_DELAY_CNT);
		IIC0_SCL_H;
		delay_s(IIC_DELAY_CNT);
		IIC0_SCL_L;
	}else if (iic_num == IIC1){
		IIC1_SCL_L;
		SDA1_OUT();
		IIC1_SDA_H;
		delay_s(IIC_DELAY_CNT);
		IIC1_SCL_H;
		delay_s(IIC_DELAY_CNT);
		IIC1_SCL_L;
	}
}

void IIC_Send_Byte(uint8_t iic_num, unsigned char txd)
{
	unsigned long i;
	if (iic_num == IIC0){
		SDA0_OUT();
		IIC0_SCL_L;
		for (i = 0; i < 8; i++){
			if ((txd & 0x80) != 0)
				IIC0_SDA_H;
			else
				IIC0_SDA_L;
			txd <<= 1;
			delay_s(IIC_DELAY_CNT);
			IIC0_SCL_H;
			delay_s(IIC_DELAY_CNT);
			IIC0_SCL_L;
			delay_s(IIC_DELAY_CNT);
		}
	}else if (iic_num == IIC1){
		SDA1_OUT();
		IIC1_SCL_L;
		for (i = 0; i < 8; i++){
			if ((txd & 0x80) != 0)
				IIC1_SDA_H;
			else
				IIC1_SDA_L;
			txd <<= 1;
			delay_s(IIC_DELAY_CNT);
			IIC1_SCL_H;
			delay_s(IIC_DELAY_CNT);
			IIC1_SCL_L;
			delay_s(IIC_DELAY_CNT);
		}
	}
}

unsigned char IIC_Read_Byte(uint8_t iic_num, unsigned char ack)
{
	unsigned char i, rcv = 0;

	if (iic_num == IIC0){
		SDA0_IN();
		for (i = 0; i < 8; i++){
			IIC0_SCL_L;
			delay_s(IIC_DELAY_CNT);
			IIC0_SCL_H;
			rcv <<= 1;
			if (READ_SDA0 != 0)
				rcv++;
			delay_s(IIC_DELAY_CNT >> 1);
		}
	}else if (iic_num == IIC1){
		SDA1_IN();
		for (i = 0; i < 8; i++){
			IIC1_SCL_L;
			delay_s(IIC_DELAY_CNT);
			IIC1_SCL_H;
			rcv <<= 1;
			if (READ_SDA1 != 0)
				rcv++;
			delay_s(IIC_DELAY_CNT >> 1);
		}
	}

	if (!ack)
		IIC_NAck(iic_num);
	else
		IIC_Ack(iic_num);
	return rcv;
}

  • 8
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值