【蓝桥杯单片机进阶强化-01】PCF8591的基本原理与A/D转换应用

【蓝桥杯单片机进阶强化-01】PCF8591的基本原理与A/D转换应用

内容来自b站小蜜蜂老师 蓝桥杯练习进阶

一、题目展示在这里插入图片描述

二、PCF8591基本介绍

2.1 PCF8591功能概述

在这里插入图片描述

PCF8591是具有IIC接口的8位A/D和D/A转换芯片,具有4路模拟输入、一路DAC输出和一个IIC总线接口。其主要的功能特性如下:
      ●单电源供电,典型值为5V。
      ●通过3个硬件地址引脚编址。
      ●8位逐次逼近式A/D转换。
      ●片上跟踪与保持电路,采样速率取决与IIC总线速度。
      ●4路模拟输入可编程为单端输入或查分输入。
      ●自动增量通道选择。
      ●带一个模拟输出的乘法DAC。

2.2 PCF8591内部AD/DA转换电路

在这里插入图片描述

2.3 访问规则

在这里插入图片描述

PCF8591为一个IIC挂载设备,所以在进行编程时就要符合IIC通信原理
同时也要满足器件本身的传输规则

  PCF8591的设备地址包括固定部分和可编程部分。
  可编程部分需要根据硬件引脚A0、A1和A2来设置。
  设备地址的最后一位用于设置数据传输的方向,即读/写位。
  由A0 A1 A2 的选择我们可以知道在进行IIC通信时可以同时
  挂载8个PCF8591设备而设备的固定部位为1001是一致的所以
  在进行不同设备选择时我们只需要改变A0 A1 A2 的值就可以
  进行我们要想的设备工作。
2.4 板子上PCF8591原理图与控制寄存器

在这里插入图片描述

在这里插入图片描述

在我们使用的平台上面A0 A1 A2默认都是接的地 而且只挂载了一个设备所以
进行写操作时为1001 0000 ---0x90
进行读操作时为1001 0001 ---0x91


光敏传感器Rb1接到AIN1,通道1;控制寄存器应写入:0x01。
电位器Rb2接到AIN3,通道3;控制寄存器应写入:0x03。


AD转换流程
 1--发送写设备地址,选择IIC总线上的PCF8591器件。
 2--发送控制字节,选择模拟量输入模式和通道。
 3--发送读设备地址,选择IIC总线上的PCF8591器件。
 4--读取PCF8591中目标通道的数据。

三、代码展示

#include "reg52.h"
#include "iic.h"

/********************************************
Date:2022-1-15
Author:小殷同学
Learn From:B 站小蜜蜂老师
*********************************************/

sbit S4 = P3^3;
unsigned char Rd1 = 0; //光敏电阻AIN1
unsigned char Rd2 = 0;	//可调电阻AIN3
unsigned char status = 0; //按键状态记录

//共阳数目管段码
//0-f  0xbf代表 -
unsigned char code SMG_Duan[] = {0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,
															   0x80,0x90,0x88,0x83,0xC6,0xA1,0x86,0x8E,0xbf};


//---------------------------------简单延时函数-------------------------
void Delay(unsigned int t)
{
 	while(t--);
}

//-------------------------------74HC138初始化---------------------------
void Init_74HC138(unsigned char n)
{
 	switch(n)
	{
	 	case 4:P2 = P2| 0x1f; P2 = 0x80; break;
		case 5:P2 = P2| 0x1f; P2 = 0xa0; break;
		case 6:P2 = P2| 0x1f; P2 = 0xc0; break;
		case 7:P2 = P2| 0x1f; P2 = 0xe0; break;
		case 0:P2 = P2| 0X1f; P2 = 0x00; break; //所有锁存器都不选择
	}
}

//----------------------------------系统初始化---------------------------
void InitSystem(void)
{
 	 Init_74HC138(5);
	 P0 = 0x00;			 //关闭继电器与蜂鸣器
	 Init_74HC138(4);
	 P0 = 0xff;   //关闭led
}



//---------------------------------数码管安位显示--------------------------
void SMG_DisplayBit(unsigned char pos ,unsigned char dat)
{
 		Init_74HC138(6);
		P0 = 0x01 << pos ;//位选
		Init_74HC138(7);
		P0 = dat;        //段码
}


//-------------------------------关闭所有数码管----------------------
void SMG_CLOSEALL(unsigned char dat)
{
	 Init_74HC138(6);
	 P0 = 0xff; //选中所有数码管
	 Init_74HC138(7);
	 P0 = dat; //关闭
}

//---------------------------------数码管AD显示----------------------
void SMG_Display_ADC(unsigned char channel,unsigned char dat)
{
	SMG_DisplayBit(0,SMG_Duan[16]);
	Delay(200);
	SMG_DisplayBit(1,SMG_Duan[channel]);
	Delay(200);
	SMG_DisplayBit(2,SMG_Duan[16]);
	Delay(200);
	SMG_DisplayBit(3,0xff);
	Delay(200);
	SMG_DisplayBit(4,0xff);
	Delay(200);
	SMG_DisplayBit(5,SMG_Duan[dat/100]);
	Delay(200);
	SMG_DisplayBit(6,SMG_Duan[dat/10%10]);
	Delay(200);
	SMG_DisplayBit(7,SMG_Duan[dat%10]);
	Delay(200);
	SMG_CLOSEALL(0xff);
	Delay(200);
}

//----------------------------读取光敏AD-----------------------------------

//PCF8591的设备的读操作地址为:0x91;而写操作地址则为:0x90
//光敏传感器接到AIN1,通道1;控制寄存器应写入:0x01。
//电位器Rb2接到AIN3,通道3;控制寄存器应写入:0x03。
void Read_Rd1_Data(void)
{
		 IIC_Start();					//IIC总线起始信号
		 IIC_SendByte(0x90);	//发送PCF8591设备地址 写操作
		 IIC_WaitAck();			  //等待回应
		 IIC_SendByte(0x01);  //发送AIN模拟通道号	 AIN3
		 IIC_WaitAck();				//等待回应
		 IIC_Stop();					//IIC总线停止信号

		 SMG_Display_ADC(1,Rd1);

		 IIC_Start();						//起始信号
		 IIC_SendByte(0x91);	  //发送PCF8591设备地址 读操作
		 IIC_WaitAck();					//等待回应
		 Rd1 = IIC_RecByte();		//读取数据
		 IIC_SendAck(0);				//发送应答信号
		 IIC_Stop();						//IIC总线停信号

		 SMG_Display_ADC(1,Rd1);
}

//-----------------------------读取滑动电阻AD-----------------------------
void Read_Rd2_Data(void)
{
		IIC_Start();	        //IIC总线起始信号
		IIC_SendByte(0x90);	  //发送PCF8591设备地址 写操作
		IIC_WaitAck();			  //等待回应
		IIC_SendByte(0x03);	  //发送AIN模拟通道号	 AIN3
		IIC_WaitAck();				 //等待回应
		IIC_Stop();						 //IIC总线停止信号

		SMG_Display_ADC(3,Rd2);

	    IIC_Start();//起始信号
		IIC_SendByte(0x91);	  //发送PCF8591设备地址 读操作
		IIC_WaitAck();			  //等待回应
		Rd2 = IIC_RecByte();  //读取数据
		IIC_SendAck(0);				//发送应答信号
		IIC_Stop();	  				//IIC总线停信号

		SMG_Display_ADC(1,Rd2);
}

//----------------------------------按键切换控制----------------------------
void Key_Tackle(void)
{
	 if(S4 == 0)
	 {
			Delay(20);
			if(S4 == 0)
			{
			 	if(status == 0)
				{
				 	status = 1;
					while(S4 == 0)
					{
						 SMG_Display_ADC(1,Rd1);
					}	
				}

				else if(status == 1)
				{
				 	status = 0;
					while(S4 == 0)
					{
						 SMG_Display_ADC(1,Rd2);
					}
				 	
				}
			}	
	 }
}

void main(void)
{
	InitSystem();  //初始化系统
	Read_Rd1_Data(); //上电默认进行光敏数据采集
	while(1)
	{
		Key_Tackle();
		if(status == 0)
		{
		 	 Read_Rd1_Data();
		}
		else
		{
		 	 Read_Rd2_Data();
		}
	}
}

四、总结

通过该节PCF8591 AD转换的进阶练习 一方面将前面所学的知识进行了巩固 另一方面也对IIC通信的时序流程原理和PCF8591该芯片功能使用原理等等进行了熟悉 也掌握了如何基本该平台去驱动我们的硬件 实现我们想要的功能

路漫漫其修远兮 加油

  • 3
    点赞
  • 28
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小殷学长

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值