代码如下,利用PCF8591和iic采集模拟信号然后通过iic接口的OLED显示出来
代码不完善有BUG,望大神斧正!
这个示波器推荐输入电压0-5V,显示的时候右上角会显示实时电压(单位毫伏)
但是由于前置硬件的存在输入超过5V的电压甚至是负电压也是可以的,但是超过±5V的电压会被钳位二极管钳住到±5V

电路原理图如下:
1.png
/*********************************************************************************
  • * 【函数功能】: DA-AD实验/ADC示波器显示                                                                                          
  • * 【使用说明】: 单片机:STC89C52/STC15F104w
  •          1 光敏电阻
  •                                  2 热敏电阻
  •                                  3 输入端
  •                                  4 可调0-5V电压(蓝色电位器调节)
  •                                  
  • **********************************************************************************/
  • /********************************************************************************************/
  • #include<stc15.h>    //包含单片机寄存器的头文件
  • #include <I2C.H>
  • #define uchar unsigned char
  • #define  PCF8591 0x90    //PCF8591 地址
  • int xx=0;int y11,y22;
  • // 变量定义
  • unsigned char AD_CHANNEL;
  • unsigned int  D[32];
  • int ii,hh;
  •   // 函数申明
  • void delay(uchar i);
  • bit DACconversion(unsigned char sla,unsigned char c,  unsigned char Val);
  • bit ISendByte(unsigned char sla,unsigned char c);
  • unsigned char IRcvByte(unsigned char sla);
  • //******************************************************************/
  • int main()
  • {  
  •   oled_init();//初始化
  •         /*oled_wr_byte(0x2e,0);//关滚动
  •   oled_showstring(0,0,"TM VALUE",16);
  •   oled_showstring(0,2,"PR VALUE",16);
  •   oled_showstring(0,4,"NO VALUE",16);
  •   oled_showstring(0,6,"AR VALUE",16);*/
  •         while(1)
  •         {
  •         oled_DrawLine(0,0,0,63);
  •                 oled_DrawLine(0,63,127,63);
  •         /********以下AD-DA处理*************/  
  •         for(xx=0;xx<128;xx++)
  •                 {
  •             switch(AD_CHANNEL)
  •                 {
  •                         case 0: ISendByte(PCF8591,0x41);
  •                              D[0]=IRcvByte(PCF8591);  //ADC0 模数转换1      光敏电阻
  •                                  break;  
  •                         
  •                         case 1: ISendByte(PCF8591,0x42);
  •                              D[1]=IRcvByte(PCF8591);  //ADC1  模数转换2          热敏电阻
  •                                  break;  
  •                         
  •                         case 2: ISendByte(PCF8591,0x43);
  •                              D[2]=IRcvByte(PCF8591);  //ADC2        模数转换3           输入端
  •                                  break;  
  •                         
  •                         case 3: ISendByte(PCF8591,0x40);
  •                              D[3]=IRcvByte(PCF8591);  //ADC3   模数转换4           可调0-5v
  •                                  break;  
  •                         
  •                         case 4: DACconversion(PCF8591,0x40, D[4]); //DAC          数模转换
  •                              break;
  •                  
  •                 }
  •               D[4]=D[2];//把模拟输入采样的信号 通过数模转换输出
  •                         
  •            if(++AD_CHANNEL>4) AD_CHANNEL=0;
  •           ii=map(D[2],0,255,63,9);
  •                 hh=map(D[2],0,255,0,5000);
  •            /********以下将AD的值通过OLED显示*************/
  •          oled_shownum(64,0,hh,4,32);
  •     //oled_shownum(80,1,ii,3,32);        
  •    Setpos(xx,ii);               
  •          delay(200);
  •         
  •         }
  •                 oled_clear();
  •         }
  • }
  • void delay(uchar i)
  • {
  •   uchar j,k;
  •   for(j=i;j>0;j--)
  •     for(k=125;k>0;k--);
  • }
  • /*******************************************************************
  • DAC 变换, 转化函数               
  • *******************************************************************/
  • bit DACconversion(unsigned char sla,unsigned char c,  unsigned char Val)
  • {
  •    Start_I2c();              //启动总线
  •    SendByte(sla);            //发送器件地址
  •    //if(ack==0)return(0);
  •    SendByte(c);              //发送控制字节
  •    //if(ack==0)return(0);
  •    SendByte(Val);            //发送DAC的数值  
  •    //if(ack==0)return(0);
  •    Stop_I2c();               //结束总线
  •    return(1);
  • }
  • /*******************************************************************
  • ADC发送字节[命令]数据函数               
  • *******************************************************************/
  • bit ISendByte(unsigned char sla,unsigned char c)
  • {
  •    Start_I2c();              //启动总线
  •    SendByte(sla);            //发送器件地址
  •    //if(ack==0)return(0);
  •    SendByte(c);              //发送数据
  •    //if(ack==0)return(0);
  •    Stop_I2c();               //结束总线
  •    return(1);
  • }
  • /*******************************************************************
  • ADC读字节数据函数               
  • *******************************************************************/
  • unsigned char IRcvByte(unsigned char sla)
  • {  unsigned char c;
  •    Start_I2c();          //启动总线
  •    SendByte(sla+1);      //发送器件地址
  •    //if(ack==0)return(0);
  •    c=RcvByte();          //读取数据0
  •    Ack_I2c(1);           //发送非就答位
  •    Stop_I2c();           //结束总线
  •    return(c);
  • }
  • 复制代码
    void oled_init(void)//初始化ssd1306
    {
        delay_ms(500);//延时(必须有)
        oled_wr_byte(0xAE,0);//关闭oled面板
        oled_wr_byte(0x00,0);//设置低位列地址
        oled_wr_byte(0x10,0);//设置高位列地址
        oled_wr_byte(0x40,0);//设置起始行地址设置映射RAM显示起始行(0x00~0x3F)
        oled_wr_byte(0x81,0);//--设置对比度控制寄存器
        oled_wr_byte(0xCF,0);//设置SEG输出电流亮度
        oled_wr_byte(0xA1,0);//设置分段/列映射0xa0左右反置 0xa1型正常
        oled_wr_byte(0xC8,0);//设置COM/行扫描方向0xc0上下反置 0xc8型正常
        oled_wr_byte(0xA6,0);//设置正常显示
        oled_wr_byte(0xA8,0);//设置复用比(1到64)
        oled_wr_byte(0x3F,0);//1/64负载
        oled_wr_byte(0xD3,0);//设置显示偏移映射RAM计数器(0x00~0x3F)
        oled_wr_byte(0x00,0);//不补偿
        oled_wr_byte(0xD5,0);//设置显示时钟分频比/振荡器频率
        oled_wr_byte(0x80,0);//设置分频比,将时钟设置为100帧/秒
        oled_wr_byte(0xD8,0);
        oled_wr_byte(0x05,0);
        oled_wr_byte(0xD9,0);//设置预充电时间
        oled_wr_byte(0xF1,0);//将预充电设置为15个时钟,放电设置为1个时钟
        oled_wr_byte(0xDA,0);//设置com引脚硬件配置
        oled_wr_byte(0x12,0);//
        oled_wr_byte(0xDB,0);//设置vcomh
        oled_wr_byte(0x40,0);//设置VCOM取消选择级别
        oled_wr_byte(0x20,0);//设置页面寻址模式(0x00/0x01/0x02)
        oled_wr_byte(0x02,0);//
        oled_wr_byte(0x8D,0);//设置电荷泵启用/禁用
        oled_wr_byte(0x14,0);//设置(0x10)禁用
        oled_wr_byte(0xA4,0);//禁用整个显示打开(0xa4/0xa5)
        oled_wr_byte(0xA6,0);//禁用反转显示打开(0xa6/a7)
        oled_wr_byte(0xAF,0);//打开oled面板
        fill_picture(0x00);//初始清屏
        oled_set_pos(0,0);//初始光标
    }

    制作出来的实物图如下:
    2.gif

    3.png