PCF8591(AD&DA转换芯片)

工具

1.Proteus 8 仿真器

2.keil 5 编辑器

原理图

讲解

PCF8591是一个单片集成、单独供电、低功耗、8-bit CMOS数据获取器件。PCF8591具有4个模拟输入、1个模拟输出和1个串行I²C总线接口。PCF8591的3个地址引脚A0, A1和A2可用于硬件地址编程,允许在同个I2C总线上接入8个PCF8591器件,而无需额外的硬件。在PCF8591器件上输入输出的地址、控制和数据信号都是通过双线双向I2C总线以串行的方式进行传输。

作用

AD (模数转换)

        将模拟信号(电流或电压信号)装换成数字信号(电平信号)

DA (数模转换)

        将数字信号(电平信号)装换成模拟信号(电流或电压信号)

特性

  1. 单独供电
  2. PCF8591的操作电压范围2.5V-6V
  3. 低待机电流
  4. 通过I2C总线串行输入/输出
  5. PCF8591通过3个硬件地址引脚寻址
  6. PCF8591的采样率由I2C总线速率决定
  7. 4个模拟输入可编程为单端型或差分输入
  8. 自动增量频道选择
  9. PCF8591的模拟电压范围从VSS到VDD
  10. PCF8591内置跟踪保持电路
  11. 8-bit逐次逼近A/D转换器
  12. 通过1路模拟输出实现DAC增益

引脚信息

引脚 说明
ANI0~AIN3 模拟信号输入端
A0~A2 引脚地址端
VDD 电源正
VSS 电源负
SDA I2C数据线
SCL I2C时钟线
OSC

外部时钟输入端,内部时钟输出端

EXT

内部、外部时钟选择线,使用内部时钟时 EXT 接地

AGND 模拟信号地
AOUT D/A转换输出端
VREF

基准电源端(注意:不可超过芯片的最大电压值,同时基准电压参与采样输出值的计算)

数字值 = (模拟电压 / VREF) * 256

内部结构

功能描述

寻址

D7 D6 D5 D4 D3 D2 D1 D0
1 0 0 1 A2 A1 A0 R/W

地址总是必须作为12c总线协议中的开始条件之后的第一个字节被发送。I2C总线系统中的每一片PCF8591都通过发送有效地址到该器件来激活。高四位为固定部分,低四位为可编程部分,A2,A1,A0是引脚地址,最低位是读写功能位:0是写,1是读。

控制

D7 D6 D5 D4 D3 D2 D1 D0
未用(写0)

D/A输出允许位

0禁止 1允许

A/D输入方式选择位

00:4路单端输入

01:3路差分输入

10:单端与差分输入

11:2路差分输入

未用(写0)

自动益增选择位

0禁止 1允许

AD通道选择位

00:选择通道0

01:选择通道1

10:选择通道2

11:选择通道3

发送到PCF8591设备的第二个字节将存储在其控制寄存器中,并需要控制设备的功能。
控制寄存器的高4位用于使能模拟输出,并将模拟输入编程为单端或差分输入。
低4位选择由高4位所定义的模拟输入通道之一。
如果设置了自动增量标志,在每次A/D转换后,通道号会自动增加。
如果在使用内部振荡器的应用中需要自动增量模式,则应该设置控制字节(第6位)中的模拟输出使能标志。
这允许内部振荡器连续运行,从而防止由振荡器启动延迟导致的转换错误。上电复位后,控制寄存器的所有位都复位为逻辑0。为了省电,D/A转换器和振荡器被禁用。模拟输出被切换到高阻抗状态。

D5 D4 模拟输入配置方式 

注意

读取数据时会先反馈上一次模数转换的数据

 

 

代码

采集通道1模拟电压值并在液晶显示

#include <reg52.h>
#include "Delay.H"
#include "LCD1602.H"
#include <intrins.H>
sbit SDA = P2^7;   //数据
sbit SCL = P2^6;	 //时钟
sbit button =P1^7; //按钮
unsigned int num=0; //电压值

#define delay();{_nop_();_nop_();_nop_();_nop_();_nop_();} //五个机器周期 5微妙 一周期多长时间与晶振有关
 

 
/**
  * @brief  开始信号
  * @param  
  * @param 
  * @param 
  * @retval 
  */
void start()
{
	SDA=1;
	SCL=1;	
	delay();
	SDA=0; 
	delay();
	SCL=0;
}
/**
  * @brief  结束信号
  * @param  
  * @param 
  * @param 
  * @retval 
  */
void end()
{
	SDA=0;	
	SCL=1;
	delay();
	SDA=1;
	delay_ms(10);
}
 
// 发送
void send_data(unsigned char byte)
{
	unsigned char i;
	for(i=0;i<8;i++) //字节拆分按位传递
	{	//SCL为高电平 读取SDA稳定数据 所以SDA变化在前
		SDA=byte&(0x80>>i); //从最高位依次传递给SDA 
		delay();
		SCL=1;
		delay();
		SCL=0;
	}
}
 
// 接收
unsigned char read()
{
	unsigned char i,byte=0x00;
	SDA=1; 
	for(i=0;i<8;i++) //字节拆分按位接收
	{	
		SCL=1;
		delay();
		if(SDA){byte|=(0x80>>i);}
		delay();
		SCL=0;
	}
	return byte;
}
 
// 假设SCL和SDA是控制I2C时钟线和数据线的宏或变量  
// delay函数用于提供必要的延迟,确保时序正确  
  
void send_sck(bit ACK) { 
    // 根据ACK的值设置数据线SDA  
    SDA = ACK; // 注意:通常ACK是低电平,NACK是高电平
    delay();   // 保持SDA状态,等待从机读取 
    SCL = 1;   // 将时钟线SCL拉高 
    delay();   // 等待时钟线稳定 
    SCL = 0;   // 将时钟线SCL拉低,结束应答  
    delay();   // 等待时钟线稳定  
	SDA = 1;   //释放数据线 线权交给从机
}
//接收应答
bit read_sck()
{
	bit ACK;
	SDA=1;
	delay();    //5us
	SCL=1;
	delay();    //5us
	ACK=SDA;
	delay();    //5us
	SCL=0;
	return ACK;
}
 /**
* @brief  I2C发送
   * @param  address 器件地址  byte PCF8591芯片 第二字节紧跟着 控制地址
   * @param 
   * @param 
   * @retval 
   */
void I2C_send(unsigned char address,unsigned char byte)
{
	start();
	send_data(address); 
	read_sck();
	send_data(byte);
	read_sck();
	end();
	delay_ms(5);
}
 /**
* @brief  I2C读取
   * @param  address 器件地址  
   * @param 
   * @param 
   * @retval 
   */
unsigned char I2C_read(unsigned char address)
{
	unsigned char read_data;
		start();
		send_data(0x91); //器件
		read_sck();
		read();
		send_sck(0);   //应答
		read_data=read();
		send_sck(1);   //非应答停止接收
		end();
	return read_data;
}


main(void) 
{ 
	LCD_Init(); //初始化液晶
	LCD_ShowString(1,1,"Old_man");
	LCD_ShowString(2,1,"0.00V");
	while(1)
	{
		//按钮按下
		if(!button)
		{
			while(!button);
			//按钮抬起后
			//I2C 读取PCF8591的值
			I2C_send(0x90,0x01);
			num=I2C_read(0x91); 	//读取的值		
			LCD_ShowNum(2,1,num*(5*1000/255)/1000,1);							//整数部分
			LCD_ShowString(2,2,".");								//小数点
			LCD_ShowNum(2,3,num*(5*1000/255)/10%100,2);		//小数部分
			LCD_ShowString(2,5,"V");
		}
	}


} 
 
 

实现

🚀本欧也处于学习阶段,所学所识将以笔记发布。

笔记会根据相关知识的接触而随时更新! 

 如果文章对你有帮助,请留下你宝贵的点赞吧👍

V:Werluo  本欧也很喜欢交朋友的哦! 

 

相关推荐

最近更新

  1. TCP协议是安全的吗?

    2024-04-08 07:36:02       19 阅读
  2. 阿里云服务器执行yum,一直下载docker-ce-stable失败

    2024-04-08 07:36:02       19 阅读
  3. 【Python教程】压缩PDF文件大小

    2024-04-08 07:36:02       20 阅读
  4. 通过文章id递归查询所有评论(xml)

    2024-04-08 07:36:02       20 阅读

热门阅读

  1. C语言学习分享

    2024-04-08 07:36:02       12 阅读
  2. 什么是物联网?

    2024-04-08 07:36:02       13 阅读
  3. 小程序View点击响应传递多个参数

    2024-04-08 07:36:02       12 阅读
  4. 微信小程序脚本的执行顺序

    2024-04-08 07:36:02       13 阅读
  5. KADB锁冲突查看及解决

    2024-04-08 07:36:02       12 阅读
  6. 金融数据_Scikit-Learn决策树(DecisionTreeClassifier)实例

    2024-04-08 07:36:02       14 阅读
  7. 【面经】软件开发工程师-后端方向1

    2024-04-08 07:36:02       12 阅读
  8. 2024-04-07(复盘前端)

    2024-04-08 07:36:02       12 阅读
  9. MCU电子方案开发

    2024-04-08 07:36:02       13 阅读
  10. Vue3 + TS 按需引入和全局引入 Echarts

    2024-04-08 07:36:02       12 阅读
  11. FPGA与数字图像处理专栏分类与索引

    2024-04-08 07:36:02       14 阅读