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

目录

一、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 intunsigned 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.0592MHzvoid 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 XXXXP2&=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 XXXXP2&=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 XXXXP2&=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.mzph.cn/news/794381.shtml

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

相关文章

论文笔记:UNDERSTANDING PROMPT ENGINEERINGMAY NOT REQUIRE RETHINKING GENERALIZATION

ICLR 2024 reviewer评分 6888 1 intro zero-shot prompt 在视觉-语言模型中&#xff0c;已经取得了令人印象深刻的表现 这一成功呈现出一个看似令人惊讶的观察&#xff1a;这些方法相对不太受过拟合的影响 即当一个提示被手动工程化以在给定训练集上达到低错误率时&#xff0…

学习心得1

这时我第一次更学习心得&#xff01;不足的在评论区指教。 首先先来分享一下&#xff0c;刷一维数组题目的方法。 仔细读题&#xff0c;不会做的题目先完成输入输出。不要干等着着急&#xff0c;就跳到下一题。如果使用的时oj&#xff0c;那就没有题解但是使用洛谷、LeetCood…

Prometheus+grafana监控nacos和spring-boot服务(增加自定义指标)(七)

前面记录了项目中常用的各种中间件的指标采集器的用法及搭建方式 &#xff0c; 由于所有组件写一篇幅过长&#xff0c;所以每个组件分一篇方便查看&#xff0c;前六篇链接如下 Prometheusgrafana环境搭建方法及流程两种方式(docker和源码包)(一)-CSDN博客 Prometheusgrafana…

LeetCode - 边积分最高的节点

2374. 边积分最高的节点 这是一个有向图&#xff0c;且每个节点都只有一条出边&#xff0c;指向0的边有1&#xff0c;2&#xff0c;3&#xff0c;4 10&#xff0c; 指向7的有5&#xff0c;6 11. 我们只需要一次遍历就可以解决&#xff0c;先搞一张哈希表&#xff0c;k存节点…

解决VScode中matplotlib图像中文显示问题

一、更改配置文件 参考这个文件路径找到自己Python环境下的matplotlibrc文件并用记事本打开。 用ctrl F寻找下面的这两行并将前面的#删除&#xff0c;保存并退出。 font.family: sans-serif font.serif: DejaVu Serif, Bitstream Vera Serif, Computer Modern Roman, N…

Day31|贪心算法part01:理论基础、455.分发饼干、376. 摆动序列、53. 最大子序和

理论基础 记得贪心没有规律即可&#xff01;解不出来就看题解。 455. 分发饼干 先把学生和饼干都排序&#xff08;Arrays.sort只能升序&#xff09;&#xff0c;然后都从后往前遍历&#xff0c;把最大的饼干给需求最大的孩子&#xff08;贪心&#xff09; class Solution {…

计算机提示msvcp120.dll怎么解决,7种详细有效修复方法分享

在Windows操作系统的庞大舞台上&#xff0c;每一个组件都扮演着其独特的角色。在这些不为人知的角色中&#xff0c;有一个名为msvcp120.dll的文件&#xff0c;它是Visual C运行时库的一部分&#xff0c;对于确保许多应用程序的正常运行至关重要。本文将深入探讨msvcp120.dll文件…

【项目实战】——商品管理的制作完整代码

&#x1f468;‍&#x1f4bb;个人主页&#xff1a;开发者-曼亿点 &#x1f468;‍&#x1f4bb; hallo 欢迎 点赞&#x1f44d; 收藏⭐ 留言&#x1f4dd; 加关注✅! &#x1f468;‍&#x1f4bb; 本文由 曼亿点 原创 &#x1f468;‍&#x1f4bb; 收录于专栏&#xff1a…

逐步学习Go-WaitGroup【连字都懒得写了,直接Show my Code】

package waitgroup_testimport ("fmt""runtime""sync""testing""time""github.com/stretchr/testify/assert" )// 这是对Go语标准库中sync包下的WaitGroup的描述。// WaitGroup用于等待一组并发的goroutine结结束…

非关系型数据库-----------探索 Redis高可用 、持久化、性能管理

目录 一、Redis 高可用 1.1什么是高可用 1.2Redis的高可用技术 二、 Redis 持久化 2.1持久化的功能 2.2Redis 提供两种方式进行持久化 三、Redis 持久化之----------RDB 3.1触发条件 3.1.1手动触发 3.1.2自动触发 3.1.3其他自动触发机制 3.2执行流程 3.3启动时加载…

在深度学习模型中引入先验

当面对复杂问题的时候&#xff0c;在深度学习模型提取特征的过程中完全抛弃知识是非常不明智的策略。虽然有很多研究者在深度网络处理数据之前&#xff0c;利用具有某种知识的模型驱动方法对数据进行预处理&#xff0c;但是这种方法没有进行实质性地改造深度网络&#xff0c;且…

ms-前端八股文

1、暂时性死区 是指在 JavaScript 中使用 let 或 const 声明变量时&#xff0c;变量在其声明之前不能被访问或使用的特性。 var可以变量提升&#xff08;在 JavaScript 中&#xff0c;变量声明提升是指在执行代码之前&#xff0c;变量声明会被提升到作用域的顶部。&#xff0…

scRAN-seq|加权最近邻分析(1)

概述 本文[1]介绍了Seurat 5.0.0中的加权最近邻&#xff08;WNN&#xff09;分析方法&#xff0c;这是一种用于整合和分析多模态单细胞数据的无监督框架。 简介 多模态分析作为单细胞基因组学的一个新兴领域&#xff0c;它通过同时测量多种数据类型来精确描绘细胞状态&#xff…

idea的后端环境配置

首先&#xff0c;在你刚打开idea时红色箭头所指的是你进行配置的地方&#xff0c;接下来我把具体步骤说一下 1&#xff0c;直接点击箭头所指的地方就会出现如图界面&#xff0c;然后点击Tomcat server,使其展开点击第一个 第二步取消勾选&#xff0c;第三步选择bin的上一级然后…

C++ | Leetcode C++题解之第10题正则表达式匹配

题目&#xff1a; 题解&#xff1a; class Solution { public:bool isMatch(string s, string p) {int m s.size();int n p.size();auto matches [&](int i, int j) {if (i 0) {return false;}if (p[j - 1] .) {return true;}return s[i - 1] p[j - 1];};vector<…

启智社区昇腾算力快速使用 ATC

快速使用 ATC 本文将详细介绍如何借助启智社区昇腾算力 910/910B 进行模型转换&#xff0c;彻底告别开发板上模型转换各种报错的痛苦。 TODO&#xff1a; 完成数据集、模型存储教程 完成训练&模型转换教程 完成 ATC 其他功能教程 Fork 仓库 打开仓库点击右上角的派生按钮…

活动回顾丨掘金海外,探寻泛娱乐社交APP出海新风口

3月中旬,Flat Ads携手声网、XMP在广州成功举办“泛娱乐社交APP出海新风口——广州站”的主题线下沙龙活动。 多位大咖与泛娱乐社交APP赛道的行业伙伴汇聚一堂。本次活动邀请到Flat Ads 市场VP 王若策、声网娱乐视频产品负责人 陈际陶、XMP资深产品运营专家 屈俊星等多位行业大…

基于SpringBoot Vue员工管理系统

一、&#x1f4dd;功能介绍 基于SpringBoot Vue员工管理系统 角色&#xff1a;管理员、用户 管理员&#xff1a;管理员进入主页面&#xff0c;主要功能包括系统首页、个人中心、员工管理、部门管理、请假申请管理、出勤记录管理、奖惩信息管理、工资信息管理等进行操作。 员…

上位机图像处理和嵌入式模块部署(qmacvisual之plc通信)

【 声明&#xff1a;版权所有&#xff0c;欢迎转载&#xff0c;请勿用于商业用途。 联系信箱&#xff1a;feixiaoxing 163.com】 传统的非标自动化设备当中&#xff0c;plc发挥了很大的作用。这里面如何对这些电机和机构进行控制&#xff0c;大多数场景下用的就是plc设备了。目…

LeetCode 热题 100 | 贪心算法

目录 1 121. 买卖股票的最佳时机 2 55. 跳跃游戏 3 45. 跳跃游戏 II 4 763. 划分字母区间 菜鸟做题&#xff0c;语言是 C 1 121. 买卖股票的最佳时机 解题思路&#xff1a; 维护一个变量 max_pricemax_price 用于存储排在 i 天之后的股票最高价格第 i 天的最高利润 …