1、本设计采用52单片机作为主控器。
2、单片机通过ADC0808读取信号发生器所产生的波形通过12864进行显示,可显示方波,三角波,锯齿波,正弦波等。
仿真原理图如下(proteus仿真工程文件可到本帖附件中下载)
单片机源程序如下:
- //proteus仿真论坛
- #include <reg51.h>
- #include <intrins.h>
- #include <ADC0808.c>
- sbit DI=P2^2; // 数据\指令 选择 AMPIRE12864 RS口
- sbit RW=P2^1; // 读\写 选择 R/W
- sbit E=P2^0; // 读\写使能 E
- sbit CS1=P2^4; // 片选1 CS1
- sbit CS2=P2^3; // 片选2 CS2
- sbit busy=P1^7; //DB7
- sbit jia=P3^7; //gg按键接地(x轴加调节)
- sbit jian=P3^3; // 按键接地 (x轴减调节)
- sbit jia1=P3^0; //按键接地 (y轴加调节)
- sbit jian1=P3^1; //按键接地 (y轴减调节)
- unsigned int i;
- unsigned char ye,lei,shu;
- unsigned char a[91];
- char code t[]={
-
-
- 0x00,0x00,0x08,0x00,0x04,0x00,0x02,0x00,0x01,0x80,0x40,0x60,0x80,0x00,0x7F,0xFF, //小
- 0x00,0x00,0x00,0x20,0x00,0x40,0x00,0x80,0x01,0x00,0x06,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x80,0x00,0x80,0x00,0x82,0x00,0x82,0x00,0x82,0x40,0x82,0x80,0x82,0x7F,0xE2, //子
- 0x00,0xA2,0x00,0x92,0x00,0x8A,0x00,0x86,0x00,0x80,0x00,0xC0,0x00,0x80,0x00,0x00,
-
- 0x00,0x40,0x00,0x60,0x3F,0x5E,0x01,0x48,0x01,0x48,0xFF,0xFF,0x11,0x48,0x21,0x4C, //制
- 0x1F,0x68,0x00,0x40,0x07,0xF8,0x40,0x00,0x80,0x00,0x7F,0xFF,0x00,0x00,0x00,0x00,
-
- 0x00,0x80,0x00,0x40,0x00,0x20,0xFF,0xF8,0x00,0x87,0x00,0x40,0x00,0x30,0x00,0x0F, //作
- 0xFF,0xF8,0x08,0x88,0x08,0x88,0x08,0xC8,0x0C,0x88,0x08,0x0C,0x00,0x08,0x00,0x00,
- }; //没看懂
-
- void checkstate() //检查控件选中状态,都能判断是否选中控件
- {
- DI=0; // 数据\指令 选择 AMPIRE12864 RS口
- RW=1; // 读\写 选择 R/W
- do
- {
- E=1;
- E=0;
- //仅当第7位为0时才可操作(判别busy信号)
- }while(busy==1);
- }
- void writecommand(unsigned char command) //写命令
- {
- checkstate();
- DI=0;//高电平:数据D0~D7将送入显示RAM;低电平D0~D7将送入指令寄存器执行
- RW=0;//高电平读数据,低电平写数据
- P1=command;
- E=1; //高电平有效,低电平锁定数据
- E=0;
- }
- void writedate(unsigned char date) //写数据
- {
- checkstate(); //忙检测
- DI=1;
- RW=0;
- P1=date;
- E=1;
- E=0;
- }
- void pianxuan(unsigned int i) //选择左右屏
- {
- if(i==1)
- CS1=0,CS2=1; //左屏
- if(i==2)
- CS1=1,CS2=0; //右屏
- if(i==3)
- CS1=0,CS2=0; //全屏
- }
- void shuju()
- {
- pianxuan(i); //选屏
- writecommand(ye); //写命令(页)
- writecommand(lei); //写命令列
- writedate(shu); //写数据
- }
- void cleanscreen() //清屏 ???
- {
- unsigned char page,i;
- pianxuan(3);
- for(page=0xb8;page<=0xbf;page++) //从0页到7页
- {
- writecommand(page);
- writecommand(0x40); //第0列
- for(i=0;i<64;i++) //0~63列
- writedate(0x00); //清0
-
- }
- pianxuan(1); //左屏
- lei=0x40; //第0列
- for(ye=0xb8;ye<0xbf;ye++) //从第0页到第七页
- {
- shu=0xff;
- shuju();
- }
- ye=0xb8;
- for(lei=0x40;lei<=0x7f;lei++)
- {
- shu=0x80;
- shuju(); //0x80
- }
- ye=0xbf;
- for(lei=0x40;lei<=0x7f;lei++)
- {
- shu=0x01;
- shuju();
- }
- pianxuan(2);
- ye=0xb8;
- for(lei=0x40;lei<=0x5b;lei++)
- {
- shu=0x80;
- shuju();
- }
- ye=0xbf;
- for(lei=0x40;lei<=0x5b;lei++)
- {
- shu=0x01;
- shuju();
- }
- lei=0x5b;
- for(ye=0xb9;ye<=0xbe;ye++)
- {
- shu=0xff;
- shuju();
- }
-
- }
- void init(void) //开显示,起始行0行
- {
- writecommand(0xc0); //开启显示0011 1111
- writecommand(0x3f); //设置起始行1100 0000 第0行
- }
- void delay_50us(uint t) //延时50us
- {
- uchar j;
- for(;t>0;t--)
- for(j=19;j>0;j--);
- }
-
- void qing() //清掉七页
- {
- uchar i;
- for(i=0xb9;i<=0xbe;i++) //第二页到第六页
- {
- ye=i;
- shu=0x00;
- shuju();
- }
- }
- void main()
- {
-
-
- uint r,j,g=0,q,dianya=1,k,p; //定义无符号整型
- uchar m,l; //定义字符型m l
- //pianxuan(3);
- cleanscreen(); //清屏
- init(); //开启显示
- pianxuan(2); //选右屏
- l=0xb8; //选第0页l 1011 1000
- for(k=0;k<4;k++,l=l+0x02) //l跳两页加页,0页跳2页,跳4页,跳6页
- {
- ye=l;
- lei=0x70; // 0111 0000 右屏第47列
- for(r=0;r<16;r++) // 跳着填数据,第0页从t{}中每跳2个写数据(右屏47~63列)
- {
- shu=t[2*r+1+32*k];
- shuju();
- lei++;
- }
- ye=l+0x01; //当前页加1页
- lei=0x70; //第47列
- for(r=0;r<16;r++) // 跳着填数据,第0页从t{}中每跳2个写数据(右屏47~63列)
- {
- shu=t[2*r+32*k];
- shuju();
- lei++;
- }
- }
- /*void shuju()
- {
- pianxuan(i); //选屏
- writecommand(ye); //写命令(页)
- writecommand(lei); //写命令列
- writedate(shu); //写数据
- }*/
- while(1)
- {
- uchar d1,d2,d3,d4,d5,d6;
- while(jia==0)
- {
- while(jia==0); //空函数保持当前状态
- g=g+1; //g=1
- }
- while(jian==0)
- {
- while(jian==0);
- if(g!=0) g=g-1; //让g=0
- }
- while(jia1==0)
- {
- while(jia1==0);
- dianya=dianya+1; //电压变0??
- }
- while(jian1==0)
- {
- while(jian1==0);
- if(dianya!=1) dianya=dianya-1; //电压变1
- }
- for(j=0;j<90;j++) //AD采样最大值
- {
- adc();
- a[j]=AD; //存储数字量
- if(a[j]>a[91])
- {
- a[91]=a[j]; //最大量放最后
- }
- delay_50us(g);
- }
-
- while(AD!=a[91]) //判断AD是否与最大值相等
- {
- adc();
- }
- for(j=0;j<90;j++) //AD采样
- {
- adc(); //采样90个
- a[j]=AD;
- delay_50us(g);
- }
- lei=0x41; //第一列
- for(r=0,j=0;r<90;r++,j++)
- {
- if(j<63) i=1; //选屏
- if(j==63) lei=0x40; //j:列 i:屏(左右) 页:l
- if(j>=63)i=2;
- qing(); //清7页
- if(a[j>=127])//正电压 ??????
- {
- AD=(a[j]-127)*0.196/dianya; //计算在12864的电压值 郑学长?
- if(AD<=7) ye=0xbb,shu=(0x80>>AD);
- else if(AD<=15) ye=0xba,shu=(0x80>>(AD-8));
- else if(AD<=23) ye=0xb9,shu=(0x80>>(AD-16));
- else if(AD<=31) ye=0xb9,shu=(0x80>>(AD-24));
- }
- if(a[j]<127)//负电压
- {
- AD=(127-a[j])*0.196/dianya;
- if(AD<=7) ye=0xbc,shu=(0x01<<(AD));
- else if(AD<=15) ye=0xbd,shu=(0x01<<(AD-8));
- else if(AD<=23) ye=0xbe,shu=(0x01<<(AD-16));
- else if(AD<=31) ye=0xbe,shu=(0x01<<(AD-24));
- }
- if(r==0) //第一次循环把shu给d1,ye给d2
- {
- d1=shu; //shu是t{}里面。
- d2=ye; //最后一页
- }
- if(r!=0) //除了第一次循环外
- {
- d3=shu;
- d4=ye;
- if(ye==d2) //判断d2与d4是否相等(是否在同一页)
- {
- if(shu>d1) //把shu向右移 趋近d1
- {
- d5=shu;
- d5=d5>>1;
- while(d5!=d1)
- {d5=d5>>1;shu=shu|(shu>>1);}
- }
- if(shu<d1)
- {
- 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);
- }
- shuju();
- ye++;
- while(ye<d2) {shu=0xff,shuju(),ye++;}
- if(ye==d2)
- {
- shu=0x01;
- if(shu<d1)
- {
- d5=shu;
- d5=d5<<1;
- while(d5!=d1)
- {d5=d5<<1;shu=shu|(shu<<1);}
- }
- ……………………
- …………限于本文篇幅 余下代码请从51黑下载附件…………
复制代码
仿真程序51hei附件下载:
简易示波器修改版.7z
(105.68 KB, 下载次数: 57)
|