单片机+LCD12864数字示波器程序+Proteus仿真

发布者:科技之翼最新更新时间:2020-01-31 来源: 51hei关键字:单片机  LCD12864  数字示波器  Proteus仿真 手机看文章 扫描二维码
随时随地手机看文章

基于51单片机和Proteus仿真的数字示波器
 
#include
#include
//12864控制引脚定义
sbit DI = P2 ^ 2; //数据指令选择引脚
sbit RW = P2 ^ 1; //读写选择引脚
sbit E= P2 ^ 0;   //读写使能引脚
sbit CS1 = P2 ^ 4;    //片选1引脚
sbit CS2 = P2 ^ 3;    //片选2引脚
sbit BUSY= P1 ^ 7;    //忙标志位
//按键控制定义
sbit Y1 = P3 ^ 0;
sbit Y2 = P3 ^ 1;
sbit X1 = P3 ^ 3;
sbit X2 = P3 ^ 7;
//ADC0832控制引脚
sbit START=P3^4;
sbit OE=P3^6;
sbit EOC=P3^5;

unsigned int ADdata;    //AD采集值
unsigned int Ldata;
unsigned char ye,lei,shu;
unsigned char ADViewdata[91]; //AD显示数据存储区

char code FrameData[]={                     //提示字符存储区                                                                                                                                         
0x00,0x00,0x3F,0xF8,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0xFE,0x01,0x00,
0x01,0x00,0x11,0x10,0x11,0x08,0x21,0x04,0x41,0x02,0x81,0x02,0x05,0x00,0x02,0x00,    //示
0x00,0x20,0x20,0x20,0x10,0x20,0x13,0xFE,0x82,0x22,0x42,0x24,0x4A,0x20,0x0B,0xFC,
0x12,0x84,0x12,0x88,0xE2,0x48,0x22,0x50,0x22,0x20,0x24,0x50,0x24,0x88,0x09,0x06,                //波                
0x00,0x00,0x3E,0x7C,0x22,0x44,0x22,0x44,0x3E,0x7C,0x01,0x20,0x01,0x10,0xFF,0xFE,
0x02,0x80,0x0C,0x60,0x30,0x18,0xC0,0x06,0x3E,0x7C,0x22,0x44,0x22,0x44,0x3E,0x7C,    //器 
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,    //" "
};
//AD转换软件
void ADCChage()
{
  START=1;
  START=0;
  while(EOC==0)  //等待转换完成
{
   OE=1;
}
  ADdata = P0;   //读取AD数据
        OE=0;
}
//检查12864液晶状态                               
void CheckState()
{
  DI=0;
        RW=1;
        do
        {
          E=1; 
          E=0;
   //仅当第7位为0时才可操作(判别busy信号)
        }while(BUSY==1);
}
//向12864写入一个字节的命令
void WriteCommand(unsigned char cmd)         
{
        CheckState();         //检查当前的12864状态
        DI = 0;
        RW = 0;
        P1 = cmd;             //送出相应的命令
        E = 1;
        E = 0;
}  
//向12864写入一个字节的数据
void WriteData(unsigned char dat)                
{
   CheckState();   //检查当前的12864状态
   DI = 1; 
   RW = 0;
   P1 = dat;       //送出相应的数据
   E = 1; 
   E = 0; 
}
//12864液晶的选择控制引脚
void LCMCSControl(unsigned int csl)
{
  if(csl==1)    //根据参数不同判断当前的12864控制引脚状态
  { 
    CS1=0,
    CS2=1;
  }
  if(csl==2)
  {
    CS1=1,
    CS2=0;
  }
  if(csl==3)
  {
    CS1=0,
    CS2=0;
  }
}
//12864显示函数
void LCMView()
{
  LCMCSControl(Ldata);     //先发送控制命令
  WriteCommand(ye);
  WriteCommand(lei);
  WriteData(shu);         //然后发送数据
}
//12864的清屏函数
void CleanScreen()                                                
{
        unsigned char page,i;
        LCMCSControl(3);
        for(page=0xb8;page<=0xbf;page++)
        {   
                WriteCommand(page);
                WriteCommand(0x40);
                for(i=0;i<64;i++)
    {
                  WriteData(0x00);
    }
        }
        LCMCSControl(1);
  lei=0x40;
        for(ye=0xb8;ye<0xbf;ye++)
        {
         shu=0xff;
         LCMView();
        }
        ye=0xb8;
        for(lei=0x40;lei<=0x7f;lei++)
        {
          shu=0x80;
          LCMView();
        }
        ye=0xbf;
        for(lei=0x40;lei<=0x7f;lei++)
        {
          shu=0x01;
          LCMView();
        }
  LCMCSControl(2);
  ye=0xb8;
        for(lei=0x40;lei<=0x5b;lei++)
  {
          shu=0x80;
          LCMView();
        }
        ye=0xbf;
        for(lei=0x40;lei<=0x5b;lei++)
        {
          shu=0x01;
          LCMView();
        }
        lei=0x5b;
        for(ye=0xb9;ye<=0xbe;ye++)
        {
         shu=0xff;
         LCMView();
        } 
}
//12864的初始化函数
void InitLCM(void)   
{        
  WriteCommand(0xc0);
        WriteCommand(0x3f);
}
//50us的延时函数
void Delay50us(unsigned int t)
{
unsigned char j;  
for(;t>0;t--)   
  for(j=19;j>0;j--);
}
//刷新12864液晶
void RefreshLCM()
{
  unsigned char i;
  for(i=0xb9;i<=0xbe;i++)
  {
    ye=i;
          shu=0x00;
          LCMView();
        }
}
//主函数
void main()
{
    unsigned int r,j,q,k;
    unsigned int Xaxis =0;
    unsigned int Yaxis = 1;
    unsigned char l;
    unsigned char d1,d2,d3,d4,d5;
    CleanScreen();
    InitLCM();
          LCMCSControl(2);
          l=0xb8;
          for(k=0;k<4;k++,l=l+0x02)         //首先显示右侧的提示
          {
            ye=l;
            lei=0x70;
            for(r=0;r<16;r++)
      {
        shu=FrameData[2*r+1+32*k];
              LCMView();
              lei++;
            }
            ye=l+0x01;
            lei=0x70;
            for(r=0;r<16;r++)
      { 
        shu=FrameData[2*r+32*k];
              LCMView();
              lei++;
            }
        }
  while(1)
  {
    while(X2==0)      //调节X轴
    {
      while(X2==0);
      Xaxis = Xaxis + 1;
    }
    while(X1==0)
    {
      while(X1==0);
      if(Xaxis!=0) 
      {
        Xaxis = Xaxis - 1;
      }
    }
    while(Y1==0)     //调节Y轴
    {
      while(Y1==0);
      Yaxis = Yaxis + 1;
    }
    while(Y2==0)
    {
      while(Y2==0);
      if(Yaxis!=1) 
      {
        Yaxis=Yaxis-1;
      }
    }
    for(j=0;j<90;j++) //AD采样最大值
    {
      ADCChage();
      ADViewdata[j]=ADdata;
      if(ADViewdata[j]>ADViewdata[91])
      {
        ADViewdata[91]=ADViewdata[j];
      }
      Delay50us(Xaxis);
    }
    while(ADdata!=ADViewdata[91])    //如果采集值不相等,则继续
    {
      ADCChage();
    }
    for(j=0;j<90;j++)      //连续采样90次
    {
       ADCChage();
       ADViewdata[j]=ADdata; 
       Delay50us(Xaxis);
    }
    lei=0x41;
    for(r=0,j=0;r<90;r++,j++)
          {
             if(j<63)
      { 
        Ldata=1;
      }
            if(j==63)
      { 
        lei=0x40;
      }
            if(j>=63)
      {
        Ldata=2;
      }
            RefreshLCM();     //刷新当前显示
            if(ADViewdata[j>=127])//正电压
            {                             
        ADdata=(ADViewdata[j]-127)*0.196/Yaxis;  //计算电压值
        if(ADdata<=7)       
        {
          ye=0xbb;
          shu=(0x80>>ADdata);
        }
              else if(ADdata<=15) 
        {
          ye=0xba;
          shu=(0x80>>(ADdata-8));
        }
        else if(ADdata<=23)
        {
          ye=0xb9;
          shu=(0x80>>(ADdata-16));
         }
        else if(ADdata<=31) 
        {
          ye=0xb9;
          shu=(0x80>>(ADdata-24));
        }
            }
            if(ADViewdata[j]<127)     //负电压
            {
                ADdata=(127-ADViewdata[j])*0.196/Yaxis;    //计算电压值
          if(ADdata<=7)
          {
              ye=0xbc;
              shu=(0x01<<(ADdata));
          }
          else if(ADdata<=15)
          {
              ye=0xbd;
              shu=(0x01<<(ADdata-8));
          }
          else if(ADdata<=23) 
          {
              ye=0xbe;
              shu=(0x01<<(ADdata-16));
          }
                else if(ADdata<=31)
          {
              ye=0xbe;
              shu=(0x01<<(ADdata-24));
          }
            }
      if(r==0)//判断正负
            {
              d1=shu;
              d2=ye;
             }
             if(r!=0)
            {
              d3=shu;
              d4=ye;
              if(ye==d2)  //如果相等,则判断是否显示完成
              {
                if(shu>d1)
                {
                  d5=shu;
                  d5=d5>>1;
                  while(d5!=d1)
                  {
              d5=d5>>1;
                    shu=shu|(shu>>1);
            }
                }
                if(shu                {
                  d5=shu;
                  d5=d5<<1;
                  while(d5!=d1)
                 {
              d5=d5<<1;
              shu=shu|(shu<<1);
           } 
                }
              }
        if(ye              {  
                for(q=0;q<7;q++) 
                {
                        shu=shu|(shu<<1);
                      } 
                    LCMView();
                     ye++;
                    while(ye        {
          shu=0xff;
          LCMView();
          ye++;
        }
                    if(ye==d2)
        {
                        shu=0x01;
                                          if(shu                  {
                    d5=shu;
                    d5=d5<<1;
                    while(d5!=d1)
                    {
                d5=d5<<1;
                shu=shu|(shu<<1);
               } 
                   }
                                          }
        }
              if(ye>d2)
              {
                for(q=0;q<7;q++) 
                {
                        shu=shu|(shu>>1);
                      }
                    LCMView();
                     ye--;
                    while(ye>d2) {shu=0xff,LCMView(),ye--;}
                    if(ye==d2)
        {
                        shu=0x80;
                                          if(shu>d1)
                  {
                    d5=shu;
                    d5=d5>>1;
                    while(d5!=d1)
                    {
                d5=d5>>1;
                shu=shu|(shu>>1);
               } 
                   }
                                } 
      }
          }
          if(r!=0)
          {
            d1=d3;
            d2=d4;
          }
    LCMView();
    if(lei!=0x7f)
    {
      lei++;
    }
   }
        }
}

[1] [1]
关键字:单片机  LCD12864  数字示波器  Proteus仿真 引用地址:单片机+LCD12864数字示波器程序+Proteus仿真

上一篇:单片机驱动TEA5767 FM立体声收音机C51通用源码
下一篇:单片机PWM+红外对管控制直流电机设计

推荐阅读最新更新时间:2024-11-13 10:10

使用单片机3个IO口+74HC595驱动驱动控制LCD1602液晶
此内容有一定的深度,初学者不建议看。 最近一直在研究数码管驱动芯片 74HC595 ,发现一件很好玩的事情,那就是 用74HC595做驱动调试程序时,发现它只能输出,不能输入。 查找大量资料,从某个网友制作的mylib.c(NES)中获得了一条指令: #define bin(_a,_b,_c,_d,_e,_f,_g,_h) ((_a) 7|(_b) 6|(_c) 5|(_d) 4|(_e) 3|(_f) 2|(_g) 1|(_h)) 分别是8 7 6 5 4 3 2 1位 我就想既然情况是这样的,那么能不能完全用74595来控制整个1602呢?于是…就有个下面这个有趣的过程了 废话不多说,先上电路系统仿
[单片机]
使用<font color='red'>单片机</font>3个IO口+74HC595驱动驱动控制LCD1602液晶
单片机中使用DS18B20温度传感器C语言程序(参考4)
#include AT89X52.H #include intrins.h sbit DQ = P2^2; //定义DS18B20端口DQ sbit BEEP=P2^3 ; //定义报警接口 unsigned char presence ; //定义传感器初始化标志 unsigned char code LEDData = {0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F,0xff}; unsigned char data temp_data = {0x00,0x00}; //存储零时值 unsigned char data display = {
[单片机]
基于51单片机的语音万年历设计
一.硬件方案 本电路是由AT89C52单片机为控制核心,具有在线程功能,低功耗,能在3V超低压工作;时钟电路有DS1302提供,它是一种高性能.低功耗,带RAM的实时时钟电路,它可以对年,月,日,周日,时,分,秒进行及时,同时具有闰年补偿功能,工作电压为2.5~5.5V.采用三线接口与CPU进行同步通信,并可采用突发方式一次产送多个字节的时钟信号或RAM数据.具有寿命长精度高和低功耗等特点.温度数据有DS18B20采集.显示部分有LCD12864液晶显示。 主要由51单片机+最小系统+LCD12864液晶显示模块+时钟模块+温度采集模块+按键模块+语音芯片及喇叭;如图: 二.设计功能 (1)采用DS1302时钟芯片、DS1
[单片机]
基于51<font color='red'>单片机</font>的语音万年历设计
51单片机开发之中断
4.2 中断 4.2.1 中断介绍 中断系统是为使CPU具有对外界紧急事件的实时处理能力而设置的。 当中央处理机CPU正在处理某件事的时候外界发生了紧急事件请求,要求CPU暂停当前的工作,转而去处理这个紧急事件,处理完完后,再回到原来被中断的地方,继续原来的工作,这样的过程称为中断,实现这种功的部件称为中断系统,请示CPU中断的请求源称为中断源。 微型机的中断系统一般允许多个中断源,当几个中断源同时向CPU请求中断,要求为它服务的时候,这就存在CPU优先响应哪一个中断源请求的问题。通常根据中断源的轻重缓急排队,优先处理最紧急事件的中断请求源,即规定每一个中断源有一个优先级别,CPU总是先响应优先级别最高的中断请求。 当CP
[单片机]
51<font color='red'>单片机</font>开发之中断
STM32独立看门狗介绍_STM32单片机独立看门狗实验
  STM32独立看门狗简介   单片机系统在外界的干扰下会出现程序跑飞的现象导致出现死循环,看门狗电路就是为了避免这种情况的发生。看门狗的作用就是在一定时间内(通过定时计数器实现)没有接收喂狗信号(表示MCU已经挂了),便实现处理器的自动复位重启(发送复位信号)。   STM32的独立看门狗由内部专门的40Khz低速时钟驱动,即使主时钟发生故障,它也仍然有效。这里需要注意独立看门狗的时钟是一个内部RC时钟,所以并不是准确的40Khz,而是在30~60Khz之间的一个可变化的时钟,只是我们在估算的时候,以40Khz的频率来计算,看门狗对时间的要求不是很精确,所以,时钟有些偏差,都是可以接受的。   涉及的寄存器有:键寄存器
[单片机]
Microchip推出集成多个16位PWM的单片机
Microchip推出集成3个高分辨率16位PWM的8引脚封装新器件不断扩展8位PIC®单片机产品组合 全新PIC单片机集成16位PWM和通信,小尺寸实现精确驱动      全球领先的整合单片机、混合信号、模拟器件和闪存专利解决方案的供应商——Microchip Technology Inc.(美国微芯科技公司)在近日举办的2014嵌入式世界国际展览会(Embedded World)上宣布推出全新的PIC12(L)F157X系列产品,以扩展其8位PIC®单片机(MCU)产品组合。新器件的一大特点是在8引脚封装内集成了多个16位PWM以及各种模拟外设和串行通信。该单片机系列提供了三个带独立定时器的功能齐全的16位PWM
[单片机]
Microchip推出集成多个16位PWM的<font color='red'>单片机</font>
PIC 单片机应用问答14 篇
1 PIC 单片机振荡电路中如何选择晶体 对于一个高可靠性的系统设计,晶体的选择非常重要。尤其设计带有睡眠唤醒(往往用低电压以求低功耗)的系统。这是因为低供电电压使提供给晶体的激励功率减少,造成晶体起振很慢或根本就不能起振。这一现象在上电复位时并不特别明显,原因是上电时电路有足够的扰动很容易建立振荡;在睡眠唤醒时,电路的扰动要比上电时小得多,起振变得很不容易。在振荡回路中晶体既不能过激励(容易振到高次谐波上)也不能欠激励(不容易起振)。晶体的选择至少必须考虑谐振频点、负载电容、激励功、率温度特性、长期稳定性 2 如何判断电路中晶振是否被过分驱动? 电阻RS 常用来防止晶振被过分驱动。过分驱动晶振会渐渐损耗减少晶振的接触电镀,这将
[单片机]
用Proteus学习51单片机之串口
串口的理论知识我就不记了,网上多的是。51单片机的串口,有4种方式,分别为方式0,方式1,方式2,方式3.由于我的目的,使用串口主要是为了和电脑进行通信,所以主要使用方式1(事实上我也只学了方式1,其他方式等用到的时候再学吧)。 串口的方式1,其波特率与定时器T1相关,公式如下: 方式1波特率 = (2SMOD×32)/(T1溢出率) SMOD是一个寄存器,一般我们就取0了 T1的溢出率,即每秒T1计数满几次(相关知识可以看看前面笔记的记录) 正是因为如上的公式,所以设置TH1和TL1的初值,就能控制方式1的波特率了。不过一般波特率是固定的那么几种,像2400,4800和9600等,要用的时候查一下初值就成了。 由于用的是Prot
[单片机]
用Proteus学习51<font color='red'>单片机</font>之串口
小广播
设计资源 培训 开发板 精华推荐

最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

换一换 更多 相关热搜器件
更多往期活动

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved