蓝桥杯单片机快速开发笔记——PCF8591的DAC模拟电压输出

一、原理分析

        PCF8591电压信号探测器:http://t.csdnimg.cn/R38tC

        IIC原理:http://t.csdnimg.cn/v4dSv

        IIC指令:http://t.csdnimg.cn/RY6yi

       HC573/HC138:http://t.csdnimg.cn/W0a0U

        数码管:http://t.csdnimg.cn/kfm9Y

        独立键盘:http://t.csdnimg.cn/YPInc

二、思维导通

6ae47acad66c4bb5a0d3b71bb48966cb.png

三、示例例程

        1、题目要求:

        在新建的工程中,采用I/O模式编写代码,针对CT107D单片机综合训练平台,实现以下功能:

  1. 移植IIC总线的底层驱动代码文件至工程中。
  2. 配置J5为BTN模式,将S4设置为独立按键,并选择DAC的输出模式。
  3. 数码管显示格式如下:最左侧3位显示当前的DAC输出模式,最右侧3位显示当前DAC的输出电压,电压单位为V,保留2位小数。
  4. DAC的输出模式包括三种:
    • 模式1:显示“- -”,DAC输出固定电压为2.00V。
    • 模式2:显示“-2-”,DAC输出固定电压为4.00V。
    • 模式3:显示“-3-”,右侧显示PCF8591芯片AIN3通道的实时输入电压,并将该电压作为DAC的输出参数,实现DAC输出电压与PCF8591芯片AIN3通道输入电压同步变化。通过调节Rb2可调电阻,可改变DAC的输出电压。
  5. 系统上电后,默认工作在模式1。在模式1中按下S4按键,切换至模式2;在模式2中按下S4按键,切换至模式3;在模式3中按下S4按键,重新回到模式1,如此循环。
  6. 使用万用表测量J3的19和20引脚,即DAC输出电压,确保万用表显示的数值与数码管右侧显示的电压基本一致。

        2.示例代码

        

#include "stc15.h"
#include "iic.h"

#define TSMG 500
#define TKEY 200

sbit s4 = P3^3;

unsigned char stat = 1;     //模式
unsigned int smg_v = 200;   //数码管显示电压
unsigned int ain3 = 0;      //通道3数值

void delay_smg(unsigned int t)
{
	while(t--);
}

void delay_key(unsigned int t)
{
	while(t--);
}

code unsigned char Seg_Table[] = 
{
	0xc0, //0
	0xf9, //1
	0xa4, //2
	0xb0, //3
	0x99, //4
	0x92, //5
	0x82, //6
	0xf8, //7
	0x80, //8
	0x90, //9
	0x88, //A
	0x83, //b
	0xc6, //C
	0xa1, //d
	0x86, //E
	0x8e //F
};

code unsigned char Seg_DotTable[] = 
{
	0x40, //0
	0x79, //1
	0x24, //2
	0x30, //3
	0x19, //4
	0x12, //5
	0x02, //6
	0x78, //7
	0x00, //8
	0x10  //9
};
//控制所有数码管
void smg_all(unsigned dat)
{
	hc573(6,0xff);
	hc573(7,dat);
}

//单个数码管设置
void smg_bit(unsigned char channel, unsigned dat)
{
	hc573(6,0x01 << channel);
	hc573(7,dat);
	delay_smg(TSMG);
	hc573(6,0x01 << channel);
	hc573(7,0xff);
}
//数码管显示函数
void smg_dispay()
{
	smg_bit(0, 0xbf);
	smg_bit(1, Seg_Table[stat]);
	smg_bit(2, 0xbf);
	
	smg_bit(5, Seg_DotTable[smg_v / 100]);
	smg_bit(6, Seg_Table[(smg_v / 10) % 10]);
	smg_bit(7, Seg_Table[smg_v % 10]);
}

//读取AIN3实时输入电压
void read_pcf8591_ain3()
{
	unsigned int temp = 0;
	float v = 0;
	
	I2CStart();
	I2CSendByte(0x90);
	I2CWaitAck();
	I2CSendByte(0x43);	//输出DAC,转换AIN3
	I2CWaitAck();
	I2CStop();
	smg_dispay();
	
	I2CStart();
	I2CSendByte(0x91);
	I2CWaitAck();
	temp = I2CReceiveByte();
	I2CSendAck(1);
	I2CStop();
	
	v = temp * (5.0 / 255);
	ain3 = v * 100;
}
//输出电压函数
void out_pcf8591(unsigned int dat)
{
	I2CStart();
	I2CSendByte(0x90);
	I2CWaitAck();
	I2CSendByte(0x43);	//输出DAC,转换AIN3
	I2CWaitAck();
	I2CSendByte(dat);
	I2CWaitAck();
	I2CStop();
}

//系统初始化函数
void init_sys()
{
	hc573(5, 0x00);  //关闭蜂鸣器继电器
	hc573(4, 0xff);  //熄灭LED
	smg_all(0xff);   //熄灭所有数码管
	out_pcf8591(102);	//输出2.00V
	
}

//键盘扫描函数
void scan_key()
{
	if(s4 == 0)
	{
		delay_key(TKEY);
		if(s4 == 0)
		{
			switch(stat)
			{
				case 1:
					//当处于模式2时
					stat++;
					out_pcf8591(204);  //输出4V电压
					smg_v = 400;
				break;
				
				case 2:
					stat++;
				break;
				
				case 3:
					//当处于模式3时
					stat = 1;
					out_pcf8591(102);  //输出2V电压
					smg_v = 200;
				break;
			}
			
			
			while(s4 == 0)
			{
				smg_dispay();
			}
		}
	}
}


void main()
{
	init_sys();  	
	
	while(1)
	{
		if(stat == 3)  //当处于模式3时
		{
			read_pcf8591_ain3();
			smg_v = ain3;
			out_pcf8591(ain3);
		}
		
	  scan_key();
	  smg_dispay();
	}
}

 

 

  • 4
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

木木不迷茫(˵¯͒¯͒˵)

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

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

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

打赏作者

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

抵扣说明:

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

余额充值