【51单片机入门记录】A/D、D/A转换器PCF859应用

news2024/11/17 20:36:16

目录

一、IIC初始化代码

二、开发板电路图

三、PCF8591读/写字节操作流程及相关函数

(1)PCF8591(AD)读操作流程及代码

(2)PCF8591(AD)写操作流程及代码

四、应用示例-显示电压值


一、IIC初始化代码

  1. 加载“iic.c文件”,主函数中添加iic.h头文件
  2. 调节软件延迟时长(全部扩大十倍即可)
  3. 编写PCF8591读写函数,并且在头文件中定义
  4. 编写用户用能函数

二、开发板电路图

(图源第十五届蓝桥杯电子赛资源包)

  • 根据图以及前面所学的EEPROM存储器的位置,可知IIC总线上有两个设备,一个是PCF85191另一个是AT24C02 EEPROM存储器。
  • AIN1(光敏电阻线路)、AIN3(活动变阻器、电压采集)

三、PCF8591读/写字节操作流程及相关函数

(1)PCF8591(AD)读操作流程及代码

  1. 主控器发出起始信号
  2. 主控器发出寻址字节(写:0X90)
  3. 被控器做出应答后
  4. 主控器发出控制字节(写:)
  5. 被控器做出应答后
  6. 主控器发出停止信号
  7. 主控器发出起始信号
  8. 主控器发出寻址字节(读:0x91)
  9. 被控器做出应答后
  10. 主控器从被控器读出数据字节,主控器发出应答
  11. 主控器发出停止信号
unsigned char AD_read(unsigned char add)
{
	unsigned char dat;
	
	I2CStart();
	I2CSendByte(0X90);
	I2CWaitAck();
	I2CSendByte(add);
	I2CWaitAck();
	I2CStop();
	
	I2CStart();
	I2CSendByte(0X91);
	I2CWaitAck();
	dat=I2CReceiveByte();
	I2CSendAck(1);
	I2CStop();
	
	return dat;
}
	

(2)PCF8591(AD)写操作流程及代码

  1. 主控器发出起始信号
  2. 主控器发出寻址字节(写:0X90)
  3. 被控器做出应答后
  4. 主控器发出控制字节(写)
  5. 被控器做出应答后
  6. 主控器发出DA输出数据字节(写)
  7. 被控器做出应答后
  8. 主控器发出停止信号
void AD_write(unsigned char dat)
{
	I2CStart();
	I2CSendByte(0X90);
	I2CWaitAck();
	I2CSendByte(0X40);
	I2CWaitAck();
	I2CSendByte(dat);
	I2CWaitAck();
	I2CStop();
	
}

四、应用示例-显示电压值

//iic.c
#include <STC15F2K60S2.H>
#include<intrins.h>
#define DELAY_TIME	50

//总线引脚定义
sbit sda = P2^1; 
sbit scl = P2^0; 

//
static void I2C_Delay(unsigned char n)
{
    do
    {
        _nop_();_nop_();_nop_();_nop_();_nop_();
        _nop_();_nop_();_nop_();_nop_();_nop_();
        _nop_();_nop_();_nop_();_nop_();_nop_();		
    }
    while(n--);      	
}

//
void I2CStart(void)
{
    sda = 1;
    scl = 1;
	I2C_Delay(DELAY_TIME);
    sda = 0;
	I2C_Delay(DELAY_TIME);
    scl = 0;    
}

//
void I2CStop(void)
{
    sda = 0;
    scl = 1;
	I2C_Delay(DELAY_TIME);
    sda = 1;
	I2C_Delay(DELAY_TIME);
}

//
void I2CSendByte(unsigned char byt)
{
    unsigned char i;
	
    for(i=0; i<8; i++){
        scl = 0;
		I2C_Delay(DELAY_TIME);
        if(byt & 0x80){
            sda = 1;
        }
        else{
            sda = 0;
        }
		I2C_Delay(DELAY_TIME);
        scl = 1;
        byt <<= 1;
		I2C_Delay(DELAY_TIME);
    }
	
    scl = 0;  
}

//
unsigned char I2CReceiveByte(void)
{
	unsigned char da;
	unsigned char i;
	for(i=0;i<8;i++){   
		scl = 1;
		I2C_Delay(DELAY_TIME);
		da <<= 1;
		if(sda) 
			da |= 0x01;
		scl = 0;
		I2C_Delay(DELAY_TIME);
	}
	return da;    
}

//
unsigned char I2CWaitAck(void)
{
	unsigned char ackbit;
	
    scl = 1;
	I2C_Delay(DELAY_TIME);
    ackbit = sda; 
    scl = 0;
	I2C_Delay(DELAY_TIME);
	
	return ackbit;
}

//
void I2CSendAck(unsigned char ackbit)
{
    scl = 0;
    sda = ackbit; 
	I2C_Delay(DELAY_TIME);
    scl = 1;
	I2C_Delay(DELAY_TIME);
    scl = 0; 
	sda = 1;
	I2C_Delay(DELAY_TIME);
}

unsigned char AD_read(unsigned char add)
{
	unsigned char dat;
	
	I2CStart();
	I2CSendByte(0X90);
	I2CWaitAck();
	I2CSendByte(add);
	I2CWaitAck();
	I2CStop();
	
	I2CStart();
	I2CSendByte(0X91);
	I2CWaitAck();
	dat=I2CReceiveByte();
	I2CSendAck(1);
	I2CStop();
	
	return dat;
	
}
void AD_write(unsigned char dat)
{
	I2CStart();
	I2CSendByte(0X90);
	I2CWaitAck();
	I2CSendByte(0X40);
	I2CWaitAck();
	I2CSendByte(dat);
	I2CWaitAck();
	I2CStop();
	
}
//IIC.h
#ifndef _IIC_H
#define _IIC_H
//
static void I2C_Delay(unsigned char n);

//
void I2CStart(void);

//
void I2CStop(void);

//
void I2CSendByte(unsigned char byt);

//
unsigned char I2CReceiveByte(void);

//
unsigned char I2CWaitAck(void);

//
void I2CSendAck(unsigned char ackbit);
//
unsigned char AD_read(unsigned char add);
void AD_write(unsigned char dat);


#endif
//main.c
#include <STC15F2K60S2.H>
#include<intrins.h>
#include<IIC.h>

#define uchar unsigned char
#define uint unsigned int
	
unsigned char LED_Bit=0XFF;
unsigned char Actuator_Bit=0X00;

#define LEDx_ON(n) 	{ LED_Bit&=_crol_(0XFE,n-1); P0=LED_Bit; P2|=0X80;	P2&=0X9F;	P2&=0X1F;}
#define LEDx_OFF(n) { LED_Bit|=_crol_(0X01,n-1); P0=LED_Bit; P2|=0X80;	P2&=0X9F;	P2&=0X1F;}

#define Buzzer_ON 	Actuator_Bit|=0x40; P0=Actuator_Bit;	P2|=0XA0;	P2&=0XBF; P2&=0X1F;		
#define Buzzer_OFF 	Actuator_Bit&=0XBF; P0=Actuator_Bit;	P2|=0XA0;	P2&=0XBF;	P2&=0X1F;
#define Relay_ON 		Actuator_Bit|=0x10; P0=Actuator_Bit;	P2|=0XA0;	P2&=0XBF;	P2&=0X1F;
#define Relay_OFF 	Actuator_Bit&=0XEF; P0=Actuator_Bit;	P2|=0XA0;	P2&=0XBF;	P2&=0X1F;

unsigned char code tab[]=	{0XC0,0XF9,0XA4,0XB0,0X99,0X92,0X82,0XF8,0X80,0X90,\
													 0X40,0X79,0X24,0X30,0X19,0X12,0X02,0X78,0X00,0X10,\
													 0XBF,0XFF};
unsigned char KEY_Value = 0 ;
unsigned char DigCom=0;
unsigned char DigBuf[8] = {10,10,10,10,10,10,10,10};

unsigned char LED = 1 ;
unsigned int LED_tt =0;
bit LED_Ref = 0 ;

unsigned int SEG_tt =0;		//定义一个数码管计数时间标识位
bit SEG_Ref = 0 ;					//定义一个数码管刷新标识位
bit SEG_Run = 0 ;					//定义一个控制数码管运行标识位
unsigned int Num = 999 ;

unsigned char Open;

unsigned char EEPROM_Write[8] = {2,3,4,5,6,7,8,9};
unsigned char EEPROM_Read[8] = {0,0,0,0,0,0,0,0};

unsigned int AD_VALUE=0;
unsigned int AD_tt =0;
bit AD_Ref =0;


void ALL_Init(void);
void Delay_MS(unsigned int MS);
void KeyScan(void);
void ArrKeyScan(void);
void Timer0Init(void);		//1毫秒@11.0592MHz

void main(void)
{
	ALL_Init();
	Timer0Init();
	EA=1;ET0=1;
	
	
	while(1)
	{
		if(AD_Ref == 1)
		{
			AD_Ref = 0 ;
			AD_VALUE = AD_read(0X03);
			AD_write(AD_VALUE);
			
			AD_VALUE = AD_VALUE * 1.96;
			DigBuf[2]=21;DigBuf[3]=21;DigBuf[4]=21;
			DigBuf[5]=AD_VALUE/100 + 10; DigBuf[6]=AD_VALUE%100/10;
			DigBuf[7]=AD_VALUE%10;				
		}
		
		
		KeyScan();
		if(KEY_Value==7){KEY_Value=0;SEG_Run = 1 ;}
		if(KEY_Value==6){KEY_Value=0;SEG_Run = 0 ;}
		if(KEY_Value==5){KEY_Value=0;LEDx_ON(1);Buzzer_ON;}
		if(KEY_Value==4){KEY_Value=0;LEDx_OFF(1);Buzzer_OFF;}	
	}
}

void KeyScan(void)
{
	if(P30==0)
	{
		Delay_MS(10);
		if(P30==0)KEY_Value = 7 ;		
		while(!P30);
	}
	else if(P31==0)
	{
		Delay_MS(10);
		if(P31==0)KEY_Value = 6 ;		
		while(!P31);
	}	
	else if(P32==0)
	{
		Delay_MS(10);
		if(P32==0)KEY_Value = 5 ;		
		while(!P32);
	}	
	else if(P33==0)
	{
		Delay_MS(10);
		if(P33==0)KEY_Value = 4 ;		
		while(!P33);
	}	
}

void Timer0(void) interrupt 1
{
	P0=0X00;
	P2|=0XC0;  // P2=P2|0XC0;   XXXX XXXX | 1100 0000 = 11XX XXXX
	P2&=0XDF;	 // P2=P2&0XDF;   11XX XXXX & 1101 1111 = 110X XXXX	
	P2&=0X1F;		//关闭所有的74HC573锁存器	
	
	P0=tab[DigBuf[DigCom]];	
	P2|=0XE0;			//	P2=P2|0XE0;   XXXX XXXX | 1110 0000 = 111X XXXX
	P2&=0XFF;		 	// P2=P2&0XDF;   11XX XXXX & 1101 1111 = 110X XXXX	
	P2&=0X1F;			//关闭所有的74HC573锁存器
	
	P0=(0X01<<DigCom); 	//然后选中第一个数码管
	P2|=0XC0;  // P2=P2|0XC0;   XXXX XXXX | 1100 0000 = 11XX XXXX
	P2&=0XDF;	 // P2=P2&0XDF;   11XX XXXX & 1101 1111 = 110X XXXX	
	P2&=0X1F;		//关闭所有的74HC573锁存器

	if(++DigCom == 8)DigCom = 0 ;
	
	LED_tt++;
	if(LED_tt == 999) {LED_tt = 0 ; LED_Ref = 1 ;}

	if(++SEG_tt==1000){SEG_tt=0;SEG_Ref=1;}
	
	if(++AD_tt==500){AD_tt=0;AD_Ref=1;}
//	XXX_tt++;
//	if(++XXX_tt==NNN){XXX_tt=0;XXX_Ref=1;}	
}

void Timer0Init(void)		//1毫秒@11.0592MHz
{
	AUXR |= 0x80;		//定时器时钟1T模式
	TMOD &= 0xF0;		//设置定时器模式
	TL0 = 0xCD;		//设置定时初始值
	TH0 = 0xD4;		//设置定时初始值
	TF0 = 0;		//清除TF0标志
	TR0 = 1;		//定时器0开始计时
}



void Delay_MS(unsigned int MS)
{
	unsigned i,j;
	for(i=0;i<MS;i++)
		for(j=853;j>0;j--); //STC15单片机设置为853; STC8H单片机修改为1109;STC32G单片机修改为427;
}

void ALL_Init(void)
{
	P0 =0X00;		//先设置关闭蜂鸣器继电器的P0输出值(全关)
	P2|=0XA0;		// 将P27 P25 设置为1 其他位保持不变
	P2&=0XBF; 	// 将P26设置为0 其他位保持不变
	P2&=0X1F;		//关闭所有的74HC573锁存器

	P0 =0XFF;		//先设置关闭所有的LED的P0输出值(全关)
	P2|=0X80;		// 将P27设置为1 其他位保持不变
	P2&=0X9F;		// 将P26 P25设置为0 其他位保持不变
	P2&=0X1F;		//关闭所有的74HC573锁存器
	
	P0 =0X00;		//先设置选择数码管位选的P0输出值(全不选)
	P2|=0XC0;		// 将P27 P26 设置为1 其他位保持不变
	P2&=0XDF;		// 将P26设置为0 其他位保持不变
	P2&=0X1F;		//关闭所有的74HC573锁存器
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1571264.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

c# wpf template itemtemplate+ListBox

1.概要 2.代码 <Window x:Class"WpfApp2.Window7"xmlns"http://schemas.microsoft.com/winfx/2006/xaml/presentation"xmlns:x"http://schemas.microsoft.com/winfx/2006/xaml"xmlns:d"http://schemas.microsoft.com/expression/blend/…

Nuxt 项目的创建

中文文档&#xff1a;https://nuxt.com.cn/docs/getting-started/installation#%E6%96%B0%E9%A1%B9%E7%9B%AE Nuxt 项目创建的先决条件&#xff1a; Node.js 版本 18.0.0 及以上文本编辑器&#xff1a;VS Code Volar 插件 或 Webstorm 执行如下命令&#xff0c;创建 Nuxt 项目…

【MATLAB】GA_BP神经网络时序预测算法

有意向获取代码&#xff0c;请转文末观看代码获取方式~ 1 基本定义 GA_BP神经网络时序预测算法是一种结合了遗传算法(GA)和反向传播(BP)神经网络的时序预测方法。它利用了遗传算法的全局搜索和优化能力&#xff0c;以及BP神经网络的学习和逼近能力&#xff0c;可以更有效地预…

[java]网络编程

网络编程概述 计算机网络&#xff1a; 把分布在不同地理区域的具有独立功能的计算机,通过通信设备与线路连接起来&#xff0c;由功能完善的软件实现资源共享和信息传递的系统。 Java是 Internet 上的语言&#xff0c;它从语言级上提供了对网络应用程序的支持&#xff0c;程序…

【MySQL】聚合函数和分组聚合

&#x1f466;个人主页&#xff1a;Weraphael ✍&#x1f3fb;作者简介&#xff1a;目前学习计网、mysql和算法 ✈️专栏&#xff1a;MySQL学习 &#x1f40b; 希望大家多多支持&#xff0c;咱一起进步&#xff01;&#x1f601; 如果文章对你有帮助的话 欢迎 评论&#x1f4ac…

渗透测试靶机----Raven-1

渗透测试靶机----Raven-1 开启靶机&#xff0c;登录窗&#xff0c;平平无奇 开扫&#xff1a; 先看看ip 这里发现192.168.217.166 发现相关服务端口&#xff0c;这里看到80&#xff0c;还是老样子&#xff0c;先80入手打开发现一个熟悉的站点&#xff1a; 这里可以使用漏扫工具…

解密项目管理工具数据安全:防火防盗,保密有招

相关数据显示&#xff0c;2021年中国数字经济规模总量达到45.5万亿元&#xff0c;占到国内GDP总量的39.8%。数字经济已经渗入我们工作生活的方方面面&#xff0c;项目管理工具就是其中之一&#xff0c;在数据安全备受重视的今天如何保证项目管理工具的数据安全性&#xff1f;Zo…

C-开发 visual Studio扩展插件介绍-格式化插件Xaml Styler、CSharpier介绍(扩展插件安装方法)

C#开发 visual Studio扩展插件介绍 扩展插件安装方法Xaml StylerCSharpier 提高C#开发效率常用的插件 扩展插件安装方法 菜单栏点击“扩展”→“管理扩展”。 打开扩展页面 右上角搜索需要安装的插件&#xff0c;然后点击下载 安装完成后&#xff0c;根据提示关闭VS进行安…

MPEG-1 详解

MPEG-1 详解 MPEG-1 详解特点MPEG-1 中的运动补偿与 B 帧的引入MPEG-1 vs H.261MPEG-1 视频数据流的结构MPEG-1 视频压缩模式MPEG-1 视频解码框图MPEG-1 音频编码模式MPEG-1 audio layer 1MPEG-1 audio layer 2MPEG-1 audio layer 3 MPEG-1 音频编码框图MPEG-1 音频解码框图参考…

大数据实验四-MapReduce编程实践

一&#xff0e;实验内容 MapReduce编程实践&#xff1a; 使用MapReduce实现多个文本文件中WordCount词频统计功能&#xff0c;实验编写Map处理逻辑、编写Reduce处理逻辑、编写main方法。 二&#xff0e;实验目的 1、通过实验掌握基本的MapReduce编程方法。 2、实现统计HDF…

使用阿里云试用Elasticsearch学习:1.2 基础入门——数据输入和输出

什么是文档? 在大多数应用中&#xff0c;多数实体或对象可以被序列化为包含键值对的 JSON 对象。 一个 键 可以是一个字段或字段的名称&#xff0c;一个 值 可以是一个字符串&#xff0c;一个数字&#xff0c;一个布尔值&#xff0c; 另一个对象&#xff0c;一些数组值&#…

Linux+HA高可用24X7的安全保证

一&#xff0e; 介绍作为服务器&#xff0c;需要提供一定的24X7的安全保证&#xff0c;这样可以防止关键节点的宕机引起系统的全面崩溃。利用OpenSource开源软件&#xff0c;完成系统的高可靠双机热备方案。基于linux的 HA软件可靠稳定&#xff0c;比使用商业版本的HA软件降低成…

中国智慧城管哪家做的好?

智慧城市管理综合执法系统建立全市统一的法律法规、裁量基准、执法事项、执法文书和基础信息库&#xff0c;实现从获取线索、立案、调查、处理到结案全过程的信息化和文书制作的智能化。全面支持移动执法办案&#xff0c;提高执法效率。 技术架构&#xff1a; 微服务javasprin…

arm开发板移植工具mkfs.ext4

文章目录 一、前言二、手动安装e2fsprogs1、下载源码包2、解压源码3、配置4、编译5、安装 三、移植四、验证五、总结 一、前言 在buildroot菜单中&#xff0c;可以通过勾选e2fsprogs工具来安装mkfs.ext4工具&#xff1a; Target packages -> Filesystem and flash utilit…

【Python】免费的图片/图标网站

专栏文章索引&#xff1a;Python 有问题可私聊&#xff1a;QQ&#xff1a;3375119339 这里是我收集的几个免费的图片/图标网站&#xff1a; iconfont-阿里巴巴矢量图标库icon&#xff08;.ico&#xff09;INCONFINDER&#xff08;.ico&#xff09;

力扣刷题 二叉树的迭代遍历

题干 给你二叉树的根节点 root &#xff0c;返回它节点值的 前中后序 遍历。 示例 1&#xff1a; 输入&#xff1a;root [1,null,2,3] 输出&#xff1a;[1,2,3]示例 2&#xff1a; 输入&#xff1a;root [] 输出&#xff1a;[]示例 3&#xff1a; 输入&#xff1a;root […

智慧农业新篇章:数字乡村引领农业现代化

随着信息技术的飞速发展&#xff0c;数字乡村正成为引领农业现代化的重要力量。智慧农业作为数字乡村的核心内容&#xff0c;以其高效、精准、可持续的特点&#xff0c;为农业现代化开辟了新篇章。本文将从智慧农业的内涵与特点、数字乡村在农业现代化中的引领作用、智慧农业发…

机器学习第33周周报Airformer

文章目录 week33 AirFormer摘要Abstract一、论文的前置知识1. 多头注意力机制&#xff08;MSA&#xff09;2. 具有潜变量的变分模型 二、文献阅读1. 题目2. abstract3. 问题与模型阐述3.1 问题定义3.2 模型概述3.3 跨空间MSA&#xff08;DS-MSA&#xff09;3.4 时间相关MSA&…

小程序如何设置余额充值和消费功能

小程序中设置余额充值和消费功能非常重要的&#xff0c;通过让客户在小程序中进行余额充值&#xff0c;不仅可以提高用户粘性&#xff0c;还可以促进消费&#xff0c;增加用户忠诚度。以下是如何在小程序中设置余额充值和消费功能的步骤&#xff1a; 1. **设计充值入口**&…