找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 3789|回复: 4
收起左侧

单片机迷你示波器程序,基STC15f104w的迷你波形显示装置制作

  [复制链接]
ID:442609 发表于 2021-7-12 00:13 | 显示全部楼层 |阅读模式
代码如下,利用PCF8591和iic采集模拟信号然后通过iic接口的OLED显示出来
代码不完善有BUG,望大神斧正!
这个示波器推荐输入电压0-5V,显示的时候右上角会显示实时电压(单位毫伏)
但是由于前置硬件的存在输入超过5V的电压甚至是负电压也是可以的,但是超过±5V的电压会被钳位二极管钳住到±5V

电路原理图如下:

电路图

电路图

单片机源程序如下:
  1. /*********************************************************************************
  2. * 【函数功能】: DA-AD实验/ADC示波器显示                                                                                          
  3. * 【使用说明】: 单片机:STC89C52/STC15F104w
  4.          1 光敏电阻
  5.                                  2 热敏电阻
  6.                                  3 输入端
  7.                                  4 可调0-5V电压(蓝色电位器调节)
  8.                                  
  9. **********************************************************************************/
  10. /********************************************************************************************/

  11. #include<stc15.h>    //包含单片机寄存器的头文件
  12. #include <I2C.H>

  13. #define uchar unsigned char
  14. #define  PCF8591 0x90    //PCF8591 地址
  15. int xx=0;int y11,y22;



  16. // 变量定义
  17. unsigned char AD_CHANNEL;
  18. unsigned int  D[32];
  19. int ii,hh;


  20.   // 函数申明

  21. void delay(uchar i);
  22. bit DACconversion(unsigned char sla,unsigned char c,  unsigned char Val);
  23. bit ISendByte(unsigned char sla,unsigned char c);
  24. unsigned char IRcvByte(unsigned char sla);

  25. //******************************************************************/
  26. int main()
  27. {  
  28.   oled_init();//初始化
  29.         /*oled_wr_byte(0x2e,0);//关滚动
  30.   oled_showstring(0,0,"TM VALUE",16);
  31.   oled_showstring(0,2,"PR VALUE",16);
  32.   oled_showstring(0,4,"NO VALUE",16);
  33.   oled_showstring(0,6,"AR VALUE",16);*/
  34.         while(1)
  35.         {
  36.         oled_DrawLine(0,0,0,63);
  37.                 oled_DrawLine(0,63,127,63);
  38.         /********以下AD-DA处理*************/  
  39.         for(xx=0;xx<128;xx++)
  40.                 {
  41.             switch(AD_CHANNEL)
  42.                 {
  43.                         case 0: ISendByte(PCF8591,0x41);
  44.                              D[0]=IRcvByte(PCF8591);  //ADC0 模数转换1      光敏电阻
  45.                                  break;  
  46.                         
  47.                         case 1: ISendByte(PCF8591,0x42);
  48.                              D[1]=IRcvByte(PCF8591);  //ADC1  模数转换2          热敏电阻
  49.                                  break;  
  50.                         
  51.                         case 2: ISendByte(PCF8591,0x43);
  52.                              D[2]=IRcvByte(PCF8591);  //ADC2        模数转换3           输入端
  53.                                  break;  
  54.                         
  55.                         case 3: ISendByte(PCF8591,0x40);
  56.                              D[3]=IRcvByte(PCF8591);  //ADC3   模数转换4           可调0-5v
  57.                                  break;  
  58.                         
  59.                         case 4: DACconversion(PCF8591,0x40, D[4]); //DAC          数模转换
  60.                              break;
  61.                  
  62.                 }

  63.               D[4]=D[2];//把模拟输入采样的信号 通过数模转换输出
  64.                         
  65.            if(++AD_CHANNEL>4) AD_CHANNEL=0;
  66.           ii=map(D[2],0,255,63,9);
  67.                 hh=map(D[2],0,255,0,5000);
  68.            /********以下将AD的值通过OLED显示*************/
  69.          oled_shownum(64,0,hh,4,32);
  70.     //oled_shownum(80,1,ii,3,32);        
  71.    Setpos(xx,ii);               
  72.          delay(200);
  73.         
  74.         }
  75.                 oled_clear();
  76.         }
  77. }


  78. void delay(uchar i)
  79. {
  80.   uchar j,k;
  81.   for(j=i;j>0;j--)
  82.     for(k=125;k>0;k--);
  83. }

  84. /*******************************************************************
  85. DAC 变换, 转化函数               
  86. *******************************************************************/
  87. bit DACconversion(unsigned char sla,unsigned char c,  unsigned char Val)
  88. {
  89.    Start_I2c();              //启动总线
  90.    SendByte(sla);            //发送器件地址
  91.    //if(ack==0)return(0);
  92.    SendByte(c);              //发送控制字节
  93.    //if(ack==0)return(0);
  94.    SendByte(Val);            //发送DAC的数值  
  95.    //if(ack==0)return(0);
  96.    Stop_I2c();               //结束总线
  97.    return(1);
  98. }

  99. /*******************************************************************
  100. ADC发送字节[命令]数据函数               
  101. *******************************************************************/
  102. bit ISendByte(unsigned char sla,unsigned char c)
  103. {
  104.    Start_I2c();              //启动总线
  105.    SendByte(sla);            //发送器件地址
  106.    //if(ack==0)return(0);
  107.    SendByte(c);              //发送数据
  108.    //if(ack==0)return(0);
  109.    Stop_I2c();               //结束总线
  110.    return(1);
  111. }

  112. /*******************************************************************
  113. ADC读字节数据函数               
  114. *******************************************************************/
  115. unsigned char IRcvByte(unsigned char sla)
  116. {  unsigned char c;

  117.    Start_I2c();          //启动总线
  118.    SendByte(sla+1);      //发送器件地址
  119.    //if(ack==0)return(0);
  120.    c=RcvByte();          //读取数据0

  121.    Ack_I2c(1);           //发送非就答位
  122.    Stop_I2c();           //结束总线
  123.    return(c);
  124. }
复制代码
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);//初始光标
}

制作出来的实物图如下:

效果

效果


51hei.png

以上3个文件下载(需要自己建立Keil工程):
c文件与头文件.7z (6.44 KB, 下载次数: 24)

评分

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

查看全部评分

回复

使用道具 举报

ID:519089 发表于 2021-7-14 20:03 | 显示全部楼层
没什么用啊。。这速度没谁了,,,555都测不了
回复

使用道具 举报

ID:313048 发表于 2021-7-16 09:44 | 显示全部楼层
从你这速度可以猜测出你是采集一次显示一次,给你个建议,做个缓存,采集一页的数据之后再显示,这样至少解决你这缓慢显示的问题。就每次刷新一页。
回复

使用道具 举报

ID:1042569 发表于 2023-4-24 23:03 | 显示全部楼层
太慢了吧!!!
回复

使用道具 举报

ID:1034262 发表于 2023-4-30 11:55 | 显示全部楼层
STC公司出了一个示波器例子,500K采样50K带宽的,可以去他们官网下载。
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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