找回密码
 立即注册

QQ登录

只需一步,快速开始

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

51单片机AD四路采集串口显示双IIC及OLED显示

[复制链接]
跳转到指定楼层
楼主
ID:866576 发表于 2023-11-6 14:51 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
为了让后来者少走弯路,分享一个51单片机AD四路采集PCF8591实时采集的例程。双IIC接口,还附上Proteus防真。
地址:AD四路采集串口显示双IIC

单片机源程序如下:
  1. #include "main.h"

  2. // 变量定义

  3. u32 V0=0,V1=0,V2=0,V3=0;
  4. u8 num;

  5. //******************************************************************/

  6. main()
  7. {  
  8.         OLED_Init();
  9.         OLED_ColorTurn(0);     //0正常显示,1 反色显示
  10.   OLED_DisplayTurn(0);   //0正常显示 1 屏幕翻转显示        
  11.         OLED_DrawBMP(0,0,128,64,BMP1);
  12.         
  13.         Uart_Init();        
  14.         Timer0_Init();
  15.         
  16.         delayms(500);
  17.   OLED_Clear();
  18.         
  19.         OLED_ShowChinese(24,1,0,16);//祝
  20.         OLED_ShowChinese(40,1,1,16);//你
  21.         OLED_ShowChinese(56,1,2,16);//好
  22.         OLED_ShowChinese(72,1,3,16);//运
  23.         OLED_ShowChinese(88,1,4,16);//!
  24.         delayms(500);
  25.          OLED_Clear();
  26.         
  27.         OLED_ShowString(0,0,"CHANNEL1:",16);   
  28.         OLED_ShowString(0,2,"CHANNEL2:",16);   
  29.         OLED_ShowString(0,4,"CHANNEL3:",16);   
  30.         OLED_ShowString(0,6,"CHANNEL4:",16);   
  31.         
  32.         while(1)
  33.         {
  34.              if(num==10)         
  35.                          {
  36.                          V0=ADC(0x40);         
  37.                              delayms(10);        
  38.                    V1=ADC(0x41);      
  39.                        delayms(10);        
  40.                          V2=ADC(0x42);
  41.                                    delayms(10);        
  42.                          V3=ADC(0x43);
  43.                              delayms(10);        
  44.                          DAC(V1);      
  45.                              delayms(10);        
  46.                                  
  47.                                   UartPrintASCII(V0);
  48.                         delayms(2);
  49.           UartPrintASCII(V1);
  50.             delayms(2);
  51.                 UartPrintASCII(V2);
  52.                    delayms(2);
  53.                 UartPrintASCII(V3);
  54.                                   UartPrintf("OK !");
  55.                  
  56.                    V0=V0*50000/255;
  57.                          V1=V1*50000/255;
  58.                          V2=V2*50000/255;
  59.                          V3=V3*50000/255;
  60.                                  
  61.                                 num=0;
  62.                        
  63.                                                   OLED_ShowNum(80,0,V1/10000,1,16);
  64.                                                         OLED_ShowString(88,0,".",16);
  65.                                                         OLED_ShowNum(96,0,V1%10000,4,16);
  66.                                                         
  67.                                                   OLED_ShowNum(80,2,V2/10000,1,16);
  68.                                                         OLED_ShowString(88,2,".",16);
  69.                                                         OLED_ShowNum(96,2,V2%10000,4,16);
  70.                                                         
  71.                                                   OLED_ShowNum(80,4,V3/10000,1,16);
  72.                                                         OLED_ShowString(88,4,".",16);
  73.                                                         OLED_ShowNum(96,4,V3%10000,4,16);
  74.                                                         
  75.                                                   OLED_ShowNum(80,6,V0/10000,1,16);
  76.                                                         OLED_ShowString(88,6,".",16);
  77.                                                         OLED_ShowNum(96,6,V0%10000,4,16);
  78.                         
  79.                          }
  80.                           
  81.    }
  82. }


  83. //*******************************************************************

  84. void Timer0_Isr() interrupt 1
  85. {
  86.         TF0 = 0;                      /*清除中断标志*/
  87.   TR0 = 0;                      /*关中断*/
  88.         
  89.         num++;
  90.         
  91.   TL0 = 0x00;                                //设置定时初始值
  92.         TH0 = 0x4C;                                //设置定时初始值
  93.   TR0 = 1;                      /*开中断*/        
  94. }
  95. //*******************************************************************
复制代码




  1. #include "ADC.h"  


  2. //*****串口初始化函数***********

  3. //******************************

  4. void Uart_Init(void)                                                                     
  5. {
  6.         REN  = 1;       //允许串行口接收数据
  7.         PCON &= 0x7F;                //波特率不倍速
  8.         SCON = 0x50;                //8位数据,可变波特率
  9.         AUXR &= 0xBF;                //定时器时钟12T模式
  10.         AUXR &= 0xFE;                //串口1选择定时器1为波特率发生器
  11.         TMOD &= 0x0F;                //设置定时器模式
  12.         TMOD |= 0x20;                //设置定时器模式
  13.         TL1 = 0xFD;                        //设置定时初始值
  14.         TH1 = 0xFD;                        //设置定时重载值
  15.         EA   = 1;       //打开全局中断控制
  16.         ES   = 0;       //打开串行口中断        
  17.         ET1 = 0;                          //禁止定时器中断
  18.         TR1 = 1;                          //定时器1开始计时
  19. }


  20. void UartPrintASCII(u8 dat)                                //发送一个字符
  21. {
  22.           TI=0;   
  23.     SBUF=dat;   
  24.     while(TI==0);   
  25.     TI=0;   
  26. }

  27. void UartPrintf(u8 *p)                                //发送字符串
  28. {        
  29.          while(*p)
  30.          {
  31.                  SBUF=*(p++);
  32.                 while(TI==0)
  33.                         {

  34.                   };
  35.                 TI=0;
  36.   }
  37. }

  38. void Timer0_Init(void)                //50毫秒@11.0592MHz
  39. {
  40.         EA=1;
  41.         ET0 = 1;        /*允许定时中断*/
  42.         TMOD &= 0xF0;                //设置定时器模式
  43.         TMOD |= 0x01;                //设置定时器模式
  44.         TL0 = 0x00;                                //设置定时初始值
  45.         TH0 = 0x4C;                                //设置定时初始值

  46.         TR0 = 1;        /*启动定时中断*/
  47. }



  48. /*******************************************************************
  49.                      起动总线函数               
  50. 函数原型: void  IIcStart();  
  51. 功能:     启动I2C总线,即发送I2C起始条件.  
  52. ********************************************************************/
  53. void IIcStart()
  54. {
  55.   SCL=1;
  56.         SDA=1;         /*发送起始条件的数据信号*/
  57.       delay5us();
  58.   SDA=0;                     /*发送起始信号*/
  59.            delay5us();   
  60. }

  61. /*******************************************************************
  62.                       结束总线函数               
  63. 函数原型: void  IIcStop();  
  64. 功能:     结束I2C总线,即发送I2C结束条件.  
  65. ********************************************************************/
  66. void IIcStop()
  67. {
  68.         SCL=1 ;
  69.   SDA=0;      /*发送结束条件的数据信号*/
  70.            delay5us();
  71.   SDA=1;      /*发送I2C总线结束信号*/
  72.            delay5us();
  73. }

  74. /********************************************************************
  75.                    发送应答
  76. 函数原型:  IIc_ACK(bit a);
  77. 功能:      主控器进行应答信号(注意:0表示发送应答,1表示发送非应答)
  78. ********************************************************************/
  79. void IIc_Ack(bit ack)
  80. {
  81.     SCL=1;
  82.         delay5us();
  83.     SDA=ack;                           /*清时钟线,钳住I2C总线以便继续接收*/
  84.                             delay5us();
  85.           SCL=0;
  86. }

  87. /********************************************************************
  88.                    等待应答
  89. 函数原型:  IIc_WaitACK(void);
  90. 功能:      主控器进行应答信号(0是就帮答)
  91. ********************************************************************/
  92. bit IIc_WaitAck(void)
  93. {
  94.           SCL=0;
  95.               delay5us();         
  96.           SCL=1;
  97.               delay5us();
  98.     if(SDA==1)
  99.                 {
  100.                 SCL=0;
  101.                 return 0;        
  102.           }
  103.           else
  104.                 {
  105.                  SCL=0;
  106.                  return 1;
  107.                 }        
  108. }



  109. /*******************************************************************
  110.                  字节数据发送函数               
  111. 函数原型: void  SendByte(UCHAR c);
  112. 功能:     将数据c发送出去,可以是地址,也可以是数据,发完后等待应答,并对
  113.           此状态位进行操作.(不应答或非应答都使ack=0)     
  114.            发送数据正常,ack=1; ack=0表示被控器无应答或损坏。
  115. ********************************************************************/
  116. void SendByte(unsigned char date)
  117. {
  118.     unsigned char temp,i;                   //用于探测字节内某一位值的掩码变量
  119.             temp=date;
  120.     for (i=0; i<8; i++)           //从高位到低位依次进行
  121.     {
  122.                           temp=temp<<1;
  123.                           SCL=0 ;
  124.                              delay5us();
  125.                                 SDA = CY;
  126.            delay5us();
  127.         SCL = 1;              //拉高SCL
  128.           delay5us();
  129.     }
  130.                 SCL = 0;
  131.     SDA = 1;                 //8位数据发送完后,主机释放SDA,以检测从机应答
  132. }

  133. /*******************************************************************
  134.                  字节数据接收函数               
  135. 函数原型: UCHAR  RcvByte();
  136. 功能:        用来接收从器件传来的数据,并判断总线错误(不发应答信号),
  137.           发完后请用应答函数应答从机。  
  138. ********************************************************************/   
  139. unsigned char RcvByte(void)
  140. {
  141.     unsigned char  i,j,k;
  142.            SCL=0;
  143.                   delay5us();
  144.   for(i=0;i<8;i++)
  145.       {
  146.         SCL=1;
  147.                                     delay5us();
  148.          j=SDA;  
  149.                                  k=(k<<1)|j;
  150.                                  SCL=0;
  151.                                     delay5us();
  152.       }
  153.                         return k;
  154. }


  155. /*******************************************************************
  156. D/A 变换, 转化函数               
  157. *******************************************************************/
  158. void DAC(unsigned char dat)
  159. {
  160.    IIcStart();              //启动总线
  161.    SendByte(0x90);            //发送器件地址0x90是写,0x91是读
  162.     IIc_WaitAck();
  163.    SendByte(0x41);                //发送控制字节//允许DA输出
  164.           IIc_WaitAck();
  165.    SendByte(dat);            //发送DAC的数值  
  166.     IIc_WaitAck();
  167.    IIcStop();               //结束总线
  168. }


  169. /*******************************************************************
  170. ADC读字节数据函数               
  171. *******************************************************************/
  172. unsigned char ADC(unsigned char addr)
  173. {  
  174.          unsigned char temp;

  175.    IIcStart();          //启动总线
  176.    SendByte(0x90);      //发送器件地址0x90是写,0x91是读
  177.     IIc_WaitAck();
  178.          SendByte(addr);                //控制字节:选择光敏电阻(0x41)还是滑动变阻器(0x43
  179.     IIc_WaitAck();
  180.    IIcStart();         
  181.    SendByte(0x91);                                
  182.           IIc_WaitAck();
  183.          temp=RcvByte();
  184.           IIc_Ack(1);            //0表示发送应答,1表示发送非应答
  185.          IIcStop();
  186.          return temp;         
  187. }
复制代码
Proteus8.15版本的仿真: Proteus8.15版本的仿真.7z (133.22 KB, 下载次数: 46)

评分

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

查看全部评分

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

使用道具 举报

沙发
ID:1098747 发表于 2023-11-8 17:05 | 只看该作者
你好,请问是采了四路的电压值吗
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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