迷你单片机示波器!51单片机和STC15F104W适用~

基于STC15F104W的单片机示波器

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

主要思路还是画点函数画出图像

这段代码我是直接抄B站UP主@x麟枫 的作业的,比较懒23333

void Setpos(unsigned char x0,unsigned char y0)
{
	unsigned char y,mod,pos;
	if(y0%8==0){	//输入的y进行处理,如果能被8整除,值必然在0~7页
		 y=y0/8;	//设它的点在对应值的第一个点。
		 pos = 0x01;	
	}
	else{
		y = y0/8;		//如果不能被整除
		mod = y0%8;		//取余数,用把余数看成1~7个二进制位
						//然后用16进制在那一页上设立对应的值
		switch(mod)
		{
			case 1:
			pos = 0x02;
			break;
			case 2:
			pos = 0x04;
			break;
			case 3:
			pos = 0x08;
			break;
			case 4:
			pos = 0x10;
			break;
			case 5:
			pos = 0x20;
			break;
			case 6:
			pos = 0x40;
			break;
			case 7:
			pos = 0x80;
			break;
			default:
			break;

		}
	}
	oled_set_pos(x0,y);		//OLED设置起始位置的函数
	oled_wr_byte(pos,1);	//在那个位置写数据,1表示那个点亮,0表示那个点灭

}

然后主代码如下:

#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);
}
  • 3
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值