
 主要器件:手机电池供电,PT1301升压到5V,以TL431输出的2.5V为探头的信号地,运放TL082做信号放大,数字电位器MCP41010做增益调节,NOKIA1100液晶屏做为显示,96*65像素点,其工作所需3.3V电压是5V电压串联LED后得来的。STC12C5A50S2做为核心控制,据资料介绍其ADC采样速度可达250KHz,两路ADC采集波形数据,一路ADC采集2.5V电压,一路ADC采集电池电压,两路PWM经低通滤波后控制调理电路的偏移。探头接口是用的双声道耳机接口,比较节省空间,但是通道间会有干扰。按键有9个,CH:选通道; Vp/Hp:主菜单选择:POWER:开机;Vs/Hs:(本程序未用)    INC:+,STOP:关机 SET:进弹出菜单 DEC:- ESC:退出/暂停
 程序介绍:
    程序中为了方便图形操作,为液晶屏建立了内存缓冲,绘图操做在单片机内存中进行,然后整体复制到液晶屏.由于内存不太充裕,采用了分块的方法,以时间换取空间:
#define LCD_WIDTH 96
#define LCD_HEIGHT 8
//液晶分区数
#define LCD_PART 2
//U8 lcd_x=0;
//U8 lcd_y=0;
xdata U8 lcd_buf[LCD_HEIGHT/LCD_PART][LCD_WIDTH];//lcd显示缓存(1/LCD_PART屏)
xdata S16 lcd_bufx0=0,lcd_bufy0=0,lcd_bufx1=0,lcd_bufy1=0;//缓冲区对应四角坐标,(去掉右边框)
//x0 <= x < x1;y0 <= y < y1;
//-------------------------------------------------------
//选择液晶屏区域
//s=0~LCD_PART-1
//-------------------------------------------------------
void lcd_buf_sel(U8 s)
{
    if(s>=LCD_PART)return;
    lcd_bufx0=0;
    lcd_bufx1=LCD_WIDTH;
    lcd_bufy0=LCD_HEIGHT*s/LCD_PART;    
    lcd_bufy1=LCD_HEIGHT*(s+1)/LCD_PART;
}
绘图时需遍历每个显示缓存块:
    for(p=0;p<LCD_PART;p++)
    {
        lcd_buf_sel(p);
        //LCD_DrawPic(0,0,160,123,0,gImage_t1);
        lcd_buf_fill(0x04);        
        GUI_SetFont6x8();
        GUI_dispnum(i,3,0,5,13,0);
        GUI_PutStr(5,5,"welcome...");
        GUI_SetFont8x16();
        GUI_PutStr(5,25,"welcome...");
        lcd_refresh();
    }
程序在timer0中断里采集波形数据,主要代码如下:
//--------------------------------------------------
//定时器中查询AD
//--------------------------------------------------
void timer0(void)    interrupt 1 using 3    //T0中断,用寄存器组0
{
    //while(TF0==0);
    //TF0=0;
    U8 ad;
    //static U8 fp=0;//分频    
    if(T0EXC==0)
    {
        //mmm++;
        TH0=TH0RLD;//重装初值
        TL0=TL0RLD;
        T0EXC=T0EXH;
        //dosamp();
        while(ADC_CONTR&BIT(3));//等待通道0转换完成
        //while(!(ADC_CONTR&BIT(4)));
        ad=ADC_RES;//读通道0
        if(TrigCh==0)//通道1触发
        {
            if(ChEnable & BIT(1))//通道2使能
                ADC_CONTR=(0xE8|ADCH2);//选通道2
            else        //否则选通道1
                ADC_CONTR=(0xE8|ADCH1);//选通道1
            ADCBuf[0][BUF_Wps]=ad;//循环存储数据
        }
        else
        {
            if(ChEnable & BIT(0))//通道1使能
                ADC_CONTR=(0xE8|ADCH1);//选通道1
            else        //否则选通道1
                ADC_CONTR=(0xE8|ADCH2);//选通道2
            ADCBuf[1][BUF_Wps]=ad;//循环存储数据        
        }
        
        
        //if(BUF_Wps>=ADCBUFSIZE)BUF_Wps=0;
        if(SampState==0)//预采数据
        {
            //if(ADC_Cnt<ADCBUFSIZE)
            ADC_Cnt++;    //数据个数加1
            BUF_Cnt++;
            if(ADC_Cnt>=TrigPs)//触发位置
            {
                if(TrigEdge==0)//上升沿触发
                    SampState=1;
                else            //下降沿触发
                    SampState=2;
            }
        }
        //------------------------上升沿状态为1-2-3,下降沿状态为2-1-3
        else if(SampState==1)
        {            
            if(ad<=TrigLevel)//低于触发电平
            {
                if(TrigEdge==0)//上升沿触发
                    SampState=2;
                else            //下降沿触发
                    SampState=3;
                //if(ADC_Cnt<ADCBUFSIZE)
                ADC_Cnt++;//数据个数加1
                BUF_Cnt++;
            }
            else//否则读取队列,ADC_Cnt,BUF_Cnt就不加了
            {
                BUF_Rps++;
                if(BUF_Rps>=ADCBUFSIZE)BUF_Rps=0;
            }
        }
        else if(SampState==2)
        {
            if(ad>TrigLevel)//高于触发电平
            {
                if(TrigEdge==0)//上升沿触发
                    SampState=3;
                else            //下降沿触发
                    SampState=1;
                //if(ADC_Cnt<ADCBUFSIZE)
                ADC_Cnt++;//数据个数加1
                BUF_Cnt++;
            }
            else//否则读取队列,ADC_Cnt,BUF_Cnt就不加了
            {
                BUF_Rps++;
                if(BUF_Rps>=ADCBUFSIZE)BUF_Rps=0;
            }
        }
        else if(SampState==3)//已触发
        {
            ADC_Cnt++;    //数据个数加1
            BUF_Cnt++;
            if(ADC_Cnt>=ADCBUFSIZE)//采了足够的数据
            {
                SampState=4;
                TR0=0;
            }
        }
        if((TrigMode==0)&&(SampState<3))//自动触发处理
        {        
            if(TrigWait==0)//等待时间低位
            {
                if(TrigWaitH)//等待时间高位
                {
                    TrigWaitH--;
                }
                else
                {
                    SampState=3;
                }
            }
            TrigWait--;
        }
        if(TrigCh==0)//通道1触发
        {
            if(ChEnable & BIT(1))//通道2使能    
            {
                while(ADC_CONTR&BIT(3));//等待通道1转换完成
                //while(!(ADC_CONTR&BIT(4)));
                ad=ADC_RES;//读通道1
                ADC_CONTR=(0xE8|ADCH1);//选通道1
                ADCBuf[1][BUF_Wps]=ad;//循环存储数据
            }
        }
        else
        {
            if(ChEnable & BIT(0))//通道1使能    
            {
                while(ADC_CONTR&BIT(3));//等待通道1转换完成
                //while(!(ADC_CONTR&BIT(4)));
                ad=ADC_RES;//读通道1
                ADC_CONTR=(0xE8|ADCH2);//选通道2
                ADCBuf[0][BUF_Wps]=ad;//循环存储数据
            }        
        }
        //写指针下移
        BUF_Wps++;
        if(BUF_Wps>=ADCBUFSIZE)BUF_Wps=0;
    }
    else
    {
        T0EXC--;
    }
}