IIC好像也不是很难|AD5175初次体验

本文详细讲述了作者使用STM32与AD5175进行IIC通信的全过程,包括IIC信号介绍、电路原理图的修改、上拉电阻的选择、以及在HAL库和硬件调试中的挑战与解决方案。重点强调了硬件电路的重要性。
摘要由CSDN通过智能技术生成

目录

经过了近两个礼拜的折磨,终于用STM32驯服AD5175了,从一开始调整硬件,修改软件,反复阅读数据手册,最后再到硬件修改。回过头看会觉得简单,但是每一个被忽略的小细节就决定了最后的成败。分享一下这段经历,给自己一个总结,也给大家提个醒。(中间出现的原理图有错误,将在最后放能用的电路图)

IIC简介

IIC(Inter-Integrated Circuit),集成电路总线,常见的称呼还有I2C,是飞利浦公司推出的一种半双工同步通信方式。IIC串行总线的信号线有数据线SDA时钟线SCL,一般两根线都接有上拉电阻,以确保在空闲时刻都为高电平。IIC设备分为主机和从机,而每个设备都有其唯一的地址,这些设备连接在同一IIC总线上,由主机发出广播,控制相应地址的从机。

IIC常见的几种信号

起始信号

IIC从机并不是一直在等着数据,只有当起始信号出现后,从机才会知道,主机要开始叫人干活了。IIC协议中对起始信号的定义是这样的:当时钟线(SCL)为高电平时,数据线(SDA)从高电平向低电平跳变。代码示例

// 产生IIC起始信号
void IIC_Start(void)
{
	SDA_OUT();     
	IIC_SDA=1;	  	  
	IIC_SCL=1;
	delay_us(4);
 	IIC_SDA=0;
	delay_us(4);
	IIC_SCL=0;
}	

结束信号

就像我们聊天结束的时候说拜拜,而从机知道主机结束本次数据传输就是通过结束信号表达的:当时钟线(SCL)为高电平时,数据线(SDA)从低电平向高电平跳变。代码示例

// 产生IIC结束信号
void IIC_Stop(void)
{
	SDA_OUT();
	IIC_SDA=0;
	delay_us(4);	
	IIC_SCL=1;
	delay_us(4);	
	IIC_SDA=1;
	delay_us(4);							   	
}	

应答信号

主机每发送一个字节(8bit),从机就会反馈一个应答信号。一般的,把数据线(SDA)拉高,主机放开对数据线的控制,如果是有效应答位(ACK),从机会把数据线(SDA)电平拉低。若数据线(SDA)为高电平,称为非应答位(NACK)。代码示例

//对于从机而言
//产生ACK信号
void IIC_Ack(void)
{
	IIC_SCL=0;
	SDA_OUT();
	IIC_SDA=0;
	delay_us(2);
	IIC_SCL=1;
	delay_us(2);
	IIC_SCL=0;
}
//产生NACK信号
void IIC_NAck(void)
{
	IIC_SCL=0;
	SDA_OUT();
	IIC_SDA=1;
	delay_us(2);
	IIC_SCL=1;
	delay_us(2);
	IIC_SCL=0;
}		
//对于主机而言
//等待应答信号
u8 IIC_Wait_Ack(void)
{
	u8 ErTime=0;	   
	SDA_IN();      
	IIC_SCL=1;
	delay_us(1);	 
	while(READ_SDA)
	{
		ErTime++;
		if(ErTime>250)
		{
			IIC_Stop();
			return 1;
		}
	}
	IIC_SCL=0;
	return 0;  
}	

发送一个字节

代码示例

//发送一个字节
void IIC_Send_Byte(u8 txd)
{                        
    u8 t;   
	SDA_OUT(); 	    
    IIC_SCL=0;
    for(t=0;t<8;t++)
    {              
		IIC_SDA=(txd&0x80)>>7;
		txd<<=1; 	  
		delay_us(2);   
		IIC_SCL=1;
		delay_us(2); 
		IIC_SCL=0;	
		delay_us(2);
    }	 
} 	

读取一个字节

代码示例

//读取一个字节
u8 IIC_Read_Byte(unsigned char ack)
{
	unsigned char i,receive=0;
	SDA_IN();
	for(i=0;i<8;i++ )
	{
		IIC_SCL=0; 
		delay_us(2);
		IIC_SCL=1;
		receive<<=1;
		if(READ_SDA)
				receive++;   
		delay_us(1); 
	}					 
	if (!ack)
		IIC_NAck();
	else
		IIC_Ack(); 
	return receive;
}

电路原理图

AD5175的数据手册中没有给出具体的参考设计电路,但是有各个引脚的说明
在这里插入图片描述
PIN1:单电源模式下为2.7-5.5V;双电源模式下为正负2.5V到正负2.75V。
PIN2和PIN3是电阻的接头,没有正负极之分,但要注意每个引脚电压需要在VSS和VDD之间。
PIN4:电源负极,单电源时候接地。
PIN5:外部电容,对地接1uF电容
PIN6:地
PIN7:软件复位,低电平有效
PIN8:数据线
PIN9:时钟线
PIN10:地址位(详见数据手册)

根据数据手册可以很容易设计出电路原理图,如下图:
在这里插入图片描述
很容易看出,数据线和时钟线的地方没有接上拉电阻,后期补上了两个10k的上拉电阻(挖坑了)

莽改AD5175电阻值

从数据手册的写操作可以看出,只需要发送3字节数据就能写入一次数据(具体数据格式见数据手册)
在这里插入图片描述
一开始写的时候就很莽,看到时序图,就去找对应的操作怎么修改RDAC的值(也不是说不行,就是少了一步)。代码示例

//修改RDAC
unsigned char AD5175_WriteRDAC(void)
{				   	  	    																 
    IIC_Start(); 
		IIC_Send_Byte(0x58);	    
   	if(IIC_Wait_Ack())
		return 1;
	IIC_Send_Byte(0x05);	   
	if(IIC_Wait_Ack())
		return 2;
	IIC_Send_Byte(0x00);
	if(IIC_Wait_Ack())
		return 3;
	IIC_Stop();
}

在这里插入图片描述
写完这个,RDAC的值怎么都不会发生改变,电阻值也不会跟着变,当时就是开始查硬件的问题,也是在这个时候发现了少了上拉电阻;但是接了上拉电阻之后也不会发生任何改变。然后就开始用示波器去观察时钟信号和数据信号:
请添加图片描述
按照时钟周期一个一个的去对数据信号,改变数据信号,看到的波形也能发生变化;就开始纳闷数据发送正确,会不会还是硬件问题,甚至还怀疑是不是A和W引脚有正负极之分,在PCB上割线、飞线,调试过程还弄断了三块AD5175的芯片引脚请添加图片描述

IIC调试器

师兄看不下去了,掏出了他压箱底的IIC调试器给我用。
在这里插入图片描述
通过上位机软件发送IIC指令,后面还是用杜邦线和飞线接到AD5175上。这个上位机可以扫描从机地址,奇怪的是,怎么都扫不到,但是发送的数据波形还是正确的,就没有理会这个小bug。虽然波形正确,可怎么都不会改变AD5175的阻值;开始怀疑是不是这个模块坏了,用一个之前调成功的PCF8563模块和这个调试器接起来,发现可以读取到从机地址,但仍无法接收到正常反馈数据,遂止。

STM32的HAL库函数

既然调试器不会用,还害怕自己写的模拟IIC程序有问题,那就用HAL库,也是在这个阶段,在一次逛论坛的时候,看到有大佬说,有些是有写保护的。果然,数据手册中一查,WRITE PROTECTION几个大字赫然眼前,看到这里都想抽自己了,但也庆幸终于找到解脱之道了。
在这里插入图片描述
所以,在写RDAC之前,需要先把RDAC的写保护关闭(默认开启),在控制寄存器(control register)中把C1置为高电平即可关闭RDAC的写保护。再写入正常数据前,先写入0x1c和0x02。代码示例

//主函数
 while (1)
 {
	unsigned char temp[4]= {0x1c,0x02,0x05,0x00};
   /* USER CODE END WHILE */
	HAL_I2C_Master_Transmit(&hi2c2, 88 ,temp , I2C_MEMADD_SIZE_8BIT, 0xfff);
	HAL_I2C_Master_Transmit(&hi2c2, 88 ,temp+1 , I2C_MEMADD_SIZE_8BIT, 0xfff);
	HAL_Delay(20);
	HAL_I2C_Master_Transmit(&hi2c2, 88 ,temp+2 , I2C_MEMADD_SIZE_8BIT, 0xfff);
	HAL_I2C_Master_Transmit(&hi2c2, 88 ,temp+3 , I2C_MEMADD_SIZE_8BIT, 0xfff);
	HAL_Delay(20);
	
   /* USER CODE BEGIN 3 */
 }

但即使是到这个份上,AD5175的阻值还纹丝不动,那就只能怀疑主机是不是有问题,即使单片机最小系统之前一直用的好好的,但也有可能SMT的时候BOM配错了什么的;然后又花了半天检查了PCBA的BOM,看也看不出个名堂,那还不如用开发板呢。这时候前几天单独做的AD5175的转接板到了,那就把他接到开发板上,再用上述代码操作。
请添加图片描述
当然,结果还是不尽人意,既然确保了上位机硬件、软件没问题。从机的通讯也基本可以确定没问题,那问题还是可能出现在从机的硬件上。

一次偶然的相遇

虽然觉得问题出现在从机硬件上,可就几个电容电阻的怎么也看不出问题。在一次偶然的搜索中,刷到一篇卓大大写的关于AD5272的调试[^1]
链接: AD5272数字变阻器
看到他用的上拉电阻是2k,抱着无路可走的态度,也把上拉改小了(原来10k),这一改不要紧,AD5175的阻值开始可以控制!原来门道都在这啊!

上拉电阻的选择

作者在一开始在上拉电阻的选择时,就在网上随便搜了个电路,想着上拉电阻只要有就行的想法,照着安装了个10k的上拉电阻。下面是在网上搜集的上拉电阻选择的一些注意事项,如有错误,敬请指出。

上拉电阻不能太大

当上拉电阻大了之后,在电路中消耗的攻略就多了,所能流过的电流也小了。这个电流过小会影响芯片的正常工作;上拉电阻大了之后还会导致电压变化速度慢,可能会产生误码。

上拉电阻也不能太小

电阻小了,一个最直观的影响就是,能流过该电阻的电流变大,电流过大容易超出电阻的额定工作电压,同时输入到芯片的电流大了(超过引脚最大允许电流),也会对芯片造成损伤。

上拉电阻实际应用时候的选择

上拉电阻的值,可以通过计算得到最大值和最小值,只需要在这个里面选择就行,NXP有一份文档描述了IIC总线和上拉电阻的选择,链接: link
网上也有一些比较粗暴的方法:在1-10k中间选一个合适的。
具体怎么操作还是根据自己的喜好来(出了问题可能就是怎么也不会想到是上拉电阻的问题)

总结

遇到的问题有两个:
1、写RDAC的时候没有关闭RDAC的写保护
2、上拉电阻过大,驱动能力不足
最终的电路图就如下所示。
在这里插入图片描述

尝试了模拟IIC;电脑做主机,用调试器控制从机;用开发板调试;用HAL库调试;每种方法都是可以达到最终的效果的,所以在写程序前,一定一定要检查硬件电路的问题,硬件有问题,软件写出花来了也带不动。

PyTorch深度学习实战中,可以使用卷积神经网络进行图像分类任务。在实战中,可以使用经典的卷积神经网络模型,如VGG、ResNet、Inception和DenseNet等。这些模型都是在深度学习的发展过程中出现的经典模型,对深度学习的学术研究和工业生产都起到了巨大的促进作用。初学者可以通过阅读论文和实现代码来全面了解这些模型。例如,可以使用PyTorch中的torchvision.models模块来加载预训练的卷积神经网络模型,如VGG-16、VGG-19和ResNet等\[1\]。其中,VGG-16和VGG-19是由卷积层、池化层和全连接层等不同组合构成的经典卷积神经网络模型\[1\]。而ResNet是一种使用残差单元连接而成的卷积神经网络模型,通过跨层的短接来突出微小的变化,使得网络对误差更加敏感,并解决了网络退化现象,具有良好的学习效果\[2\]\[3\]。因此,在PyTorch深度学习实战中,可以选择合适的卷积神经网络模型来进行图像分类任务。 #### 引用[.reference_title] - *1* *2* *3* [PyTorch深度学习实战 | 典型卷积神经网络](https://blog.csdn.net/qq_41640218/article/details/129832298)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insert_down1,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值