zoukankan      html  css  js  c++  java
  • 进阶新的阶段--LCD

      lcd终于可以装上逼格满满的屏幕,满心欢喜,结果开始就大面积黑屏,原来是部分新的板子烧写了旧的superboot,重新烧写新的之后问题解决。

      lcd的显示原理是由点到线,线到面不断扫描的原理,具体设计到的上下左右边距的时序相关资料有,这里就不再赘述了。这里要说的是相关配置的思路,

      首先要使寄存器工作,当然是看lcd与芯片的硬件接口了,配置相关的引脚,

      其次,lcd通过接口与芯片相连之后,当然是要配置lcd的控制器寄存器、时序的控制寄存器、窗口的控制寄存器,一定要区分这三者的区别,区分好之后只要一步步配置就会发现让lcd简单的工作起来并不似那么复杂

      最后,配置窗口的上下左右边距和图片的尺寸大小,还有要指明图片缓存去的地址,这个是指定的,最后 使能channel 0传输数据

       相关代码如下,相关寄存器就不贴出来了,芯片手册很容易找到,这里只放重点

    void  lcd_init(void)
    {
    // 配置引脚用于LCD功能
    GPF0CON = 0x22222222; //4 //4--7
    GPF1CON = 0x22222222; // 0 --7
    GPF2CON = 0x22222222; // 0--7
    GPF3CON = 0x22222222; //0--3

    // 打开背光
    GPD0CON &= ~(0xf<<4);
    GPD0CON |= (1<<4); //输出模式??? (1<<5)

    GPD0DAT |= (1<<1); //????输出高电平,打开背光

    // 10: RGB=FIMD I80=FIMD ITU=FIMD 设置数据输出路径
    DISPLAY_CONTROL = 2<<0;

    // bit[26~28]:使用RGB接口 000
    // bit[18]:RGB 并行 0
    // bit[2]:选择时钟源为HCLK_DSYS=166MHz 0
    VIDCON0 &= ~( (3<<26)|(1<<18)|(1<<2) );

    // bit[1]:使能lcd控制器
    // bit[0]:当前帧结束后使能lcd控制器
    VIDCON0 |= ( (1<<0)|(1<<1) );

    // bit[4]:选择需要分频
    // bit[6~13]:分频系数为15 ???,即VCLK = 166M/(14+1) = 11M
    VIDCON0 |= 5<<6 | 1<<4;


    // H43-HSD043I9W1.pdf(p13) 时序图:VSYNC和HSYNC都是低脉冲
    // s5pv210芯片手册(p1207) 时序图:VSYNC和HSYNC都是高脉冲有效,所以需要反转
    VIDCON1 |= 1<<5 | 1<<6;

    // 设置时序p1207 p13
    VIDTCON0 = VBPD<<16 | VFPD<<8 | VSPW<<0;
    VIDTCON1 = HBPD<<16 | HFPD<<8 | HSPW<<0;
    // 设置长宽
    VIDTCON2 = (LINEVAL << 11) | (HOZVAL << 0);

    // 设置windows 0
    // bit[0]:使能 1
    // bit[2~5]:24bpp 1011
    WINCON0 |= 1<<0;
    WINCON0 &= ~(0xf << 2); //清2--5
    WINCON0 |= (0xB<<2) | (1<<15); // 24 位

    #define LeftTopX 0
    #define LeftTopY 0
    #define RightBotX 799
    #define RightBotY 479

    // 设置windows1的上下左右
    VIDOSD0A = (LeftTopX<<11) | (LeftTopY << 0);
    VIDOSD0B = (RightBotX<<11) | (RightBotY << 0);
    //the Window Size
    VIDOSD0C = (LINEVAL + 1) * (HOZVAL + 1);


    // 设置fb的地址
    VIDW00ADD0B0 = FB_ADDR;
    VIDW00ADD1B0 = (((HOZVAL + 1)*4 + 0) * (LINEVAL + 1)) & (0xffffff);//长度

    // 使能channel 0传输数据
    SHADOWCON = 0x1;
    }

     

    lcd配置完成就可以开始工作了,然后就可以优雅的画图了哈哈

    // 画图
    void lcd_draw_bmp(const unsigned char gImage_bmp[])
    {
      int i, j;
      unsigned char *p = (unsigned char *)gImage_bmp;
      int blue, green, red;
      int color;
      // 图片大小480x270像素
      for (i = 0; i < 480; i++)
      for (j = 0; j < 800; j++)
      {
        blue = *p++;
        green = *p++;
        red = *p++;

        color = red << 16 | green << 8 | blue << 0;
        lcd_draw_pixel(i, j, color);
      }
    }

    // 清屏 清屏会产生黑屏(0x0),所以后面做打地鼠的时候把清屏关掉
    void lcd_clear_screen(int color)
    {
      int i, j;

      for (i = 0; i < ROW; i++)
        for (j = 0; j < COL; j++)
          lcd_draw_pixel(i, j, color);

    }

    下面相关形状的画法

     

    // 描点
    void lcd_draw_pixel(int row, int col, int color)
    {
      unsigned long * pixel = (unsigned long *)FB_ADDR;

      *(pixel + row * COL + col) = color;

    }

    // 划横线
    void lcd_draw_hline(int row, int col1, int col2, int color)
    {
      int j;

      // 描第row行,第j列
      for (j = col1; j <= col2; j++)
      lcd_draw_pixel(row, j, color);

    }

    // 划竖线
    void lcd_draw_vline(int col, int row1, int row2, int color)
    {
      int i;
      // 描第i行,第col列
      for (i = row1; i <= row2; i++)
      lcd_draw_pixel(i, col, color);

    }

    // 划十字
    void lcd_draw_cross(int row, int col, int halflen, int color)
    {
      lcd_draw_hline(row, col-halflen, col+halflen, color);
      lcd_draw_vline(col, row-halflen, row+halflen, color);
    }

    // 画字符
    void lcd_draw_char(unsigned char c)
    {
      // 必须是静态变量
      static int x = 0; // 第几列
      static int y = 0; // 第几行

      int i,j;
      unsigned char line_dots;

      // 获得字模
      unsigned char *char_dots = (unsigned char *) (fontdata_8x16 + c * 16);


      // 是否需要回车换行
      if (c == ' ')
      {
        y += 16;
        if (y > ROW)
        y = 0;
        return ;
      }
      else if (c == ' ')
      {
        x = 0;
        return;
      }

      for (i = 0; i < 16; i++)
      {
        line_dots = char_dots[i];
        for (j = 0; j < 8; j++)
        {
          // 为1,则描蓝点
          if (line_dots & (0x80 >> j))
          {
            lcd_draw_pixel(y+i, x+j, 0xff);
          }  
      }
    }

    // 光标移动到下一个8*16的位置
    x += 8;
    if (x > COL)
    {
      x = 0;
      y += 16;
      if (y > ROW)
      y = 0;
    }
    }

     

     

     

  • 相关阅读:
    lodash源码分析之自减的两种形式
    lodash源码分析之NaN不是NaN
    lodash源码分析之Hash缓存
    lodash源码分析之compact中的遍历
    navigate15安装教程
    jmeter线程组调度器使用
    jmeter 注册选择文件编码格式有问题
    jmete插件下载
    jmeter linux 无gui模式分布式压测
    pycharm原码编辑界面快捷键
  • 原文地址:https://www.cnblogs.com/ygy1784717631/p/4823129.html
Copyright © 2011-2022 走看看