找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 5603|回复: 6
收起左侧

基于51单片机的PCF8591模数转换protues仿真LCD显示

[复制链接]
ID:222878 发表于 2017-7-28 21:04 | 显示全部楼层 |阅读模式
基于51单片机的PCF8591模数转换LCD显示,自带protues仿真.


0.png 0.png

单片机源程序如下:
  1. /****************************************************************
  2.               在1602液晶屏上显示各通道的电压值
  3. ******************************************************************/
  4. #include<reg52.h>    //包含单片机寄存器的头文件
  5. #include <intrins.h>

  6. #define  AddWr 0x90    //PCF8591 地址
  7. #define Data  P0    //数据端口

  8. // 变量定义
  9. unsigned char AD_CHANNEL;
  10. sbit scl=P2^6;       //I2C  时钟
  11. sbit sda=P2^7;       //I2C  数据
  12. bit ack;                 /*应答标志位*/

  13. sbit RS = P2^0;//Pin4
  14. sbit RW = P2^1; //Pin5
  15. sbit E  = P2^2;//Pin6



  16. unsigned char TempData[8];
  17. unsigned char  FirstLine[16]="Voltage:        ";
  18. unsigned char  SecondLine[16] ="Current:        ";
  19. /*******************************************************************
  20.                      起动总线函数               
  21. 函数原型: void  Start_I2c();  
  22. 功能:     启动I2C总线,即发送I2C起始条件.  
  23. ********************************************************************/
  24. void Start_I2c()
  25. {
  26.   sda=1;         /*发送起始条件的数据信号*/
  27.   _nop_();
  28.   scl=1;
  29.   _nop_();        /*起始条件建立时间大于4.7us,延时*/
  30.   _nop_();
  31.   _nop_();
  32.   _nop_();
  33.   _nop_();   
  34.   sda=0;         /*发送起始信号*/
  35.   _nop_();        /* 起始条件锁定时间大于4μs*/
  36.   _nop_();
  37.   _nop_();
  38.   _nop_();
  39.   _nop_();      
  40.   scl=0;       /*钳住I2C总线,准备发送或接收数据 */
  41.   _nop_();
  42.   _nop_();
  43. }

  44. /*******************************************************************
  45.                       结束总线函数               
  46. 函数原型: void  Stop_I2c();  
  47. 功能:     结束I2C总线,即发送I2C结束条件.  
  48. ********************************************************************/
  49. void Stop_I2c()
  50. {
  51.   sda=0;      /*发送结束条件的数据信号*/
  52.   _nop_();       /*发送结束条件的时钟信号*/
  53.   scl=1;      /*结束条件建立时间大于4μs*/
  54.   _nop_();
  55.   _nop_();
  56.   _nop_();
  57.   _nop_();
  58.   _nop_();
  59.   sda=1;      /*发送I2C总线结束信号*/
  60.   _nop_();
  61.   _nop_();
  62.   _nop_();
  63.   _nop_();
  64. }

  65. /*******************************************************************
  66.                  字节数据发送函数               
  67. 函数原型: void  I2C_SendByte(UCHAR c);
  68. 功能:     将数据c发送出去,可以是地址,也可以是数据,发完后等待应答,并对
  69.           此状态位进行操作.(不应答或非应答都使ack=0)     
  70.            发送数据正常,ack=1; ack=0表示被控器无应答或损坏。
  71. ********************************************************************/
  72. void  I2C_SendByte(unsigned char  c)
  73. {
  74. unsigned char  i;

  75. for(i=0;i<8;i++)  /*要传送的数据长度为8位*/
  76.     {
  77.      if((c<<i)&0x80)sda=1;   /*判断发送位*/
  78.        else  sda=0;               
  79.      _nop_();
  80.      scl=1;               /*置时钟线为高,通知被控器开始接收数据位*/
  81.       _nop_();
  82.       _nop_();             /*保证时钟高电平周期大于4μs*/
  83.       _nop_();
  84.       _nop_();
  85.       _nop_();         
  86.      scl=0;
  87.     }
  88.    
  89.     _nop_();
  90.     _nop_();
  91.     sda=1;                /*8位发送完后释放数据线,准备接收应答位*/
  92.     _nop_();
  93.     _nop_();   
  94.     scl=1;
  95.     _nop_();
  96.     _nop_();
  97.     _nop_();
  98.     if(sda==1)ack=0;     
  99.        else ack=1;        /*判断是否接收到应答信号*/
  100.     scl=0;
  101.     _nop_();
  102.     _nop_();
  103. }

  104. /*******************************************************************
  105.                  字节数据接收函数               
  106. 函数原型: UCHAR  I2C_RcvByte();
  107. 功能:        用来接收从器件传来的数据,并判断总线错误(不发应答信号),
  108.           发完后请用应答函数应答从机。  
  109. ********************************************************************/   
  110. unsigned char   I2C_RcvByte()
  111. {
  112.   unsigned char  retc=0,i;
  113.   sda=1;                     /*置数据线为输入方式*/
  114.   for(i=0;i<8;i++)
  115.       {
  116.         _nop_();           
  117.         scl=0;                  /*置时钟线为低,准备接收数据位*/
  118.         _nop_();
  119.         _nop_();                 /*时钟低电平周期大于4.7μs*/
  120.         _nop_();
  121.         _nop_();
  122.         _nop_();
  123.         scl=1;                  /*置时钟线为高使数据线上数据有效*/
  124.         _nop_();
  125.         _nop_();
  126.         retc=retc<<1;
  127.         if(sda==1)retc=retc+1;  /*读数据位,接收的数据位放入retc中 */
  128.         _nop_();
  129.         _nop_();
  130.       }
  131.   scl=0;   
  132.   _nop_();
  133.   _nop_();
  134.   return(retc);
  135. }

  136. /********************************************************************
  137.                      应答子函数
  138. 函数原型:  void Ack_I2c(bit a);
  139. 功能:      主控器进行应答信号(可以是应答或非应答信号,由位参数a决定)
  140. ********************************************************************/
  141. void Ack_I2c(bit a)
  142. {  
  143.   if(a==0)
  144.   {
  145.   sda=0;
  146.     _nop_();
  147.   _nop_();
  148.   _nop_();      
  149.   scl=1;
  150.   _nop_();
  151.   _nop_();                    /*时钟低电平周期大于4μs*/
  152.   _nop_();
  153.   _nop_();
  154.   _nop_();  
  155.   scl=0;                     /*清时钟线,住I2C总线以便继续接收*/
  156.   _nop_();
  157.   _nop_();   
  158.   sda=1;
  159.     _nop_();
  160.   _nop_();   

  161.   }              /*在此发出应答或非应答信号 */
  162.   else
  163. {  sda=1;                                  /*0为发出应答,1为非应答信号 */
  164.   _nop_();
  165.   _nop_();
  166.   _nop_();      
  167.   scl=1;
  168.   _nop_();
  169.   _nop_();                    /*时钟低电平周期大于4μs*/
  170.   _nop_();
  171.   _nop_();
  172.   _nop_();  
  173.   scl=0;                     /*清时钟线,住I2C总线以便继续接收*/
  174.   _nop_();
  175.   _nop_();
  176.   sda=0;
  177.       _nop_();
  178.   _nop_();   

  179.   }   
  180. }

  181. /************************************************************
  182. * 函数名        : Pcf8591_SendByte
  183. * 函数功能                : 写入一个控制命令
  184. * 输入          : addr(器件地址),channel(转换通道)
  185. * 输出                 : 无
  186. ************************************************************/
  187. bit PCF8591_SendByte(unsigned char addr,unsigned char channel)
  188. {
  189.    Start_I2c();              //启动总线
  190.    I2C_SendByte(addr);            //发送器件地址
  191.    if(ack==0)return(0);
  192.    I2C_SendByte(0x40|channel);              //发送控制字节
  193.    if(ack==0)return(0);
  194.    Stop_I2c();               //结束总线
  195.    return(1);
  196. }

  197. /************************************************************
  198. * 函数名               : PCF8591_RcvByte
  199. * 函数功能           : 读取一个转换值
  200. * 输入          :
  201. * 输出          : dat
  202. ************************************************************/
  203. unsigned char PCF8591_RcvByte(unsigned char addr)
  204. {  
  205.    unsigned char dat;

  206.    Start_I2c();          //启动总线
  207.    I2C_SendByte(addr+1);      //发送器件地址
  208.    if(ack==0)return(0);
  209.    dat=I2C_RcvByte();          //读取数据0

  210.    Ack_I2c(1);           //发送非应答信号
  211.    Stop_I2c();           //结束总线
  212.    return(dat);
  213. }

  214. /******************************************************************/
  215. /*                   1602液晶屏相关函数                                     */
  216. /******************************************************************/
  217. void DelayUs(unsigned char us)//delay us
  218. {
  219. unsigned char uscnt;
  220. uscnt=us>>1;/* Crystal frequency in 12MHz*/
  221. while(--uscnt);
  222. }
  223. /******************************************************************/
  224. void DelayMs(unsigned char ms)//delay Ms
  225. {
  226. while(--ms)
  227.    {
  228.      DelayUs(250);
  229.      DelayUs(250);
  230.          DelayUs(250);
  231.          DelayUs(250);
  232.    }
  233. }
  234. void WriteCommand(unsigned char c)
  235. {
  236. DelayMs(5);//short delay before operation
  237. E=0;
  238. RS=0;
  239. RW=0;
  240. _nop_();
  241. E=1;
  242. Data=c;
  243. E=0;
  244. }
  245. /****************************************************************/
  246. void WriteData(unsigned char c)
  247. {
  248. DelayMs(5);   //short delay before operation
  249. E=0;
  250. RS=1;
  251. RW=0;
  252. _nop_();
  253. E=1;
  254. Data=c;
  255. E=0;
  256. RS=0;
  257. }
  258. /*********************************************************************/
  259. void ShowChar(unsigned char pos,unsigned char c)
  260. {
  261. unsigned char p;
  262. if (pos>=0x10)
  263.     p=pos+0xb0; //是第二行则命令代码高4位为0xc
  264. else
  265.     p=pos+0x80; //是第二行则命令代码高4位为0x8
  266. WriteCommand (p);//write command
  267. WriteData (c);   //write data
  268. }
  269. /*************************************************************************/
  270. void ShowString (unsigned char line,char *ptr)
  271. {
  272. unsigned char l,i;
  273. l=line<<4;
  274. for (i=0;i<16;i++)
  275.   ShowChar (l++,*(ptr+i));//循环显示16个字符
  276. }
  277. /*********************************************************************/
  278. void InitLcd()
  279. {
  280. DelayMs(15);
  281. WriteCommand(0x38); //display mode
  282. WriteCommand(0x38); //display mode
  283. WriteCommand(0x38); //display mode
  284. WriteCommand(0x06); //显示光标移动位置
  285. WriteCommand(0x0c); //显示开及光标设置
  286. WriteCommand(0x01); //显示清屏

  287. }


  288. /////////////////////////////////////////////////////////////////
  289. void disp(void)

  290. {
  291.    unsigned char i=0;
  292.    while(FirstLine[i]!=' ')
  293.    {
  294.            ShowString(0,FirstLine);
  295.         i++;
  296.    }


  297. FirstLine[8]= '0'+TempData[0];
  298. FirstLine[9]= '0'+TempData[1];
  299. FirstLine[10]='.';
  300. FirstLine[11]='0'+TempData[2];
  301. FirstLine[12]='0'+TempData[3];
  302. FirstLine[14]='V';

  303. ShowString(0,FirstLine);

  304.      while(SecondLine[i]!=' ')
  305.    {
  306.            ShowString(1,SecondLine);
  307.         i++;
  308.    }

  309. SecondLine[8]='0'+TempData[4];
  310. SecondLine[11]='0'+TempData[6];
  311. SecondLine[10]='.';
  312. SecondLine[14]='V';



  313. ShowString(1,SecondLine);

  314. }
  315. /*------------------------------------------------
  316.                     延时程序
  317. ------------------------------------------------*/
  318. void mDelay(unsigned char j)
  319. {
  320.   unsigned int i;
  321. ……………………

  322. …………限于本文篇幅 余下代码请从51黑下载附件…………
复制代码

所有资料51hei提供下载:
AD-PCF8591.zip (70.71 KB, 下载次数: 210)

评分

参与人数 1黑币 +50 收起 理由
admin + 50 共享资料的黑币奖励!

查看全部评分

回复

使用道具 举报

ID:202719 发表于 2018-1-20 00:17 | 显示全部楼层
没有仿真文件的?
回复

使用道具 举报

ID:285352 发表于 2018-5-23 10:17 | 显示全部楼层
刚好在学习,收藏了
回复

使用道具 举报

ID:285352 发表于 2018-5-23 10:33 | 显示全部楼层
找不到仿真文件呀,只有代码
回复

使用道具 举报

ID:362275 发表于 2018-7-1 15:31 | 显示全部楼层
没有封装吗
回复

使用道具 举报

ID:389518 发表于 2018-8-30 09:40 | 显示全部楼层
仿真文件在哪?用楼主的仿真图连接的电路根本无法实现
回复

使用道具 举报

ID:492564 发表于 2019-3-30 23:11 | 显示全部楼层
没protues文件啊
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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