查看: 494|回复: 5

[原创] RGB点阵屏驱动显示全彩图片方法

[复制链接]

11

主题

0

好友

574

积分

举人

Rank: 4

  • TA的每日心情
    奋斗
    2016-11-16 21:14
  • 签到天数: 77 天

    [LV.6]常住居民II

    发表于 2016-5-23 17:09:26 |显示全部楼层
    本帖最后由 geek1024 于 2016-5-23 17:22 编辑

    在去年写过的一篇帖子:STM32f103实战之驱动32*32 RGB点阵 中介绍了下RGB 点阵屏显示的方法。但是在上一篇帖子中明明标题是RGB点阵,可是为嘛没看到有RGB显示的方法,因为方法在本文中经行补充。
    此次项目我是参考了很多大大们写过的资料后,用了不到2个月时间重写程序,包括底层驱动,上层画图库,显示ASCII字符,显示中文字符等函数。
    RGB点阵屏接口是标准08接口:


    接口连线(部分定义,详细见工程matrix_config.h中定义)
    1. #define MTX_PORT      
    2. #define MTX_PORTc GPIOC  
    3. #define MTX_RCCPB   RCC_APB2Periph_GPIOB  
    4.   
    5. #define MTX_PR0     GPIO_Pin_0   //GPIOC  
    6. #define MTX_PG0     GPIO_Pin_11  //GPIOB  
    7. #define MTX_PB0     GPIO_Pin_1   //GPIOC  
    8.   
    9. #define MTX_PR1     GPIO_Pin_2   //GPIOC  
    10. #define MTX_PG1     GPIO_Pin_12  //GPIOB  
    11. #define MTX_PB1     GPIO_Pin_3   //GPIOC  
    12.   
    13. #define MTX_PA      GPIO_Pin_4   //GPIOC  
    14. #define MTX_PB      GPIO_Pin_6   //GPIOC  
    15. #define MTX_PC      GPIO_Pin_5   //GPIOC  
    16.   
    17. #define MTX_PSTB    GPIO_Pin_13  //GPIOB  
    18. #define MTX_POE     GPIO_Pin_7   //GPIOC  
    19. #define MTX_PCLK    GPIO_Pin_10  //GPIOB  
    复制代码
    屏幕我是采用2块 16*32 RGB点阵,采用级联方式连接。

    扫描方式是8/1 扫描,就是说R0 G0 B0 对应的是上面0-7 的数据 R1 G1 B1 对应下面0-7 的数据,单块屏幕分辨率32*16 ,级联2块构成32*32 RGB 点阵屏。

    点阵要显示灰度,有两种方式,第一采用硬PWM芯片驱动,如TLC5941 芯片,可以硬件产生pwm 感兴趣的去看手册,我在此不解释,另一种是比较常用的是采用恒流芯片,类似74hc138 不同的是驱动全彩屏用的是恒流芯片驱动。而一般单色双色屏采用的是74hc138+595 由于全彩屏亮度高,耗电量也高,并且刷新速度快,导致行驱动多采用MOS管驱动,这就是屏幕驱动的区别。而驱动芯片也采用高速FPGA 或 CPLD 的驱动方式。RGB点阵灰度显示:每个点点亮不同时间会显示不同亮度,玩过PWM 的童鞋应该明白吧,50% 的占空比就是显示 一遍的亮度。
    定义一个不同占空比数组

    int waits[] = {10,20,40,80,160,320,640,1280};//显示不同占空比,就能显示不同灰度,你以为就这一个函数就够了吗?  NO NO NO 这只是整屏一个灰度显示函数
    1. int waits[] = {10,20,40,80,160,320,640,1280};  
    2. /**
    3. * latches / shows a line and waits for n amount of time.
    4. */  
    5. void showLine(int amount) {  
    6.     int c = 0;  
    7.   STROBE;  
    8.   DISP_ON;  
    9.   for (c=0; c<amount; c++) //asm("nop");  
    10.   DISP_OFF;  
    11. }  
    复制代码
    上面函数我稍微说下: 每次刷新一屏数据。 一屏幕又被刷新8次,但是这8次刷新中,占空比不同,占空比依次递减。最终调用此函数,就刷一屏数据。下面上面函数放进定时器里,就不用管了。 但是要定义一个 3byte * 1024 的空间 这是显示缓存,要显示的数据就存在此数组中。好在stm32 ram 有20k,32*32 点阵 都要占3Kb RAM, 看来刷RGB 真是很占系统资源的。

    下面底层函数搞定,剩下就是移植上层函数。参考2 Adafruit 已经开源了一个画图基础库,直接偷过来移植,移植很容易他的库是C++ 只要把变量定义稍稍修改,就能用。函数中包括画点 画线 画矩形 填充矩形 画三角形 填充三角形 画圆 填充圆 等  具体用法:

    1. void drawPixel(s8,s8,u32);  
    2.   
    3. void drawLine(s8,s8,s8,s8,u32);  
    4.   
    5. void drawFastVLine(s8, s8, s8, u32);  
    6.   
    7. void drawFastHLine(s8, s8, s8, u32);  
    8.   
    9. void drawRect(s8, s8, s8, s8, u32);  
    10.   
    11. void fillRect(s8 x, s8 y ,s8 w, s8 h, u32 Color);  
    12.   
    13. void fillScreen(u32 Color);  
    14.   
    15. void drawCircle(s8 x0, s8 y0, s8 r, u32 Color);  
    16.   
    17. void drawCircleHelper(s8 x0, s8 y0, s8 r, s8 cornername,    u32 Color);  
    18.   
    19. void fillCircleHelper(s8 x0, s8 y0, s8 r, s8 cornername,    s8 delta, u32 Color);  
    20.   
    21. void fillCircle(s8 x0, s8 y0, s8 r, u32 color);  
    22.   
    23. void drawTriangle(s8 x0, s8 y0, s8 x1, s8 y1,   s8 x2, s8 y2, u32 Color);  
    24.   
    25. void fillTriangle(s8 x0, s8 y0, s8 x1, s8 y1, s8 x2, s8 y2, u32 Color);  
    26.   
    27. void drawRoundRect(s8 x0, s8 y0, s8 w, s8 h,    s8 radius, u32 Color);  
    28.   
    29. void fillRoundRect(s8 x0, s8 y0, s8 w, s8 h,    s8 radius, u32 Color);  
    30.   
    31. void ClearBuff(u16 num1, u16 num2);  
    32.   
    33. void fillScreen(u32 Color);  
    复制代码

    画一个点:

    1. drawPixel(0, 0, Color888(255, 255, 255));
    复制代码

    填充一个矩形:

    1. fillRect(0, 0, 32, 32, Color888(0, 255, 0));
    复制代码

    画一个矩形:

    1. drawRect(0, 0, 32, 32, Color888(255, 255, 0));
    复制代码

    画线:

    1. // draw an 'X' in red  
    2. drawLine(0, 0, 31, 15, Color888(255, 0, 0));  
    3. drawLine(31, 0, 0, 15, Color888(255, 0, 0));
    复制代码

    显示ASCII 字符: (目前支持4种字体)

    1. setFont(font5x7);  
    2. drawString(2,0,COLOR_GREEN,"Select");  
    3. drawString(6,7,0x0000fffa,"Mode");  
    4. setFont(font3x5);  
    5. drawString(3,14,0x0000fffa,"< use >");  
    复制代码
    还支持滚动显示字符:
    setScrollSpeed(25);setScrollFont(font3x5);setScrollColor(COLOR_BLUE);scrollText("Hello World!!!", 1);
    还能显示中文,点阵屏内有一块 w25Q16 spi flash 。 内部前700Kb 存放 中文字库,支持显示 GBK 字符集 所以要显示中文很容易了:
    1. draw_hanzi( 0, 0,0x00ffffff,"天");
    2. draw_hanzi(16, 0,0x00ffffff,"宇");
    复制代码



    参考资料:

    1. 底层函数参考:Github  STM32RGBMatrixDriver
      

    2. 上层画图库   :adafruit/RGB-matrix-Panel

    3. 参考资料3    : The Light Appliance Page

    4.灰度显示资料 :LED点阵屏显示原理

    5.Adafruit 函数 :Library

    6.汉字字符显示参考: (1)gbk字符集编码 (2)GBK内码查询


    程序下载:
    游客,如果您要查看本帖隐藏内容请回复



    回复

    使用道具 举报

    11

    主题

    0

    好友

    574

    积分

    举人

    Rank: 4

  • TA的每日心情
    奋斗
    2016-11-16 21:14
  • 签到天数: 77 天

    [LV.6]常住居民II

    发表于 2016-5-23 17:20:08 |显示全部楼层
    沙发自己的
    回复

    使用道具 举报

    0

    主题

    0

    好友

    55

    积分

    童生

    Rank: 2

  • TA的每日心情
    开心
    2016-6-13 14:17
  • 签到天数: 5 天

    [LV.2]偶尔看看I

    发表于 2016-5-23 22:38:51 |显示全部楼层
    本帖最后由 mcza30 于 2016-5-23 22:43 编辑

    谢谢楼主分享,下载学习
    -----进不了网页
    回复

    使用道具 举报

    1

    主题

    1

    好友

    2683

    积分

    进士

    Rank: 5Rank: 5

  • TA的每日心情
    奋斗
    昨天 23:06
  • 签到天数: 645 天

    [LV.9]以坛为家II

    发表于 2016-5-23 22:43:51 |显示全部楼层
    写的好,编的好,学习了
    回复

    使用道具 举报

    0

    主题

    0

    好友

    4

    积分

    白丁

    Rank: 1

    该用户从未签到

    发表于 2016-9-9 13:50:17 |显示全部楼层
    好资料,谢谢分享!!
    回复

    使用道具 举报

    0

    主题

    0

    好友

    13

    积分

    白丁

    Rank: 1

    该用户从未签到

    发表于 2016-10-8 10:15:38 |显示全部楼层
    谢谢分享。。。。。
    回复

    使用道具 举报

    您需要登录后才可以回帖 登录 | 立即注册

    关闭

    站长推荐上一条 /5 下一条


    手机版|爱板网 |网站地图  

    GMT+8, 2016-12-9 13:46 , Processed in 0.170206 second(s), 13 queries , Memcache On.

    苏公网安备 32059002001056号

    Powered by Discuz!

    回顶部