STM32 RGB点阵屏故事 下
来源:互联网 发布:思科网络技术学院答案 编辑:程序博客网 时间:2024/05/22 03:12
在去年写过的一篇帖子:STM32f103实战之驱动32*32 RGB点阵 中介绍了下RGB 点阵屏显示的方法。但是在上一篇帖子中明明标题是RGB点阵,可是为嘛没看到有RGB显示的方法,因为方法在本文中经行补充。此次项目用了不到2个月时间重写程序,包括底层驱动,上层画图库,显示ASCII字符,显示中文字符等函数。
RGB点阵屏接口是标准08接口:
接口连线(部分定义,详细见工程matrix_config.h中定义)
#define MTX_PORT#define MTX_PORTc GPIOC#define MTX_RCCPBRCC_APB2Periph_GPIOB#define MTX_PR0GPIO_Pin_0 //GPIOC#define MTX_PG0GPIO_Pin_11 //GPIOB#define MTX_PB0GPIO_Pin_1 //GPIOC#define MTX_PR1GPIO_Pin_2 //GPIOC#define MTX_PG1GPIO_Pin_12 //GPIOB#define MTX_PB1GPIO_Pin_3 //GPIOC#define MTX_PAGPIO_Pin_4 //GPIOC#define MTX_PBGPIO_Pin_6 //GPIOC#define MTX_PCGPIO_Pin_5 //GPIOC#define MTX_PSTBGPIO_Pin_13 //GPIOB#define MTX_POEGPIO_Pin_7 //GPIOC#define MTX_PCLKGPIO_Pin_10 //GPIOB
扫描方式是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 这只是整屏一个灰度显示函数,
/** * latches / shows a line and waits for n amount of time. */void showLine(int amount) {int c = 0; STROBE; DISP_ON; for (c=0; c<amount; c++)="" asm("nop");="" disp_off;="" }<="" pre=""><span style="line-height: 18px;"></span><p style="word-wrap: break-word; margin-top: 5px; margin-bottom: 5px; line-height: 18px;"></p><span style="line-height: 18px;">真正显示PWM函数:</span><p style="word-wrap: break-word; margin-top: 5px; margin-bottom: 5px; line-height: 18px;"></p><p style="word-wrap: break-word; margin-top: 5px; margin-bottom: 5px; line-height: 18px;"></p><span style="line-height: 18px;"></span><pre name="code" class="c" style="line-height: 18px;">void display_PWM(void) {u8 s;u8 plane;u8 Display_Cache[64][3];u8 Display_Cache1[64][3];#if(MATRIX_WIDTH == 32)for(plane = 0; plane < scan; plane ++) //ÐÐɨÃè { setRow(s); Send_RGB_Module(plane,0); showLine(waits[1]); } #else //GPIO6_LOW; for(plane = 0; plane < scan; plane ++) //ÐÐɨÃè ɨÃè8ÐÐ { u8 num,a; for(a=0;a<32;a++){ Display_Cache[a][0]=Display_PWM[plane*32+a][0]; Display_Cache[a][1]=Display_PWM[plane*32+a][1]; Display_Cache[a][2]=Display_PWM[plane*32+a][2];} for(a=0;a<32;a++){ Display_Cache[a+32][0]=Display_PWM[plane*32+a+512][0]; Display_Cache[a+32][1]=Display_PWM[plane*32+a+512][1]; Display_Cache[a+32][2]=Display_PWM[plane*32+a+512][2];} for(a=0;a<32;a++){ Display_Cache1[a][0]=Display_PWM[plane*32+a+256][0]; Display_Cache1[a][1]=Display_PWM[plane*32+a+256][1]; Display_Cache1[a][2]=Display_PWM[plane*32+a+256][2];} for(a=0;a<32;a++){ Display_Cache1[a+32][0]=Display_PWM[plane*32+a+768][0]; Display_Cache1[a+32][1]=Display_PWM[plane*32+a+768][1]; Display_Cache1[a+32][2]=Display_PWM[plane*32+a+768][2];} setRow(plane); // ÐÐÑ¡Ôñ for(num=8;num>0;num--) //ÿһÐÐɨÃè8´Î {for(s = 0; s <2 /*= (MATRIX_WIDTH/32)*/; s ++) //ɨ2Ä£¿é 32*2 ¸öµã { for(a=0;a<matrix_module a="" 0="" 32="" if="" display_cache="" s="" 0x80="" mtx_portc-="">BSRR = MTX_PR0;elseMTX_PORTc->BRR = MTX_PR0; if((Display_Cache[s*32+a][1] & 0x80) == 0x80)MTX_PORT->BSRR = MTX_PG0;elseMTX_PORT->BRR = MTX_PG0;if((Display_Cache[s*32+a][2] & 0x80) == 0x80)MTX_PORTc->BSRR = MTX_PB0;elseMTX_PORTc->BRR = MTX_PB0;if((Display_Cache1[s*32+a][0] & 0x80) == 0x80)MTX_PORTc->BSRR = MTX_PR1;elseMTX_PORTc->BRR = MTX_PR1; if((Display_Cache1[s*32+a][1] & 0x80) == 0x80)MTX_PORT->BSRR = MTX_PG1;elseMTX_PORT->BRR = MTX_PG1;if((Display_Cache1[s*32+a][2] & 0x80) == 0x80)MTX_PORTc->BSRR = MTX_PB1;elseMTX_PORTc->BRR = MTX_PB1;CLK_TOGGLE}}for(a=0;a<64;a++) { Display_Cache[a][0] = Display_Cache[a][0] <<1; Display_Cache[a][1] = Display_Cache[a][1] <<1; Display_Cache[a][2] = Display_Cache[a][2] <<1; Display_Cache1[a][0] = Display_Cache1[a][0] <<1; Display_Cache1[a][1] = Display_Cache1[a][1] <<1; Display_Cache1[a][2] = Display_Cache1[a][2] <<1; } showLine(waits[num]); //8(5): 2.12 0.38 } } //GPIO6_HIGH; #endif } </matrix_module>
下面底层函数搞定,剩下就是移植上层函数。参考2 Adafruit 已经开源了一个画图基础库,直接偷过来移植,移植很容易他的库是C++ 只要把变量定义稍稍修改,就能用。函数中包括画点 画线 画矩形 填充矩形 画三角形 填充三角形 画圆 填充圆 等 具体用法:
void drawPixel(s8,s8,u32);void drawLine(s8,s8,s8,s8,u32);void drawFastVLine(s8, s8, s8, u32);void drawFastHLine(s8, s8, s8, u32);void drawRect(s8, s8, s8, s8, u32);void fillRect(s8 x, s8 y ,s8 w, s8 h, u32 Color);void fillScreen(u32 Color);void drawCircle(s8 x0, s8 y0, s8 r, u32 Color);void drawCircleHelper(s8 x0, s8 y0, s8 r, s8 cornername,u32 Color);void fillCircleHelper(s8 x0, s8 y0, s8 r, s8 cornername,s8 delta, u32 Color);void fillCircle(s8 x0, s8 y0, s8 r, u32 color);void drawTriangle(s8 x0, s8 y0, s8 x1, s8 y1,s8 x2, s8 y2, u32 Color);void fillTriangle(s8 x0, s8 y0, s8 x1, s8 y1, s8 x2, s8 y2, u32 Color);void drawRoundRect(s8 x0, s8 y0, s8 w, s8 h,s8 radius, u32 Color);void fillRoundRect(s8 x0, s8 y0, s8 w, s8 h,s8 radius, u32 Color);void ClearBuff(u16 num1, u16 num2);void fillScreen(u32 Color);
画一个点:
drawPixel(0, 0, Color888(255, 255, 255));
填充一个矩形:
fillRect(0, 0, 32, 32, Color888(0, 255, 0));
画一个矩形:
drawRect(0, 0, 32, 32, Color888(255, 255, 0));
画线:
// draw an 'X' in red drawLine(0, 0, 31, 15, Color888(255, 0, 0)); drawLine(31, 0, 0, 15, Color888(255, 0, 0));
显示ASCII 字符: (目前支持4种字体)
setFont(font5x7);drawString(2,0,COLOR_GREEN,"Select");drawString(6,7,0x0000fffa,"Mode");setFont(font3x5);drawString(3,14,0x0000fffa,"< use >");
setScrollSpeed(25);setScrollFont(font3x5);setScrollColor(COLOR_BLUE);scrollText("Hello World!!!", 1);
draw_hanzi( 0, 0,0x00ffffff,"天");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内码查询
- STM32 RGB点阵屏故事 下
- RGB 点阵
- STM32点阵
- 点阵屏
- stm32 rgb多彩led驱动
- 四极管 点阵屏控制 AVR 静态点阵
- DOS下的点阵汉字
- 16*16点阵屏
- 点阵屏接口大全
- 点阵
- STM32 控制74HC595 驱动点阵 文字能移动
- J2ME下的点阵字实现
- WINCE下点阵转化为位图
- LED点阵屏设计一
- 关于STM32驱动点阵的问题整理及科研思维小酌
- 16*16点阵上下左右滚屏显示
- 制作大型LED广告点阵屏 显示屏
- Android点阵屏效果的控件
- 环信IM集成 —— 聊天界面URL颜色展示
- hadoop学习中DNF服务器的安装(主要用来替换host文件的配置)
- Android Fragment 你应该知道的一切
- JavaScript 跨域访问的问题和解决过程
- 两张图片合成
- STM32 RGB点阵屏故事 下
- C#操作地图文档和图层
- Android程序的反破解技术
- MemCache工作流程
- Android仿微信界面
- Accessing the Raspberry Pi Camera with OpenCV and Python
- swift资源库-2-初识UI
- 解决java.lang.IllegalStateException: Fragment not attached to Activity
- 韩顺平Spring框架学习,学习笔记(一)