IIC通信——PCF8591的D/A转换

PCF8591具有数模信号转换的功能,可以将单片机UART引脚发送的数字信号转换为模拟信号,单片机的P1.6引脚连接SDA数据线,负责在上面写字节和传送字节,P1.7引脚连接SCL时钟线,相当于节拍器,控制着数据的写入和传送,我们需要实现的是数字信号转换为模拟信号,而AIN0-AIN3引脚是模拟信号的输入端,用不到所以悬空,A0-A2是硬件地址端,这里将它们接地,因此引脚地址000_,再加上厂家已经给定的器件地址1001,组成器件总地址,AOUT引脚是数模转换的输出端,接到示波器的任何一个引脚,将转换成的模拟信号发送给示波器,使它显示相应波形图。

 声明SCL为单片机P1.7引脚,SDA为单片机P1.6引脚,定义全局变量IIC_ERROR。

延时函数:由四个_nop_()函数,实现一个4us的延时,方便后面程序直接调用。 

开始状态SCL处于高电平时,SDA从高电平转向低电平,表示一个开始状态,代码中先将SDA和SCL拉高,延时函数给硬件一定时间反应,然后再将SDA拉低,实现SDA由高到低的转变,再接延时函数给硬件一定时间反应,最后将时钟线SCL拉低为后面IICsendByte()实现输出(写)一个字节做准备。

 

停止状态SCL处于高电平时,SDA从低电平转向高电平,表示一个停止状态,代码中先将SCL拉高,SDA拉低,延时函数给硬件一定时间反应,然后再将SDA拉高,实现SDA由低到高的转变,再接延时函数给硬件一定时间反应,最后将时钟线SCL拉低。 

发送字节函数:函数定义了一个形式参数wd,用来实现后面器件总地址、控制字节、数据的发送,IIC总线以字节为单位传送数据,一个字节由8位二进制数组成,该函数通过(bit)(wd&0x80)实现强制转换为该字节的最高位,又通过wd<<=1非循环左移实现字节的每一位都能在一次循环中作为最高位输出,从而实现一个字节的输出。在IIC_Start()函数结束之前我们已经将SCL线拉低,此时在此函数中可以向SDA线上写入数据,两个_nop_()延时之后,再将SCL拉高,此时数据开始传送,延时之后再将SCL线拉低为下一次循环做准备,如此循环8次,就可以将一个字节中的8个二进制代码发送完成,从而实现一个字节的发送输出。发送完一个字节之后,等待4us延时,将SDA(PCF8591在收到每个字节之后,置SDA为低电平作为确认应答,所以需要先将其拉高)、SCL(当其为1时才能传送数据)拉高等待PCF8591的应答,并将SDA的状态赋值给IIC_ERROR,用于后面DAC_PCF8591函数判断是否将字节正确发送以便决定是否执行其他操作,之后将SCL置0以便继续使用发送字节函数发送其他字节。

数模信号转换函数:定义了形参CtrlByte作为传进来的控制字节,

形参wdata作为传进来的数据字节,调用IIC_Start()函数开始,调用发送字节函数发送第一个字节(PCF8591地址选择字节),判断PCF8591是否接收到(如果PCF8591接收到,就会置SDA为0作为应答,即IIC_ERROR为0,此时循环终止,继续后续操作),如果接收到,再发送第二个字节(PCF8591控制字节),如果接收到,再发送数据并继续检查应答位,如果接收到,调用IIC_Stop()函数结束。

主函数:在循环内完成以下操作,数字信号0x00~0xff:0000 0000~1111 1111,转换为十进制就是0~255,对应的模拟信号为0~5,传过去的i会自动以二进制的形式参与运算,先从0000 0000到1111 1111形成一个上升的波形,再从1111 1111到0000 0000形成一个下降的波形,从而共同形成一个一上一下的波。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值