蓝桥杯单片机快速开发笔记——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

二、思维导通

三、示例例程

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();
	}
}
相关推荐
wuyk5556 小时前
98.C语言易混难点:字符数组与字符串指针的底层差异
c语言·开发语言·c++·stm32·嵌入式硬件·算法
峥无6 小时前
从0到1手撕红黑树:封装实现 my_map 与 my_set(SGI-STL 源码级深度解析)
开发语言·c++·笔记·算法·stl
不会代码的小猴7 小时前
3. 控件学习1
开发语言·c++·笔记·qt·算法
恒锐丰-罗生7 小时前
国产 H 桥驱动 SS6289|18V/4A 有刷电机驱动芯片性与应用分析 内置采样 + 多保护,门锁 / 机器人优选器件
驱动开发·嵌入式硬件·硬件工程
疯狂打码的少年8 小时前
【数据结构】图的存储结构:邻接矩阵与邻接表
数据结构·笔记
蒸蒸yyyyzwd9 小时前
cpp 选手准备秋招学习笔记 day10
笔记·面试·求职招聘
haerapicom10 小时前
欠定方程里藏着哪几个非零项:OMP 稀疏恢复侦探笔记
笔记
程思扬10 小时前
Android ANR实战排查:主线程SystemClock.sleep导致页面启动偶现无响应
android·笔记
zcmodeltech11 小时前
工程机械与矿山机械沙盘模型多系统协同控制系统设计:基于STM32与Modbus RTU的露天开采-井下掘进-智慧矿山全场景联动方案
数据库·stm32·单片机·嵌入式硬件·制造·多分类
zjnlswd11 小时前
C#学习笔记4
笔记·学习·c#