news 2026/9/4 16:34:13

zephyr3--外设(TODO)

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
zephyr3--外设(TODO)

现在看看如何接外设,我这次用的是Pico2。这次接了一个SPI的屏,还有一个按键。屏幕用的是GC9A01 240x240 圆屏,按键就是普通的IO口按键。

1 SPI

首先还是配置设备树,在app.overlay。

/* * GC9A01 240x240 圆屏 @ Raspberry Pi Pico 2 * * 接线: * SCL -> GP18 (SPI0 SCK) SDA -> GP19 (SPI0 TX/MOSI) * CS -> GP17 (SPI0 CSn) DC -> GP20 * RES -> GP21 BLK -> GP22 (main.c 里直接 gpio 点亮) * VCC -> 3V3 GND -> GND * * pinctrl 组 spi0_default (boards/raspberrypi/common/rpi_pico-pinctrl-common.dtsi) * 正好就是 CSN_P17 + SCK_P18 + TX_P19。 */ #include <freq.h> #include <zephyr/dt-bindings/display/panel.h> #include <zephyr/dt-bindings/gpio/gpio.h> / { chosen { zephyr,display = &gc9a01_lcd; }; mipi_dbi_gc9a01 { compatible = "zephyr,mipi-dbi-spi"; status = "okay"; write-only; #address-cells = <1>; #size-cells = <0>; spi-dev = <&spi0>; dc-gpios = <&gpio0 20 GPIO_ACTIVE_HIGH>; reset-gpios = <&gpio0 21 GPIO_ACTIVE_LOW>; gc9a01_lcd: gc9a01@0 { compatible = "galaxycore,gc9x01x"; reg = <0>; mipi-max-frequency = <DT_FREQ_M(40)>; pixel-format = <PANEL_PIXEL_FORMAT_RGB_565>; width = <240>; height = <240>; display-inversion; }; }; }; &spi0 { status = "okay"; pinctrl-0 = <&spi0_default>; pinctrl-names = "default"; };

prj.conf

# GC9A01 圆屏 (Pico2, Zephyr v4.1) CONFIG_DISPLAY=y CONFIG_GC9X01X=y CONFIG_SPI=y CONFIG_GPIO=y # 注意: 不要用 CONFIG_CHARACTER_FRAMEBUFFER / cfb_* —— CFB 只支持 # 1-bit 单色 (8 像素/字节), 用在 RGB565 彩色屏上会越界读内存导致花屏。 # 文字渲染用 main.c 里内置的 8x8 像素字库, 直接写应用帧缓冲。 CONFIG_PRINTK=y CONFIG_LOG=y CONFIG_MAIN_STACK_SIZE=4096

CMakelist.txt

cmake_minimum_required(VERSION 3.20.0) find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE}) project(gc9a01_demo LANGUAGES C) target_sources(app PRIVATE src/main.c)

代码,核心代码就是

/* RGB565 显存, 存的是字节交换后的值 (大端上屏) */ static uint16_t fb[WIDTH * HEIGHT]; static struct display_buffer_descriptor desc = { .width = WIDTH, .height = HEIGHT, .pitch = WIDTH, .buf_size = sizeof(fb), }; static inline uint16_t color565(uint8_t r, uint8_t g, uint8_t b) { uint16_t v = (uint16_t)(((r & 0xF8) << 8) | ((g & 0xFC) << 3) | (b >> 3)); return (uint16_t)((v << 8) | (v >> 8)); /* byteswap: LE buf -> BE wire */ } static void flush(void) { int ret = display_write(display, 0, 0, &desc, fb); if (ret < 0) { printk("display_write failed: %d\n", ret); } }

先是在desc中写了屏幕的核心数据。然后最核心的就是分配了一块内存,平时在这块内存中填写图像数据,最后调用display_write写入。

3 I2C

添加工程在外部添加就可以了,增加环境变量。

export ZEPHYR_BASE=/root/code/zephyr

或者每次

source ~/code/zephyr/zephyr-env.sh

创建~/proj/pico_i2c_scan

增加以下文件:

pico_i2c_scan/CMakeLists.txt

cmake_minimum_required(VERSION 3.20.0) find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE}) project(pico_i2c_scan) target_sources(app PRIVATE src/main.c)

prj.conf

CONFIG_I2C=y CONFIG_PRINTK=y # USB CDC ACM console CONFIG_USB_DEVICE_STACK=y CONFIG_USB_CDC_ACM=y CONFIG_SERIAL=y CONFIG_UART_CONSOLE=y CONFIG_UART_LINE_CTRL=y CONFIG_USB_DEVICE_INITIALIZE_AT_BOOT=y

main.c

#include <zephyr/kernel.h> #include <zephyr/device.h> #include <zephyr/drivers/i2c.h> #include <zephyr/usb/usb_device.h> #define I2C_NODE DT_NODELABEL(i2c1) int main(void) { int ret; ret = usb_enable(NULL); if (ret != 0) { printk("USB enable failed %d\n", ret); } printk("I2C scanner start\n"); const struct device *i2c_dev; i2c_dev = DEVICE_DT_GET(I2C_NODE); if (!device_is_ready(i2c_dev)) { printk("I2C device not ready\n"); return 0; } printk("I2C scanner start\n"); while (1) { printk("Scanning...\n"); for (uint8_t addr = 1; addr < 0x7f; addr++) { int ret; /* * 发送一个空write * 只检测ACK */ ret = i2c_write( i2c_dev, NULL, 0, addr); if (ret == 0) { printk( "Found device at 0x%02x\n", addr); } } k_sleep(K_SECONDS(5)); } return 0; }

overlay

boards/rpi_pico.overlay

&i2c1 { status = "okay"; }; / { chosen { zephyr,console = &cdc_acm_uart0; zephyr,shell-uart = &cdc_acm_uart0; }; }; &zephyr_udc0 { cdc_acm_uart0: cdc_acm_uart0 { compatible = "zephyr,cdc-acm-uart"; }; };

编译的命令是:

west build -p always -b rpi_pico ..

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/4 16:19:54

用32块矿卡堆出2TB显存,DIY超级计算机跑vLLM推理

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/9/4 16:19:01

AI创业如何抓住破局点?从YC史上最快独角兽AfterQuery说起

创业圈每隔一段时间就会出现一个让所有人抬头看一眼的名字。这一次&#xff0c;主角是 AfterQuery&#xff1a;一家被传闻以 32 亿美元估值完成新一轮融资的 AI 公司&#xff0c;还背上了一个更醒目的标签——“Y Combinator 史上最快独角兽”。先说结论&#xff1a;这个传闻最…

作者头像 李华
网站建设 2026/9/4 16:18:34

61.吃透 FPGA 高速接口核心!DDR3 协议分析 + RTL 实现 + 上板调试全教程

摘要 本文以FPGA接口设计为主线,从最基础的同步时序模型出发,逐步深入到DDR3 SDRAM控制器接口的完整实现。文章摒弃空洞理论,以一段可直接运行的Verilog代码为核心,详细拆解接口设计的每个环节:时钟域处理、状态机设计、时序约束、读写调度。通过本文,读者将掌握FPGA接口…

作者头像 李华
网站建设 2026/9/4 16:15:13

【单片机课设毕设项目】基于 STM32 或 51 单片机的多参数室内火灾隐患监测装置设计 基于 STM32 或 51 单片机的可参数配置物联网安防监测系统设计(023806)

博主介绍&#xff1a;✌️码农一枚 &#xff0c;专注于大学生项目实战开发、讲解和毕业&#x1f6a2;文撰写修改等。全栈领域优质创作者&#xff0c;博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于嵌入式单片机&#xff0c;Java、小程序技术领域和毕业项目实战 ✌️…

作者头像 李华
网站建设 2026/9/4 16:10:18

小米网关HAD1.16.2固件:本地自动化与Home Assistant接入实战指南

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华