找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 3357|回复: 2
打印 上一主题 下一主题
收起左侧

LCD1602显示PCF8591 AD值 51单片机

[复制链接]
跳转到指定楼层
楼主
LCD1602显示AD值   51单片机





所有资料下载:
LCD1602显示AD值.rar (1.47 MB, 下载次数: 94)

  1. /*******************************************************************************
  2. *                 
  3. --------------------------------------------------------------------------------
  4. * 实 验 名                 : AD显示试验
  5. * 实验说明       : 使用LCD1602显示AD读取到的各个数值
  6. * 连接方式       : 见连接图
  7. * 注    意                 :
  8. *******************************************************************************/

  9. #include<reg51.h>
  10. #include"i2c.h"
  11. #include"lcd.h"

  12. //--定义PCF8591的读写地址--//
  13. #define  WRITEADDR 0x90           //写地址
  14. #define  READADDR  0x91           //读地址

  15. //--声明全局函数--//
  16. void Pcf8591SendByte(unsigned char channel);
  17. unsigned char Pcf8591ReadByte();
  18. void Pcf8591DaConversion(unsigned char value);

  19. /*******************************************************************************
  20. * 函 数 名         : main
  21. * 函数功能                   : 主函数
  22. * 输    入         : 无
  23. * 输    出         : 无
  24. *******************************************************************************/

  25. void main()
  26. {
  27.         unsigned int adNum[5];
  28.         float value0;
  29.         LcdInit();
  30.         while(1)
  31.         {       
  32.                 //--显示电位器电压--//
  33.                 Pcf8591SendByte(0);             //发送电位器转换命令

  34.                 //--由于8591在第一次读取的时候是读取到的上次转换的结果--//
  35.                 //--所以我们先读一次,只是读到的数据不做处理--//
  36.                 adNum[0]=        Pcf8591ReadByte()*2;//将前一次转换结果读走

  37.                 //--在读走上一次转换结果之后,才开始启动下一次转换,需要一点时间--//
  38.                 //--为了不浪费单片机的资源,让单片机空着,我们直接发送给我们下次--//
  39.                 //--要读取的命令,做一些数据处理和显示当做延时--//
  40.                 LcdWriteCom(0x80+0x46);                              //发送显示坐标
  41.                 LcdWriteData('0'+adNum[3]/1000);          //发送显示数据
  42.                 LcdWriteData('0'+adNum[3]%1000/100);
  43.                 LcdWriteData('0'+adNum[3]%100/10);
  44.                 LcdWriteData('0'+adNum[3]%10);
  45.                 Pcf8591SendByte(1);             //发送热敏转换命令
  46.                 adNum[0]=        Pcf8591ReadByte()*2;//读取电位器转换结果

  47.                 //--读取走了,上一次转换结果就是电位器的转换结果之后,热敏的转换开始--//
  48.                 //--我们继续做一些处理当延时。--//
  49.                 //--我们8591每读取到一个1就表示5/256V,所以要知道电压值就乘以0.01953--//
  50.                 value0=adNum[0]/2*0.01953;  //转为电压值
  51.                 adNum[0]=value0*100;        //保留两位小数
  52.                 LcdWriteCom(0x80);
  53.                 LcdWriteData('0'+adNum[0]%1000/100);
  54.                 LcdWriteData('.');
  55.                 LcdWriteData('0'+adNum[0]%100/10);
  56.                 LcdWriteData('0'+adNum[0]%10);
  57.                 LcdWriteData('V');

  58.                 Pcf8591SendByte(2);               //发送光敏转换命令
  59.                 adNum[1]=Pcf8591ReadByte()*2; //ADC1读取热敏

  60.                 //--一下读取的方式跟上面一样处理--//
  61.                 //--读光敏--//
  62.                 LcdWriteCom(0x86);
  63.                 LcdWriteData('0'+adNum[1]/1000);       
  64.                 LcdWriteData('0'+adNum[1]%1000/100);
  65.                 LcdWriteData('0'+adNum[1]%100/10);
  66.                 LcdWriteData('0'+adNum[1]%10);
  67.                
  68.                 Pcf8591SendByte(3);                   //发送外部输入电压转换命令
  69.                 adNum[2]=Pcf8591ReadByte()*2;  //ADC2读取光敏

  70.                 //--读取外部输入电压--//
  71.                 LcdWriteCom(0x80+0x40);
  72.                 LcdWriteData('0');
  73.                 LcdWriteData('0'+adNum[2]/1000);       
  74.                 LcdWriteData('0'+adNum[2]%1000/100);
  75.                 LcdWriteData('0'+adNum[2]%100/10);
  76.                 LcdWriteData('0'+adNum[2]%10);
  77.                 adNum[3]=Pcf8591ReadByte()*2;  //ADC3读取外部输入电压

  78.                 //--DA输出--//
  79.                 adNum[4]=adNum[0];
  80.                 Pcf8591DaConversion(adNum[4]/2); //DAC          数模转换
  81.                
  82.                                                                                
  83.         }
  84.                                  
  85. }
  86. /*******************************************************************************
  87. * 函 数 名         : Pcf8591SendByte
  88. * 函数功能                   : 写入一个控制命令
  89. * 输    入         : channel(转换通道)
  90. * 输    出         : 无
  91. *******************************************************************************/

  92. void Pcf8591SendByte(unsigned char channel)
  93. {       
  94.         I2C_Start();
  95.         I2C_SendByte(WRITEADDR, 1);    //发送写器件地址
  96.         I2C_SendByte(0x40|channel, 0); //发送控制寄存器
  97.         I2C_Stop();
  98. }
  99. /*******************************************************************************
  100. * 函 数 名         : Pcf8591ReadByte
  101. * 函数功能                   : 读取一个转换值
  102. * 输    入         : 无
  103. * 输    出         : dat
  104. *******************************************************************************/

  105. unsigned char Pcf8591ReadByte()
  106. {
  107.         unsigned char dat;
  108.         I2C_Start();
  109.         I2C_SendByte(READADDR, 1);//发送读器件地址
  110.         dat=I2C_ReadByte();    //读取数据
  111.         I2C_Stop();            //结束总线
  112.     return dat;
  113. }
  114. /*******************************************************************************
  115. * 函 数 名         : Pcf8591DaConversion
  116. * 函数功能                   : PCF8591的输出端输出模拟量
  117. * 输    入         : value(转换的数值)
  118. * 输    出         : 无
  119. *******************************************************************************/

  120. void Pcf8591DaConversion(unsigned char value)
  121. {
  122.         I2C_Start();
  123.         I2C_SendByte(WRITEADDR, 1);//发送写器件地址
  124.         I2C_SendByte(0x40, 1);     //开启DA写到控制寄存器
  125.         I2C_SendByte(value, 0);    //发送转换数值
  126.         I2C_Stop();       
  127. }
复制代码


  1. #include"i2c.h"

  2. /*******************************************************************************
  3. * 函 数 名         : Delay1us()
  4. * 函数功能                   : 延时
  5. * 输    入         : 无
  6. * 输    出         : 无
  7. *******************************************************************************/

  8. void I2C_Delay10us()
  9. {
  10.         uchar a, b;
  11.         for(b=1; b>0; b--)
  12.         {
  13.                 for(a=2; a>0; a--);
  14.         }
  15. }
  16. /*******************************************************************************
  17. * 函 数 名         : I2C_Start()
  18. * 函数功能                   : 起始信号:在I2C_SCL时钟信号在高电平期间I2C_SDA信号产生一个下降沿
  19. * 输    入         : 无
  20. * 输    出         : 无
  21. * 备    注         : 起始之后I2C_SDA和I2C_SCL都为0
  22. *******************************************************************************/

  23. void I2C_Start()
  24. {
  25.         I2C_SDA = 1;
  26.         I2C_Delay10us();
  27.         I2C_SCL = 1;
  28.         I2C_Delay10us();//建立时间是I2C_SDA保持时间>4.7us
  29.         I2C_SDA = 0;
  30.         I2C_Delay10us();//保持时间是>4us
  31.         I2C_SCL = 0;                       
  32.         I2C_Delay10us();               
  33. }
  34. /*******************************************************************************
  35. * 函 数 名           : I2C_Stop()
  36. * 函数功能                 : 终止信号:在I2C_SCL时钟信号高电平期间I2C_SDA信号产生一个上升沿
  37. * 输    入           : 无
  38. * 输    出                  : 无
  39. * 备    注           : 结束之后保持I2C_SDA和I2C_SCL都为1;表示总线空闲
  40. *******************************************************************************/

  41. void I2C_Stop()
  42. {
  43.         I2C_SDA = 0;
  44.         I2C_Delay10us();
  45.         I2C_SCL = 1;
  46.         I2C_Delay10us();//建立时间大于4.7us
  47.         I2C_SDA = 1;
  48.         I2C_Delay10us();               
  49. }
  50. /*******************************************************************************
  51. * 函 数 名           : I2cSendByte(uchar num)
  52. * 函数功能                  : 通过I2C发送一个字节。在I2C_SCL时钟信号高电平期间,
  53. *                    * 保持发送信号I2C_SDA保持稳定
  54. * 输    入           : num ,ack
  55. * 输    出                  : 0或1。发送成功返回1,发送失败返回0
  56. * 备    注           : 发送完一个字节I2C_SCL=0, 需要应答则应答设置为1,否则为0
  57. *******************************************************************************/

  58. uchar I2C_SendByte(uchar dat, uchar ack)
  59. {
  60.         uchar a = 0,b = 0;//最大255,一个机器周期为1us,最大延时255us。
  61.                        
  62.         for(a=0; a<8; a++)//要发送8位,从最高位开始
  63.         {
  64.                 I2C_SDA = dat >> 7;         //起始信号之后I2C_SCL=0,所以可以直接改变I2C_SDA信号
  65.                 dat = dat << 1;
  66.                 I2C_Delay10us();
  67.                 I2C_SCL = 1;
  68.                 I2C_Delay10us();//建立时间>4.7us
  69.                 I2C_SCL = 0;
  70.                 I2C_Delay10us();//时间大于4us               
  71.         }

  72.         I2C_SDA = 1;
  73.         I2C_Delay10us();
  74.         I2C_SCL = 1;
  75.         while(I2C_SDA && (ack == 1))//等待应答,也就是等待从设备把I2C_SDA拉低
  76.         {
  77.                 b++;
  78.                 if(b > 200)         //如果超过200us没有应答发送失败,或者为非应答,表示接收结束
  79.                 {
  80.                         I2C_SCL = 0;
  81.                         I2C_Delay10us();
  82.                         return 0;
  83.                 }
  84.         }

  85.         I2C_SCL = 0;
  86.         I2C_Delay10us();
  87.         return 1;               
  88. }
  89. /*******************************************************************************
  90. * 函 数 名           : I2cReadByte()
  91. * 函数功能                     : 使用I2c读取一个字节
  92. * 输    入           : 无
  93. * 输    出                  : dat
  94. * 备    注           : 接收完一个字节I2C_SCL=0
  95. *******************************************************************************/

  96. uchar I2C_ReadByte()
  97. {
  98.         uchar a = 0,dat = 0;
  99.         I2C_SDA = 1;                        //起始和发送一个字节之后I2C_SCL都是0
  100.         I2C_Delay10us();
  101.         for(a=0; a<8; a++)//接收8个字节
  102.         {
  103.                 I2C_SCL = 1;
  104.                 I2C_Delay10us();
  105.                 dat <<= 1;
  106.                 dat |= I2C_SDA;
  107.                 I2C_Delay10us();
  108.                 I2C_SCL = 0;
  109.                 I2C_Delay10us();
  110.         }
  111.         return dat;               
  112. }
复制代码


评分

参与人数 2黑币 +55 收起 理由
ENTERNAME + 5 赞一个!
admin + 50 共享资料的黑币奖励!

查看全部评分

分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏1 分享淘帖 顶1 踩
回复

使用道具 举报

沙发
ID:107467 发表于 2016-8-9 19:35 | 只看该作者
谢了,学习学习
回复

使用道具 举报

板凳
ID:122133 发表于 2017-8-9 20:57 | 只看该作者
没用
显示一直不变
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表