代码不完善有BUG,望大神斧正!
这个示波器推荐输入电压0-5V,显示的时候右上角会显示实时电压(单位毫伏)
但是由于前置硬件的存在输入超过5V的电压甚至是负电压也是可以的,但是超过±5V的电压会被钳位二极管钳住到±5V
电路原理图如下:

/********************************************************************************** 【函数功能】: 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); }
复制代码{
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);//初始光标
}
制作出来的实物图如下:

