RP2350-LCD-0.96 是一款Waveshare设计的低成本,高性能的微控制器开发板,具有灵活数字接口。硬件上,采用 Raspberry Pi 官方研发的 RP2350A 微控制器芯片,搭载了双核 ARM Cortex-M33 处理器和双核 Hazard 3 RISC-V 处理器,高达 150MHz 的运行频率,内置了 520KB 的 SRAM 和 4MB 的内存,还板载有多达 26 个多功能的 GPIO 引脚、0.96英寸的LCD屏幕、电池接口,方便使用在移动的场合、充电电流可达1A和电源IC TPS63000,1.8A 电流开关的高效率DCDC 降压-升压芯片。软件上,可选择树莓派提供的 C/C++ SDK,或者使用 MicroPython 进行开发,且配套有完善的开发资料教程,可方便快速入门开发,并嵌入应用到产品中。
led_external = machine.Pin(15, machine.Pin.OUT) #设置GP15为输出模式 while True: led_external.toggle() #每过5秒钟让LED灯的状态改变一次 utime.sleep(5)
def button_reader_thread(): #检测按键是否被按下 global button_pressed while True: if button.value() == 1: button_pressed = True _thread.start_new_thread(button_reader_thread, ()) #用开启线程的方式去检测按键 while True: if button_pressed == True: #如果按键被按下,红灯亮起,蜂鸣器响闹 led_red.value(1) for i in range(10): buzzer.value(1) utime.sleep(0.2) buzzer.value(0) utime.sleep(0.2) global button_pressed button_pressed = False led_red.value(1) #正常情况下红灯变绿灯时黄灯会亮两秒,然后黄灯和红灯灭,绿灯亮 utime.sleep(5) #由绿灯变红灯时,绿灯先灭,黄色亮两秒,然后红灯亮 led_amber.value(1) utime.sleep(2) led_red.value(0) led_amber.value(0) led_green.value(1) utime.sleep(5) led_green.value(0) led_amber.value(1) utime.sleep(5) led_amber.value(0)
def pir_handler(pin): #中断处理函数,蜂鸣器响,led快速闪烁 print("ALARM! Motion detected!") for i in range(50): led.toggle() buzzer.toggle() utime.sleep_ms(100) sensor_pir.irq(trigger=machine.Pin.IRQ_RISING, handler=pir_handler)#开启中断,当人体传感器检测到异常时就会进入中断处理函数处理 while True: #无异常状态下会每隔5秒改变一次LDE的状态 led.toggle() utime.sleep(5)
potentiometer = machine.ADC(26) #将GP26作为模拟信号采集引脚 conversion_factor = 3.3 / (65535) while True: voltage = potentiometer.read_u16() * conversion_factor #将采集到的数据进行格式化转换成电压值 print(voltage) #打印电压信息,电压值会随着滑动变阻器旋转而变化 utime.sleep(2)
#这一段代码使用到的是状态机机制,如下代码是一个装饰器,在装饰器中我们可以硬件进行初始化、设定引脚的电平等等。 #label("bitloop") 我们可以在代码中定义一下标记,方便我们通过跳转的方式跳到他们这里执行。 #jmp(not_x,"do_zero") 当x=0时,我们就调整到标签“do_zero”。 #nop() .set(0) [T2 - 1] 当x=0时,会跳转到这里执行。 @asm_pio(sideset_init=PIO.OUT_LOW, out_shiftdir=PIO.SHIFT_LEFT, autopull=True, pull_thresh=24) def ws2812(): T1 = 2 T2 = 5 T3 = 1 label("bitloop") out(x, 1) .side(0) [T3 - 1] jmp(not_x, "do_zero") .side(1) [T1 - 1] jmp("bitloop") .side(1) [T2 - 1] label("do_zero") nop() .side(0) [T2 - 1]
# Create the StateMachine with the ws2812 program, outputting on Pin(22). sm = StateMachine(0, ws2812, freq=8000000, sideset_base=Pin(0)) #创建状态机 # Start the StateMachine, it will wait for data on its FIFO. sm.active(1) #开始状态机 # Display a pattern on the LEDs via an array of LED RGB values. ar = array.array("I", [0 for _ in range(NUM_LEDS)]) print(ar) print("blue") for j in range(0, 255): for i in range(NUM_LEDS): ar[i] = j sm.put(ar,8) #put()的方法是将数据放入状态机的输出FIFO time.sleep_ms(5)
Choose_Color.py
#定义颜色 rgb9 = (0,255,0) #青色’ lcd.setCursor(0, 0) #设置游标位置 # print the number of seconds since reset: lcd.printout("Waveshare") #写入字符 lcd.setCursor(0, 1) #设置游标位置到第二行第零列 lcd.printout("Hello,World!")#写入字符 lcd.setRGB(rgb1[0],rgb1[1],rgb1[2]); #设置背光
Discoloration.py
t=0 while True: r = int((abs(math.sin(3.14*t/180)))*255); #RGB随着时间的变化而变化 g = int((abs(math.sin(3.14*(t+60)/180)))*255); b = int((abs(math.sin(3.14*(t+120)/180)))*255); t = t + 3; lcd.setRGB(r,g,b);#重新设置RGB的值 # set the cursor to column 0, line 1 lcd.setCursor(0, 0) #定位到第一行第零列 # print the number of seconds since reset: lcd.printout("Waveshare")#写入字符 lcd.setCursor(0, 1) #定位到第二行第零列 lcd.printout("Hello,World!")#写入字符 time.sleep(0.3)
本例显示的效果为通过 LVGL 显示一张图片。
本例用于测试 LVGL 控件交互、样式美化等, LVGL 的具体开发请参考LVGL开发文档。
setx PICO_SDK_PATH "D:\pico\pico-sdk"
mkdir build cd build
cmake -G "NMake Makefiles" ..
nmake编译好后会生成一个 .uf2 格式的文件。
nano ~/.bashrc #将以下内容添加到最后一行 export PICO_SDK_PATH="/home/pico/pico-sdk"
source ~/.bashrc
mkdir build cd build
cmake ..
nmake编译好后会生成一个 .uf2 格式的文件。
在使用 LVGL 图像库之前,您需要先初始化 LVGL。
LVGL_Init();
/*2.Init LVGL core*/ lv_init();
LVGL 库定时调用心跳接口函数 lv_tick_inc 来通知LVGL过去的时间,以便 LVGL 能够更新其内部的时间状态,处理与时间相关的任务,例如动画、定时器等。在主函数的循环中还需要调用 lv_task_handler 函数,以便 LVGL 及时处理事件和任务,保证用户界面的响应和刷新。
//每5ms调用一次定时器回调函数 add_repeating_timer_ms(5, repeating_lvgl_timer_callback, NULL, &lvgl_timer); static bool repeating_lvgl_timer_callback(struct repeating_timer *t) { lv_tick_inc(5); return true; }
int main() { ... while(1) { lv_task_handler(); DEV_Delay_ms(5); ... } }
要实现 LVGL 显示,必须初始化一个显示驱动,并设置显示驱动的各个属性,例如,颜色格式、绘制缓冲区、渲染模式以及显示回调函数。在每个 LV_DISP_DEF_REFR_PERIOD(在 lv_conf.h 中设置),LVGL 会检测 UI 上是否发生了一些需要重绘的事情。例如,按下按钮、更改图表、发生动画等。需要重新绘制时,LVGL 调用显示回调函数完成图像在刷新区的绘制。
#define LV_DISP_DEF_REFR_PERIOD 10 // 单位:ms,这里为10ms
#define LV_COLOR_16_SWAP 1
static lv_disp_drv_t disp_drv; static lv_disp_draw_buf_t disp_buf; static lv_color_t buf0[DISP_HOR_RES * DISP_VER_RES/2]; static lv_color_t buf1[DISP_HOR_RES * DISP_VER_RES/2];
/*3.Init LVGL display*/ lv_disp_draw_buf_init(&disp_buf, buf0, buf1, DISP_HOR_RES * DISP_VER_RES / 2); lv_disp_drv_init(&disp_drv); disp_drv.flush_cb = disp_flush_cb; disp_drv.draw_buf = &disp_buf; disp_drv.hor_res = DISP_HOR_RES; disp_drv.ver_res = DISP_VER_RES; lv_disp_t *disp= lv_disp_drv_register(&disp_drv);
void disp_flush( lv_disp_drv_t *disp_drv, const lv_area_t *area, lv_color_t *color_p ) 参数: lv_disp_drv_t *disp_drv: 显示驱动结构体指针,包含了与显示相关的信息和函数指针。该参数常用于通知刷新完成 const lv_area_t *area : 区域结构体指针,包含待刷新区域的位置信息。在本例中,用于创建 TFT 显示的窗口 lv_color_t *color_p : 颜色结构体指针,表示要在刷新区域内显示的颜色数据。在本例中,作为DMA输入读取地址将数据传输到SPI总线,完成图像的绘制
static void disp_flush_cb(lv_disp_drv_t * disp, const lv_area_t * area, lv_color_t * color_p) { LCD_SetWindows(area->x1, area->y1, area->x2+1, area->y2+1); DEV_Digital_Write(LCD_DC_PIN, 1); DEV_Digital_Write(LCD_CS_PIN, 0); dma_channel_configure(dma_tx, &c, &spi_get_hw(LCD_SPI_PORT)->dr, color_p, // read address ((area->x2 + 1 - area-> x1)*(area->y2 + 1 - area -> y1))*2, true); }
static void dma_handler(void) { if (dma_channel_get_irq0_status(dma_tx)) { dma_channel_acknowledge_irq0(dma_tx); DEV_Digital_Write(LCD_CS_PIN, 1); lv_disp_flush_ready(&disp_drv); } }
在 LVGL 中,我们能够建立各种不同的用户界面。界面的基本组成部分是对象,也称为控件(Widgets),比如按钮(Button)、标签(Label)、图像(Image)、列表(List)、图表或文本区域。在一个界面中,可以同时创建多个控件,并且我们可以设置它们的位置、尺寸、父对象、样式以及事件处理程序等基本属性。
void Widgets_Init(void);
//在 (0,0) 创建一个图块,支持向下滑动到 (0,1) tile1 = lv_tileview_add_tile(tv, 0, 0, LV_DIR_BOTTOM);
//创建一个控件,其中 tab1 为该按键的父对象,可以替换为list、title等可以有子对象的控件 sw = lv_switch_create(tab1);
//将btn控件定位在中心点向左偏移45个像素 lv_obj_align(sw, LV_ALIGN_CENTER, -45, 0);
#define LV_FONT_MONTSERRAT_16 1 // 使能16号字体 #define LV_FONT_MONTSERRAT_18 1 // 使能18号字体 #define LV_FONT_DEFAULT &lv_font_montserrat_18 // 设置默认字体大小为18号 static lv_style_t style_label; lv_style_init(&style_label); // 初始化风格 lv_style_set_text_font(&style_label, &lv_font_montserrat_16); // 设置字体大小为16号 lv_obj_add_style(label,&style_label,0); // 设置label主题的风格
//为控件 sw 添加事件 LV_EVENT_VALUE_CHANGED 的处理函数 sw_event_cb lv_obj_add_event_cb(sw, sw_event_cb,LV_EVENT_VALUE_CHANGED,NULL);
本例显示的效果为通过LVGL显示一张图片。
本例用于测试 LVGL 控件交互、样式美化等,使用的版本号为9.1,LVGL V9 的开发文档中没有提供 Python 示例,具体开发请参考LVGL开发文档。
在使用 LVGL 图像库之前,您需要导入 LVGL 库并初始化 LVGL 对象
import lvgl as lv
# Init LVGL LVGL(LCD=LCD,TSC=TSC)
if not lv.is_initialized(): lv.init()
LVGL 库定时调用心跳接口函数 lv.tick_inc 来通知 LVGL 过去的时间,以便 LVGL 能够更新其内部的时间状态,处理与时间相关的任务,例如动画、定时器等。此外还需要调用 lv.task_handler 函数,以便 LVGL 及时处理事件和任务,保证用户界面的响应和刷新。
# Create event loop if not yet present if not lv_utils.event_loop.is_running(): self.event_loop=lv_utils.event_loop()
#每 5ms 调用一次定时器回调函数 self.timer.init(mode=Timer.PERIODIC, period=self.delay, callback=self.timer_cb) // 本例中 self.delay = 5 def timer_cb(self, t): lv.tick_inc(self.delay) if self.scheduled < self.max_scheduled: try: micropython.schedule(self.task_handler_ref, 0) self.scheduled += 1 # 正在处理的任务数增加 except: pass
def task_handler(self, _): try: if lv._nesting.value == 0: lv.task_handler() if self.refresh_cb: self.refresh_cb() self.scheduled -= 1 # 正在处理的任务数减少 except Exception as e: if self.exception_sink: self.exception_sink(e)
要实现 LVGL 显示,必须初始化一个显示驱动,并设置显示驱动的各个属性,例如,颜色格式、绘制缓冲区、渲染模式以及显示回调函数。在每个 LV_DEF_REFR_PERIOD(在 lv_conf.h 中设置),LVGL 会检测 UI 上是否发生了一些需要重绘的事情。例如,按下按钮、更改图表、发生动画等。需要重新绘制时,LVGL 调用显示回调函数完成图像在刷新区的绘制。
#define LV_DEF_REFR_PERIOD 10 // 单位:ms,这里为10ms
# Init LVGL display buf1 = lv.draw_buf_create(self.LCD.width, self.LCD.height // 3 , color_format, 0) buf2 = lv.draw_buf_create(self.LCD.width, self.LCD.height // 3, color_format, 0)
self.disp_drv = lv.display_create(self.LCD.width, self.LCD.height) # 创建显示驱动器对象,并设置宽度和高度 self.disp_drv.set_color_format(color_format) # 设置颜色格式为 RGB565 self.disp_drv.set_draw_buffers(buf1, buf2) # 设置绘制缓冲区 self.disp_drv.set_render_mode(lv.DISPLAY_RENDER_MODE.PARTIAL) # 设置渲染模式为部分刷新模式 self.disp_drv.set_flush_cb(self.disp_drv_flush_cb) # 设置显示回调函数
def disp_drv_flush_cb(self,disp_drv,area,color_p) 参数: disp_drv : 显示驱动结构体指针,包含了与显示相关的信息和函数指针。该参数常用于通知刷新完成 area : 区域结构体指针,包含待刷新区域的位置信息。在本例中,用于创建 TFT 显示的窗口 color_p : 颜色结构体指针,表示要在刷新区域内显示的颜色数据。在本例中,作为DMA输入读取地址将数据传输到SPI总线,完成图像的绘制
def disp_drv_flush_cb(self,disp_drv,area,color_p): ...... self.rgb565_swap_func(data_view, size) # 转换颜色格式 self.LCD.setWindows(area.x1, area.y1, area.x2+1, area.y2+1) # 设置 LVGL 界面显示位置 ...... # DMA 配置立即执行 while self.dma.active(): # 等待 DMA 空闲 pass self.disp_drv.flush_ready() # 通知 LVGL 数据传输完成
在 LVGL 中,我们能够建立各种不同的用户界面。界面的基本组成部分是对象,也称为控件(Widgets),比如按钮(Button)、标签(Label)、图像(Image)、列表(List)、图表或文本区域。在一个界面中,可以同时创建多个控件,并且我们可以设置它们的位置、尺寸、父对象、样式以及事件处理程序等基本属性。
# Init WIDGETS WIDGETS(LCD=LCD)
//在 (0,0) 创建一个图块,支持向下滑动到 (0,1) self.tv = lv.tileview(self.scr) self.tile1 = self.tv.add_tile(0, 0, lv.DIR.BOTTOM)
//创建一个 table 控件,其中 tile2 为该控件的父对象,可以替换为list、title等可以有子对象的控件 self.table_imu_data = lv.table(self.tile2)
//将控件定位在中心点右偏移15个像素 self.table_imu_data.align(lv.ALIGN.CENTER, 15 ,0)
#define LV_FONT_MONTSERRAT_16 1 // 使能16号字体 #define LV_FONT_MONTSERRAT_18 1 // 使能18号字体 #define LV_FONT_DEFAULT &lv_font_montserrat_18 // 设置默认字体大小为18号 table_imu_data= lv.style_t() // 创建对象 table_imu_data.init() // 初始化 table_imu_data.set_text_font(lv.font_montserrat_16) // 设置字体大小为16 self.table_imu_data.add_style(style_imu_table, 0) // 设置风格
不,您需要使用带有集成保护电路的电池或连接外部保护电路以防止深度放电。
周一-周五(9:30-6:30)周六(9:30-5:30)
手机:13434470212
邮箱:services04@spotpear.cn
QQ:202004841