文章目录

  • PCF8591 应用程序

PCF8591 应用程序

PCF8591 的通信接口是 I2C,那么编程肯定是要符合这个协议的。单片机对 PCF8591 进行初始化,一共发送三个字节即可。第一个字节,和 EEPROM 类似,是器件地址字节,其中7位代表地址,1位代表读写方向。地址高4位固定是 0b1001,低三位是 A2,A1,A0,这三位我们电路上都接了 GND,因此也就是 0b000,如图所示。

发送到 PCF8591 的第二个字节将被存储在控制寄存器,用于控制 PCF8591 的功能。其中第3位和第7位是固定的0,另外6位各自有各自的作用,如下图所示,学长会逐一介绍。

控制字节的第6位是 DA 使能位,这一位置1表示 DA 输出引脚使能,会产生模拟电压输出功能。第4位和第5位可以实现把 PCF8591 的4路模拟输入配置成单端模式和差分模式,单端模式和差分模式的区别,我们在以往文章有介绍,这里大家只需要知道这两位是配置 AD 输入方式的控制位即可。

控制字节的第2位是自动增量控制位,自动增量的意思就是,比如我们一共有4个通道,当我们全部使用的时候,读完了通道0,下一次再读,会自动进入通道1进行读取,不需要我们指定下一个通道,由于 A/D 每次读到的数据,都是上一次的转换结果,所以同学们在使用自动增量功能的时候,要特别注意,当前读到的是上一个通道的值。为了保持程序的通用性,我们的代码没有使用这个功能,直接做了一个通用的程序。

控制字节的第0位和第1位就是通道选择位了,00、01、10、11代表了从0到3的一共4个通道选择。

发送给 PCF8591 的第三个字节 D/A 数据寄存器,表示 D/A 模拟输出的电压值。D/A 模拟我们一会介绍,大家知道这个字节的作用即可。我们如果仅仅使用 A/D 功能的话,就可以不发送第三个字节。

下面我们用一个程序,把 AIN0、AIN1、AIN3 测到的电压值显示在液晶上,同时大家可以转动电位器,会发现 AIN0 的值发生变化。 /Lcd1602.c 文件程序源代码**/ (此处省略,可参考之前章节的代码) /I2C.c 文件程序源代码**/

/*****************************main.c 文件程序源代码******************************/
#include <reg52.h>
bit flag300ms = 1; //300ms 定时标志
unsigned char T0RH = 0; //T0 重载值的高字节
unsigned char T0RL = 0; //T0 重载值的低字节void ConfigTimer0(unsigned int ms);
unsigned char GetADCValue(unsigned char chn);
void ValueToString(unsigned char *str, unsigned char val);
extern void I2CStart();
extern void I2CStop();
extern unsigned char I2CReadACK();
extern unsigned char I2CReadNAK();
extern bit I2CWrite(unsigned char dat);
extern void InitLcd1602();
extern void LcdShowStr(unsigned char x, unsigned char y, unsigned char *str);void main(){unsigned char val;unsigned char str[10];EA = 1; //开总中断ConfigTimer0(10); //配置 T0 定时 10msInitLcd1602(); //初始化液晶LcdShowStr(0, 0, "AIN0 AIN1 AIN3"); //显示通道指示while (1){if (flag300ms){flag300ms = 0; //显示通道 0 的电压val = GetADCValue(0); //获取 ADC 通道 0 的转换值ValueToString(str, val); //转为字符串格式的电压值LcdShowStr(0, 1, str); //显示到液晶上//显示通道 1 的电压val = GetADCValue(1);ValueToString(str, val);LcdShowStr(6, 1, str);//显示通道 3 的电压val = GetADCValue(3);ValueToString(str, val);LcdShowStr(12, 1, str);}}
}
/* 读取当前的 ADC 转换值,chn-ADC 通道号 0~3 */
unsigned char GetADCValue(unsigned char chn){unsigned char val;I2CStart();if (!I2CWrite(0x48<<1)){ //寻址 PCF8591,如未应答,则停止操作并返回 0I2CStop();return 0;}I2CWrite(0x40|chn); //写入控制字节,选择转换通道I2CStart();I2CWrite((0x48<<1)|0x01); //寻址 PCF8591,指定后续为读操作I2CReadACK(); //先空读一个字节,提供采样转换时间val = I2CReadNAK(); //读取刚刚转换完的值I2CStop();return val;
}
/* ADC 转换值转为实际电压值的字符串形式,str-字符串指针,val-AD 转换值 */
void ValueToString(unsigned char *str, unsigned char val){//电压值=转换结果*2.5V/255,式中的 25 隐含了一位十进制小数val = (val*25) / 255;str[0] = (val/10) + '0'; //整数位字符str[1] = '.'; //小数点str[2] = (val%10) + '0'; //小数位字符str[3] = 'V'; //电压单位str[4] = '\0'; //结束符
}
/* 配置并启动 T0,ms-T0 定时时间 */
void ConfigTimer0(unsigned int ms){unsigned long tmp; //临时变量tmp = 11059200 / 12; //定时器计数频率tmp = (tmp * ms) / 1000; //计算所需的计数值tmp = 65536 - tmp; //计算定时器重载值tmp = tmp + 12; //补偿中断响应延时造成的误差T0RH = (unsigned char)(tmp>>8); //定时器重载值拆分为高低字节T0RL = (unsigned char)tmp;TMOD &= 0xF0; //清零 T0 的控制位TMOD |= 0x01; //配置 T0 为模式 1TH0 = T0RH; //加载 T0 重载值TL0 = T0RL;ET0 = 1; //使能 T0 中断TR0 = 1; //启动 T0
}
/* T0 中断服务函数,执行 300ms 定时 */
void InterruptTimer0() interrupt 1{static unsigned char tmr300ms = 0;TH0 = T0RH; //重新加载重载值TL0 = T0RL;tmr300ms++;if (tmr300ms >= 30){ //定时 300mstmr300ms = 0;flag300ms = 1;}
}

细心阅读程序的同学会发现,程序在进行 A/D 读取数据的时候,共使用了两条程序去读了2个字节:I2CReadACK(); val = I2CReadNAK(); PCF8591 的转换时钟是 I2C 的 SCL,8个 SCL 周期完成一次转换,所以当前的转换结果总是在下一个字节的8个 SCL 上才能读出,因此我们这里第一条语句的作用是产生一个整体的 SCL 时钟提供给 PCF8591 进行 A/D 转换,第二次是读取当前的转换结果。如果我们只使用第二条语句的话,每次读到的都是上一次的转换结果。


【物联网毕设基础】单片机:PCF8591 应用程序相关推荐

  1. 【物联网毕设基础】单片机:PCF8591硬件接口

    文章目录 PCF8591硬件接口(电路图引脚图) PCF8591硬件接口(电路图引脚图) PCF8591 是一个单电源低功耗的8位 CMOS 数据采集器件,具有4路模拟输入,1路模拟输出和一个串行 I ...

  2. 【物联网毕设基础】单片机_嵌入式的实时性疑问解答

    1 前言 最近有一组学弟学妹问我一个问题,他们做的飞控系统,实时性总是达不到标准,来问我是怎么回事. 这涉及到了单片机/嵌入式系统实时性的问题,学长在这做一个系统性的解答. 2 单片机和嵌入式 说实话 ...

  3. 【物联网毕设基础】单片机:RS485 通信与 Modbus 协议

    文章目录 RS485 通信与 Modbus 协议 单片机 RS485 通信接口.控制线.原理图及程序实例 RS485 通信与 Modbus 协议 在工业控制.电力通讯.智能仪表等领域,通常情况下是采用 ...

  4. 【物联网毕设基础】单片机:NEC 协议红外遥控器

    文章目录 NEC 协议红外遥控器 NEC 协议红外遥控器 家电遥控器通信距离往往要求不高,而红外的成本比其它无线设备要低的多,所以家电遥控器应用中红外始终占据着一席之地.遥控器的基带通信协议很多,大概 ...

  5. 物联网毕设 51单片机题目项目汇总 - 100例

    文章目录 1前言 2 STM32 毕设课题 3 如何选题 3.1 不要给自己挖坑 3.2 难度把控 3.3 如何命名题目 1前言

  6. 物联网毕设选题 - 单片机智能远程宠物喂养系统(物联网 esp8266 stm32)

    文章目录 0 前言 1 简介 2 主要器件 3 实现效果 4 设计原理 4.1 硬件部分 4.2 模块介绍 DHT11温湿度传感器 ESP-01S WIFI模块 光照传感器 4.3 软件设计 5 部分 ...

  7. 01-STM32+BC26丨260Y远程升级篇(自建物联网平台)-基础知识-STM32如何实现的升级程序

    说明 这节提供给用户一份实现更新STM32的程序(兼容STM32f103全系列) 主要说明STM32是如何实现的升级程序.后面的章节都是在这节的基础上进行优化. 该节源码开源: https://git ...

  8. 【嵌入式基础小知识】详解单片机中的程序和变量是如何分布的以及一些注意事项

    "我固然不是了不起的跑步者,而是处于极为平凡的--毋宁说是凡庸的--水准.然而这个问题根本不重要.我超越了昨天的自己,哪怕只是那么一丁点儿,才更为重要.在长跑中,如果说有什么必须战胜的对手, ...

  9. 单片机工程师是程序员吗?真实的月薪到底有多少?

    从业这么多年,我也一直在纠结一个概念,我做的单片机软件开发是否属于IT行业? 大家都知道IT这个概念,但很少人找到单片机. 一.单片机工程师是程序员吗? 那从我的认知来说,我觉得"算是&qu ...

  10. 物联网毕设 -- ESP32-CAN加摄像头传输图像,STM32驱动小车自动避障图像采集并显示到Android端

    前言 小车分为两种模式,自动模式以及手动模式,有小车下位机通过按键可以进行模式的切换,自动模式有三个超声波避障,手动模式可以通过APP连接到小车WIFI进行手动控制,并且会有一个ESP32的图像采集回 ...

最新文章

  1. enyo官方开发入门教程翻译一Controls之Buttons
  2. 【选型】消息中间件选型
  3. PU learning学习笔记
  4. 连接mysql数据库时提示2003-can t connect to MySQL server on ip(10060)的解决办法
  5. 使用 Swift 在 iOS 10 中集成 Siri —— SiriKit 教程
  6. Python+flask+flask-email发送带附件的电子邮件
  7. 百度定位安卓6.0权限问题
  8. ❤️《集成SSM框架—图书系统》Mybatis+Spring+SpirngMVC
  9. 现在论文用手写还是用计算机写,毕业论文计算机手写数字识别技术完整版.docx...
  10. Perl命令行应用介绍
  11. 数字图像处理复习记录(一)图像平滑、图像锐化、间隔检测
  12. 漫网漫画APP源码包含后台完整版
  13. 单片机学习日记- Day12
  14. 分享一个可以让你在朋友圈赚钱的小工具
  15. python实验总结与分析_【利用python进行数据分析】利用初中物理实验 培养学生发散思维...
  16. react实现路由跳转拦截功能(导航守卫)
  17. [databinding] ... ... conflicts with another tag that has the same ID
  18. Visual Studio 历史简介
  19. 做分销系统应该做小程序还是app?
  20. 大数据分析岗位的就业前景

热门文章

  1. python 拼音搜索中文_汉语转拼音工具、新华字典API——两个支持Python的中文资源...
  2. 创始人李卉:麦客CRM2.0核心逻辑及其背后的思考
  3. 【论文阅读】Pothole Detection Based on Disparity Transformation and Road Surface Modeling
  4. 1078 字符串压缩与解压
  5. 经济法基础——第五章第二节、个人所得税法律制度
  6. Android查看手机sqlite数据库(可视化)
  7. JAVA计算机毕业设计校园闲置物品信息管理系统Mybatis+源码+数据库+lw文档+系统+调试部署
  8. 激活后服务器无限重启,服务器无限重启
  9. 电源的输出纹波噪声究竟该取多少才合适?
  10. 和数研究院4周年庆,初心不改,笃行致远!