STM32F7DISC带有LCD和Touch功能的固件

STM32系列
pyboard相关
回复
头像
shaoziyang
帖子: 3917
注册时间: 2019年 10月 21日 13:48

STM32F7DISC带有LCD和Touch功能的固件

#1

帖子 shaoziyang »

这个固件是根据 forester3 的修改版编译的,并开启了 16M flash和双精度浮点和线程功能。主要支持的功能:
  • SD卡
  • LCD显示
  • 触摸屏
  • 双精度浮点
  • 线程
  • 网络
  • ADC
固件已经上传到github上的社区固件库中(以下例程也包含其中):
https://github.com/micropython-Chinese- ... n_firmware
 

头像
shaoziyang
帖子: 3917
注册时间: 2019年 10月 21日 13:48

Re: STM32F7DISC带有LCD和Touch功能的固件

#2

帖子 shaoziyang »

绘图功能使用LCD,首先需要载入 lcdF7D库,然后才能使用lcd功能。 import lcdF7D as lcd 其次需要对lcd进行初始化 lcd.init() 然后就可以进行画线、画圆等操作了。下面是几个主要函数用法: 
  • clear(color),用颜色color清除整个屏幕
    颜色的定义为
    • 如果是空,使用set_text_color中定义的颜色
    • 如果是一个数字,以0xRRGGBB方式
    • 如果是两个数字,第一个代表Alpha,第二个数字同上
    • 如果是3个数字,分别代表R、G、B分量,Alpha固定为255
    • 如果是4个数字,分别代表A、R、G、B
  • set_text_color(color),设置前景颜色
  • set_back_color(color),设置背景颜色
  • draw_line(x1, y1, x2, y2),画直线
  • draw_Hline(x, y, len),画水平线
  • draw_Vline(x, y, len),画垂直线
  • draw_rect(x1, y1, x2, y2),画空心矩形
  • fill_rect(x1, y1, x2, y2),画实心矩形
  • draw_circle(x, y, r),画圆
  • set_font(n),设置字体大小,有效大小是8/12/16/20/24
  • display_char(x, y, asc),在x,y处显示字符
  • display_string_at(x, y, string, mode),显示字符串

随机直线

Code: Select all

from time import sleep_ms, ticks_ms, ticks_diff
import pyb, machine
from random import randrange as rand

import lcdF7D as lcd
import tchF7D as ts

MAX_X = 480
MAX_Y = 272

lcd.init()

ts.init(MAX_X, MAX_Y)


def test_rand_line(n = 5000, delay = 1):
    lcd.clear()
    lcd.set_font(24)
    lcd.set_text_color(255,255,128,0)
    lcd.display_string_at(0, 0, 'line test' ,0)
    sleep_ms(1000)
    t0 = ticks_ms()
    for i in range(n):
        lcd.set_text_color(rand(0xFF), rand(0xFFFFFF))
        lcd.draw_line(rand(MAX_X), rand(MAX_Y), rand(MAX_X), rand(MAX_Y))
        sleep_ms(delay)
    return ticks_diff(ticks_ms(), t0)

def test_rand_rect(n = 2000, delay = 1):
    lcd.clear()
    lcd.set_font(24)
    lcd.set_text_color(255,255,128,0)
    lcd.display_string_at(0, 0, 'rect test' ,0)
    sleep_ms(1000)
    t0 = ticks_ms()
    for i in range(n):
        lcd.set_text_color(rand(0xFF), rand(0xFFFFFF))
        x, y = rand(MAX_X), rand(MAX_Y)
        lcd.draw_rect(x, y, rand(MAX_X - x), rand(MAX_Y - y))
        sleep_ms(delay)
    return ticks_diff(ticks_ms(), t0)

def test_rand_fillrect(n = 2000, delay = 1):
    lcd.clear()
    lcd.set_font(24)
    lcd.set_text_color(255,255,128,0)
    lcd.display_string_at(0, 0, 'fill rect test' ,0)
    sleep_ms(1000)
    t0 = ticks_ms()
    for i in range(n):
        lcd.set_text_color(rand(0xFF), rand(0xFFFFFF))
        x, y = rand(MAX_X), rand(MAX_Y)
        lcd.fill_rect(x, y, rand(MAX_X - x), rand(MAX_Y - y))
        sleep_ms(delay)
    return ticks_diff(ticks_ms(), t0)

def test_gradient(c1=0, c2=0xff, dir=0):
    def cr(x1, x2, i, n):
        return int(x1 + i*(x2-x1)/n)

    r1, g1, b1 = c1>>16, (c1>>8)%256, c1%256
    r2, g2, b2 = c2>>16, (c2>>8)%256, c2%256
    if dir == 0:
        for i in range(MAX_X):
            r = cr(r1, r2, i, MAX_X)
            g = cr(g1, g2, i, MAX_X)
            b = cr(b1, b2, i, MAX_X)
            lcd.set_text_color(r, g, b)
            lcd.draw_Vline(i, 0, MAX_Y)
    elif dir == 1:
        for i in range(MAX_Y):
            r = cr(r1, r2, i, MAX_Y)
            g = cr(g1, g2, i, MAX_Y)
            b = cr(b1, b2, i, MAX_Y)
            lcd.set_text_color(r, g, b)
            lcd.draw_Hline(0, i, MAX_X)
    elif dir == 2:
        for i in range(MAX_X):
            r = cr(r2, r1, i, MAX_X)
            g = cr(g2, g1, i, MAX_X)
            b = cr(b2, b1, i, MAX_X)
            lcd.set_text_color(r, g, b)
            lcd.draw_Vline(i, 0, MAX_Y)    
    else:
        for i in range(MAX_Y):
            r = cr(r2, r1, i, MAX_Y)
            g = cr(g2, g1, i, MAX_Y)
            b = cr(b2, b1, i, MAX_Y)
            lcd.set_text_color(r, g, b)
            lcd.draw_Hline(0, i, MAX_X)

def test_rand_char(n = 2000, font = 12, delay = 1):
    if font > 20: _w, _h = 17, 24, 
    elif font > 16: _w, _h = 14, 20
    elif font > 12: _w, _h = 11, 16
    elif font > 8: _w, _h = 7, 12
    else: _w, _h = 5, 8

    lcd.clear()
    lcd.set_font(_h)
    mx, my = MAX_X//_w, MAX_Y//_h

    for i in range(n):
        lcd.set_text_color(rand(0xFFFFFF))
        lcd.display_char(rand(mx) * _w, rand(my) * _h, rand(95)+32)
        sleep_ms(delay)

def test_rand_pchar(n = 2000, font = 12, delay = 5):
    if font > 20: _w, _h = 17, 24, 
    elif font > 16: _w, _h = 14, 20
    elif font > 12: _w, _h = 11, 16
    elif font > 8: _w, _h = 7, 12
    else: _w, _h = 5, 8

    lcd.clear()
    lcd.set_font(_h)
    mx, my = MAX_X//_w, MAX_Y//_h
    px, py = 0, 0

    for i in range(n):
        lcd.set_text_color(rand(0xFFFFFF))
        lcd.display_char(px * _w, py * _h, rand(95)+32)
        px += 1
        if px >= mx:
            px, py = 0, py + 1
            if py >= my:
                py = my - 1
                lcd.scroll(0, -_h)
                lcd.set_text_color(0)
                lcd.fill_rect(0, MAX_Y - _h, MAX_X-1, MAX_Y-1)
        sleep_ms(delay)

def test_rand_gradient(n = 20, delay = 500):
    for i in range(n):
        test_gradient(rand(0xFFFFFF), rand(0xFFFFFF), rand(4))
        sleep_ms(delay)

MAX_ITER = 60
pal = [i%256 for i in range(MAX_ITER)]

def test_mandelbrot(x0 = -2.5, y0 = -2, x1 = 1.5, y1 = 2, ITER = MAX_ITER, RandPAL = 1):
    def calc(c):
        z = 0
        for i in range(ITER):
            z = z * z + c
            if abs(z) > 4:
                return i
        return ITER-1

    if RandPAL:
        global pal
        pal = [rand(0xFFFFFF) for i in range(MAX_ITER)]
    
    lcd.clear(0)

    t0 = ticks_ms()
    dx = (x1 - x0)/MAX_X
    dy = (y1 - y0)/MAX_Y

    for ix in range(MAX_X):
        for iy in range(MAX_Y):
            z = x0 + dx * ix + (y0 + dy * iy) * 1j
            c = calc(z)
            lcd.draw_pixel(ix, iy, pal[c%ITER])
    return ticks_diff(ticks_ms(), t0)

def test_fast_mandelbrot(x0 = -2.5, y0 = -2, x1 = 1.5, y1 = 2, ITER = MAX_ITER, RandPAL = 1):
    def calc(c):
        z = 0
        for i in range(ITER):
            z = z * z + c
            if abs(z) > 4:
                return i
        return ITER-1

    if RandPAL:
        global pal
        pal = [rand(0xFFFFFF) for i in range(MAX_ITER)]
    
    lcd.clear(0)

    t0 = ticks_ms()
    dx = (x1 - x0)/MAX_X
    dy = (y1 - y0)/MAX_Y
    c = [0]*16

    for ix in range(MAX_X//4):
        for iy in range(MAX_Y//4):
            c = [0]*16
            z = x0 + dx * ix * 4 + (y0 + dy * iy * 4) * 1j
            c[0] = calc(z)
            c[3] = calc(z + dx*3)
            c[12] = calc(z + dy*3j)
            c[15] = calc(z + dx*3 + dy*3j)
            if c[0] == c[3] and c[0] == c[12] and c[0] == c[15]:
                lcd.set_text_color(pal[c[0]%ITER])
                lcd.fill_rect(ix*4, iy*4, 4, 4)
            else:
                for i in range(16):
                    if c == 0:
                        c = calc(z + dx*(i%4) + dy*(i//4)*1j)
                    lcd.draw_pixel(ix*4+(i%4), iy*4+(i//4), pal[c%ITER])
    return ticks_diff(ticks_ms(), t0)
            
def lcd_test():
    test_rand_line()
    test_rand_rect()
    test_rand_fillrect()
    test_rand_gradient()
    test_rand_char(font = 8)
    test_rand_char(font = 12)
    test_rand_char(font = 16)
    test_rand_char(font = 20)
    test_rand_char(font = 24)
    test_rand_pchar(font = rand(32))

lcd_test()
test_fast_mandelbrot()

 

头像
shaoziyang
帖子: 3917
注册时间: 2019年 10月 21日 13:48

Re: STM32F7DISC带有LCD和Touch功能的固件

#3

帖子 shaoziyang »

图层(layer)

STM32F7DISC开发板的图形功能很丰富,其中一个很有特点的功能是图层(layer),layer的概念类似于photoshop中的图层。图层有很多用法,比如可以将图层作为缓冲区,先在一个图层中绘图,然后一次性快速显示;也可以设定图层的透明度(set_transparency),或者设定图层的显示窗口位置和大小等。受到RAM限制,目前仅支持2个图层。0是背景图层,1是前景图层。在图层1绘图时,如果颜色中设置了alpha通道,可以显示出透明色,和图层0进行叠加。

图层的主要函数:
  • layer_default_init(),初始化
  • select_layer(n),选择当前图层。
  • set_layer_window(n, x, y, width, height),设置一个图层窗口位置的大小
  • set_layer_visible(n, show),n代表图层,show代表显示或隐藏
  • set_transparency(n, tr),n代表图层,tr是透明度(0代表完全透明,255代表不透明)
  • set_layer_address(),设置图层地址,用法还不清楚
因为缺少文档,一些功能是不断测试中摸索出来的,可能存在错误或者不准确的地方,欢迎大家指出。
 

具体使用方法请参考demo,特别注意使用alpha通道开窗和透明度的效果。

代码: 全选

from time import sleep_ms
import lcdF7D as lcd
import tchF7D as ts

MAX_X = 480
MAX_Y = 272

lcd.init()

lcd.select_layer(0)
lcd.set_text_color(0xFF)
lcd.fill_rect(50, 50, 200, 100)
lcd.set_text_color(0xFF00)
lcd.fill_rect(200, 80, 200, 100)
lcd.set_text_color(0xFF0000)
lcd.fill_rect(100, 100, 200, 100)
lcd.set_text_color(0xFF00)
lcd.set_font(20)
lcd.display_string_at(0, 0, 'rect show on the screen', 0)

lcd.select_layer(1)
lcd.set_text_color(0xFF0000)
lcd.set_font(24)
lcd.display_string_at(0, 60, 'no rect show on the screen', 0)
lcd.set_text_color(0x80, 0)
lcd.fill_rect(180, 90, 30, 30)
sleep_ms(2000)

lcd.set_layer_visible(1, 0)
sleep_ms(2000)

lcd.set_layer_visible(1, 1)

for i in range(255):
    lcd.set_transparency(1, 255 - i)
    sleep_ms(10)

for i in range(220):
    lcd.set_transparency(1, i)
    sleep_ms(10)

头像
shaoziyang
帖子: 3917
注册时间: 2019年 10月 21日 13:48

Re: STM32F7DISC带有LCD和Touch功能的固件

#4

帖子 shaoziyang »

触摸功能

代码: 全选

import lcdF7D as lcd
import tchF7D as ts
from time import sleep_ms

lcd.init()
lcd.set_text_color(0x00FF00)

ts.init(480, 272)


def ts_test():
    while 1:
        ts.get_state()
        if ts.touches() > 0:
            lcd.clear(0)
            print('\nTouch num: ', str(ts.touches()))
            for i in range(ts.touches()):
                print('  {} {}'.format(i+1, ts.point_info(i+1)))
                p = ts.point_info(i+1)
                x1 = max(min(p[0] - p[2]//2, 479), 0)
                x2 = max(min(p[0] + p[2]//2, 479), 0)
                y1 = max(min(p[1] - p[2]//2, 271), 0)
                y2 = max(min(p[1] + p[2]//2, 271), 0)
                lcd.set_text_color(0x00FF00)
                lcd.draw_rect(x1, y1, x2-x1, y2-y1)
        sleep_ms(100)
 

头像
shaoziyang
帖子: 3917
注册时间: 2019年 10月 21日 13:48

Re: STM32F7DISC带有LCD和Touch功能的固件

#5

帖子 shaoziyang »

触摸功能

代码: 全选

import lcdF7D as lcd
import tchF7D as ts
from time import sleep_ms

lcd.init()
lcd.set_text_color(0x00FF00)

ts.init(480, 272)


def ts_test():
while 1:
ts.get_state()
if ts.touches() > 0:
lcd.clear(0)
print('\nTouch num: ', str(ts.touches()))
for i in range(ts.touches()):
print(' {} {}'.format(i+1, ts.point_info(i+1)))
p = ts.point_info(i+1)
x1 = max(min(p[0] - p[2]//2, 479), 0)
x2 = max(min(p[0] + p[2]//2, 479), 0)
y1 = max(min(p[1] - p[2]//2, 271), 0)
y2 = max(min(p[1] + p[2]//2, 271), 0)
lcd.set_text_color(0x00FF00)
lcd.draw_rect(x1, y1, x2-x1, y2-y1)
sleep_ms(100)
 

回复

  • 随机主题
    回复总数
    阅读次数
    最新文章