微波EDA网,见证研发工程师的成长!
首页 > 测试测量 > 测试测量技术文库 > 基于LCD12864显示器的数字示波器设计

基于LCD12864显示器的数字示波器设计

时间:09-10 来源:互联网 点击:

oid lcd12864_init(oid)


  {


  lcd_cmd_wr(DISPON,0); // 显示开启


  lcd_cmd_wr(DISPFIRST,0); // 设定显示首行地址,修改首行地址可以实现屏幕滚动显示效果


  lcd_cmd_wr(ORGY,0); // 设定初始光标


  lcd_cmd_wr(ORGX,0);


  lcd_cmd_wr(DISPON,1); // 初始另外一半


  lcd_cmd_wr(DISPFIRST,1);


  lcd_cmd_wr(ORGY,1);


  lcd_cmd_wr(ORG,1);


  lcd12864_clr(); // 执行清屏,非必须操作


  }

  该函数用来初始化LCD,设置显示模式,光标位置等,在对LCD 绘图时,最多的命令就是设定当前光标位置,通过光标位置来指定将要操作的LCD 显示点。


  在对LCD 编程操作以前,一定要执行此函数对LCD 进行初始化操作。


  从驱动函数可见,一次对LCD 写入数据是以字节为单位,通过写命令设定坐标,y 坐标从0 页到7 页,x 坐标从0 列到63 列,分左右屏,左上角为坐标(0,0)点,这和我们习惯的左下角为(0,0)坐标轴是不一样的。


  因为每次操作LCD 是一个字节为单位,对应8 点,如果我们希望以任意点为坐标显示,还得另外寻找别的办法编程实现真正“点”显示。


  如图3 所示,在屏幕上指定位置画点,水平轴就是x,与LCD 坐标一致,垂直轴需要将点坐标变成字节为单位的坐标,我们先按习惯将y 轴64 点从下至上编号0 到63,其中0 到7 点为字节0,8 到15 点为字节1,依此类推对应8 字节。


  



图3 LCD“点”显示示例

  第一点y 轴为30,应该对应垂直哪个字节的哪个比特呢?


  实际30 点应该在第4 字节(24 到31)的Bit 6 上,拿30/8 取整为3,刚好是应该跳过的前3 字节(对应0 到23),那么30%8(30 除8 取余数)呢,余数是6,不是刚好是Bit 位吗?所以可以这样将y 值映射到某字节的某点上,如果y 轴64 点对应8 字节变量Da[n],n从0 到7,则:


  da[y/8] = 1 《 (y%8);或da[y》3]=0x01《(y&0x07);后一种算法更优。


  通过总结规律,用以上算法可以将任意0 到63 之间的数据作为坐标描点到对应的8 个字节中,然后将8个字节全部写入LCD,则通过刚才算法就会有一点与所给坐标一致。


  第一点:da[30/8] = 1 《 30%8; 即da[3] = 0x40;


  第二点:da[10/8] = 1 《10%8; 即da[1] = 0x04;


  首先给出列显示子函数,在任意列显示y 值对应点。


  {


  unsigned char j;


  if(x<64) { // 根据列坐标选择左右半屏


  for(j=0;j<8;j++) { // 写左半屏


  lcd_cmd_wr(ORGY+j,0);


  lcd_cmd_wr(ORGX+x,0);


  lcd_data_wr(da[j],0);


  }


  }


  else {


  x-=64;// 坐标调整


  for(j=0;j<8;j++) { // 写右半屏


  lcd_cmd_wr(ORGY+j,1);


  lcd_cmd_wr(ORGX+x,1);


  lcd_data_wr(da[j],1);


  }


  }


  }


  有了列显示函数,LCD 任何坐标位置上描点绘图函数为:


  void lcd_disp(unsigned char x,y) //x 水平坐标,y 垂直坐标


  {


  unsigned char dat[8];


  unsigned char j;


  y=63-y;// 使xy 坐标符合习惯


  for(j=0;j<8;j++) dat[j] = 0x0;


  dat[y/8] |= 0x01《(y&0x07);


  lcd_row_wr(x,dat);


  }


  以上函数能够在指定坐标(x,y)上描点,下面尝试将ADC 的值采集后送LCD 显示。再按时间轴x 轴顺序将不同时刻采集到的y 值顺序写入LCD,这是我们就可以在LCD 上看到随时间变化的电压曲线了。主程序为:


  void main()


  {


  unsigned char i;


  LCD12864_init();


  for(i=0;i<128;i++) {


  lcd_disp(i,read_adc(0)/16);// 从10bit 映射到6bit,要除16


  }


  while(1);


  }


  调整输入给ADC 的信号频率,可以得到满意的波形图了,效果如图4 所示。


  



图4 LCD实时显示ADC图

  如果你成功做到了这一步,可喜可贺,已经掌握了绘图基础了,不过程序还要继续完善。


  三、图形液晶LCD12864绘图驱动设计提高


  如何在现实波形显示的基础上,同时将定标网格也显示出来呢?


  首先我们看一种C 语法“A = 0x05; A |= 0x50;”运行以上指令后,A = 0x55 ;也可以说第二个数据0x50 是叠加到第一个数据上的,我们可以用这种算法把需要显示的亮点(也就是“1”)按一定的算法叠加在一起,送LCD 显示,就出现了我们希望的在波形上增加背景网格的效果。


  因为网格与水平x 轴是严格关联的,所以我们可以对x 轴数据进行判断,有规律的将边框和背景格点加入。


  改进带背景格的lcd_disp() 函数。


  void lcd_disp(unsigned char x,unsigned char y)


  {


  unsigned char da[8];


  unsigned char j;


  y = 63-y;


  for(j=1;j<7;j++) da[j] = 0x0;


  da[0]=0x01;


  da[7]=0x80;


  if(x%5==0) {


  da[21/8] |= 0x01《(21%8);


  da[42/8] |= 0x01《(42%8);


  }


  if((x==0)||(x==127)) {// 加两端边框


  for(j=0;j<8;j++) da[j] = 0xff;


  }


  da[y/8] |= 0x01《(y%8);


  lcd_row_wr(x,da);


  }



Copyright © 2017-2020 微波EDA网 版权所有

网站地图

Top