树莓派+8x32的MAX7219点阵模块显示字符串

2023-11-18

https://blog.csdn.net/zyaiwmy/article/details/70224250?utm_source=blogxgwz1

按照上面这篇文章进行配置了驱程,修改了一下示例代码,效果如下:

这里记一下项目的github地址:https://github.com/rm-hull/luma.led_matrix

下面为按自己需求实现的代码

import re
import time
import argparse

from luma.led_matrix.device import max7219
from luma.core.interface.serial import spi, noop
from luma.core.render import canvas
from luma.core.virtual import viewport
from luma.core.legacy import text, show_message
from luma.core.legacy.font import proportional, CP437_FONT, TINY_FONT, SINCLAIR_FONT, LCD_FONT


def demo(str):
    # create matrix device
    serial = spi(port=0, device=0, gpio=noop())
    device = max7219(serial, cascaded=4, block_orientation=-90, rotate=0)
    
    print("Created device")
    
    with canvas(device) as draw:
        text(draw, (3,0), str, fill="white", font=proportional(LCD_FONT))
    time.sleep(300)

if __name__ == "__main__":
    parser = argparse.ArgumentParser(description='matrix_demo arguments',
        formatter_class=argparse.ArgumentDefaultsHelpFormatter)

    parser.add_argument('--str', type=str, default='hello', help='The string you want to show')

    args = parser.parse_args()

    try:
        demo(args.str)
    except KeyboardInterrupt:
        pass

上面是luma.led_matrix的使用,前几天认真的百度了一下它的源码,这里记录几个重点:一个是内存映射机制,一个是缓冲协议,还有一个就是串口通信协议。

内存映射机制要讲的话就得从操作系统开始讲起,每个外设接入到Linux系统上以及树莓派上时会在/dev/中产生一个设备文件,并且会根据驱动程序中定义的datasheet将外设的寄存器、缓冲区等信息映射到Linux内核空间中。这样就相当于写好驱程的外部设备一旦插入我们的系统上,我们的系统就会提供专门的地址空间给这个设备。拿这个MAX7219模块来说,一旦插上就说明我们可以通过写Linux内存的缓冲区以及控制寄存器的读写来控制这个外部设备。讲完外设怎么映射到系统内存中,接下来就是怎么在系统内存中找到这块内存地址并对其进行IO。
寻址就需要提一下mmap,这个是内存映射的函数。操作系统有虚拟地址空间、物理地址空间和磁盘空间,我们找内存地址是通过CPU寻址,在以前还没有引入虚拟内存的概念时都是通过控制物理内存地址通过查询物理页表进行磁盘IO的,之后由于物理内存不够了就引入了虚拟内存,这个技术让每个进程都有4GB的空间进行读写。在只有物理内存的时候CPU总线发出的地址是物理地址,但引入虚拟内存后CPU总线发出的地址是虚拟地址,之后MMU单元会接手这个虚拟地址并转换为物理地址后,接着做上面提到的只有物理内存时候的事。所以CPU是不知道自己发出的地址是物理地址还是虚拟地址的,只知道自己发出了要寻找的地址。mmap函数是将磁盘地址映射到虚拟内存的,不经过物理内存,但虚拟内存寻址的时候是需要访问物理内存再到磁盘的。之所以引入物理内存是因为磁盘的IO太浪费时间了,物理内存能基本提供几个进程的空间,让操作系统使用的时候直接访问物理内存即可,而不用频繁的与磁盘进行IO,而引入虚拟内存又是因为随着计算机的发展进程越来越多也越来越大,一个物理内存已经很难为这么多的进程提供舒适的空间了。综上是操作系统的一些概念了。

還有DMA:一个完整的DMA传输过程需要经过DMA请求、DMA响应、DMA传输、DMA结束。
通过硬件为RAM与I/O设备开辟一条直接传送数据的通道,DMA使用时CPU是不能控制和使用内存的(這里我還是有疑惑的)。获得CPU的响应之后DMA发出内存地址和控制信号,然後进行传送,传送结束。如果是写寄存器的话就需要DMA传输需要配置要传输的buf长度,源地址就是buf的长度,目标地址就是寄存器地址,DMA使用的是总线地址。所以USB里当有数据需要传输时我们又不能一直等设备,就只好DMA在有I/O需求的时候调用,由DMA控制系统总线。 

python的缓存协议,python内置对象中支持缓存协议得有bytes和bytearray,str通过encode转化为bytes,bytes是byte的序列而str是unicode的序列。网络上传输因为需要使用二进制流所以需要转化将本身的str转化为bytes从而在网络上传输。提到缓存协议是因为luma.core中是使用了PIL初始化MAX7219模块的缓存区,所以我们在MAX7219上打印东西就相当于在空白图像上画画一样。还有一种是NumPy风格的,也就是用了PIL中的Image.new(mode,size)这种方式初始化缓存。https://github.com/pyserial/pyserial/tree/master/serial
https://github.com/doceme/py-spidev/blob/master/spidev_module.c
SPI接口是有发送缓存区的,通过TXBMT判断发送缓存区是否为空,置位时表示数据已经进入移位寄存器开始发送。
SPIF是发送完成后的中断标志位,数据发送完毕后硬件置位,如果中断允许则进入中断服务程序。
也就是说先发送缓存区,再移位寄存器。

串口通信协议主要就是定义了一种数据传输格式,比如实际数据和控制数据,传输的时候跟socket通信挺相像的,还可以定义异步传输(asyncio.Protocol),定义好了传输然后就是读写+编解码,也就是也就是个通信协议,不同之处在于串口的连接方法了。我们平时用的BLCA(bind/listen/connect/accept)是同步的,也就是说会阻塞知道有数据传进来,这是一种比较低级的控制方法了。再高级一点就是select/poll/epoll,这种方式可以监听fd_set,有数据来了再处理,通过客户端套接字和服务器端套接字的缓存内容判断是否有新连接还是老客户,这种异步可以让CPU在没有数据到来的时候干别的事,不会被IO阻塞了。再高级的就是asyncio,我们平时调用asyncio有一个概念叫协程,也就是在一个线程内部的协程类似于一个进程内的多线程,使用async/await来实现,await其实也就是yield from,就是说在一个服务器内有很多IO操作时不用等待这个IO返回再进行下一个操作,而是可以让这个IO在后台等待,这个时候CPU可以去处理下一个协程,比如await asyncio.sleep(5),就是说可以去做别的事(等待5秒这件事,可以替换成别的事件),一旦收到了IO结果就立即回到await之前的协程,就算只sleep了3秒也要回去。
还有就是事件循环,我们需要先创建事件循环,然后定义协程,之后再将协程放到事件循环当中运行即可。多个协程任务不用等到这个协程任务做完才做下一个,而是可以在做前一个协程的阻塞过程中运行下一个协程。

 

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

树莓派+8x32的MAX7219点阵模块显示字符串 的相关文章

  • 传统目标检测方法研究(一)

    1 传统算法目标检测 区域选择 gt 特征提取 gt 特征分类 1 1 区域选择 python 实现 图像滑动窗口 区域选取 首先选取图像中可能出现物体的位置 由于物体位置 大小都不固定 因此传统算法通常使用滑动窗口 Sliding Win
  • db2中各个类型互相转换处理

    给数字左侧自动占位补零 digits函数 digits 参数 digits里的参数必须是整型参数 可以是smallint int bigint decimal 其中smallint占5位 int占10位 bigint占19位 decimal
  • unity 坐标系

    https blog csdn net qq 34536551 article details 90269908
  • 什么是多态?对于多态的理解....

    什么是多态 我们都知道面向对象有四个基本特性 抽象 封装 继承 多态 概括可以理解为 抽象 封装 继承 是多态的基础 多态是抽象 封装 继承的表现 多态 是Java中非常重要的一部分 简单理解 不同类的 对象 对同一消息 做出了不同的响应就
  • 电脑重装系统(U盘)

    Windows10 1 首先需要准备一个8G或以上的U盘 空的 2 前往浏览器下载windows安装工具 网址如下 https www microsoft com zh cn software download windows10 3 下载
  • CentOS7 挂载磁盘出错mount: /dev/sdb is write-protected, mounting mount: unknown filesystem type '(null)'

    报错信息如下 root localhost mount dev sdb image mount dev sdb is write protected mounting read only mount unknown filesystem t
  • 掌握Python的X篇_19_函数的定义与调用

    文章目录 1 函数 2 函数的定义 3 函数调用 1 函数 在Python 函数是一种基本的编程接口 因为函数的调用只关心参数输入和返回值 所以使得我们可以更好地进行编程分工 以下程序的功能是得到输入的三个数字的平方值 根据前面所学的话 可
  • Blender编程入门

    在本教程中 我们将学习一些 Blender 脚本技术 比如如何使用代码处理 操作 复制和动画网格图元 要结合所有这些技术 我们将创建一个波浪形的锥形图案 一个看起来很酷的动画 你可以将其转换为循环 GIF 我将使用bpy data模块中的一
  • 一位程序员工作10年总结的13个忠告

    原文网址 http zhangxpower iteye com blog 1145448 展望未来 总结过去10年的程序员生涯 给程序员小弟弟小妹妹们的一些总结性忠告 走过的路 回忆起来是那么曲折 把自己的一些心得体会分享给程 序员兄弟姐妹
  • oracle数据库存储过程基本语法

    oracle数据库存储过程 一 基本语法 数据类型 一 字符类型 字符串数据类型还可以依据存储空间分为固定长度类型 CHAR 和可变长度类型 varchar2 nvarchar2 两种 1 char类型 定长字符串 会用空格填充来达到器最大
  • WSL 修改默认用户

    通常可以通过以下命令来指定进入 wsl 的时候使用的用户 wsl u
  • STM32驱动HX711称重模块

    使用模块如下图所示 使用单片机为STM32C8T6 引脚DT gt PB7 SCK gt PB6 使用通道A 下面是驱动程序 void GPIO Weigh Init void GPIO InitTypeDef GPIO InitStruc
  • 设计模式-单一职责原则介绍与理解

    描述 一个类应该专注于实现一个功能 好处 便于代码复用 举例 俄罗斯方块游戏 首先可以想到的是游戏逻辑与界面的分离 也就是说逻辑一个类 界面部分一个类 这样做的好处就是我们可以复用游戏逻辑的代码 例如我们用java写了一个基于PC端的俄罗斯
  • JAVA实现压缩解压文件

    1 源码运行前准备好文件夹 2 源码 package com els modules inquiry service impl import java io File import java io FileInputStream impor
  • P2PSim中重要函数的说明

    环境 RedHat9上安装的P2Psim0 3 目的 在P2Psim使用Vivaldi协议仿真 现状 主程序代码中关于vivaldi协议的部分注释掉了 思路 从主函数分析代码 找到原因 vivaldi协议主函数是vivalditest C
  • windows server 2012R2 部署安装 hmail

    windows server 2012R2 部署安装 hmail 环境说明 系统 windows server2012 R2软件版本 hMailServer 5 6 7 B2425 exe 邮件客户端 foxmail7 2版本 加密工具 h
  • Python21天打卡Day20-可变参数、关键字参数

    在 Python 中 可变参数允许函数接受任意数量的参数 这些参数被封装成一个元组 Tuple 或列表 List 并作为参数传递给函数 Python 中有两种类型的可变参数 args 用于传递可变数量的位置参数 Positional Arg
  • 【Docker系列】从头学起 Docker——docker run 命令详解

    文章目录 作用 语法格式 docker run 执行流程 options 说明 实际例子 例一 例二 例三 例四 例五 例六 例七 例八 总结 例九 作用 创建一个新的容器并运行一个命令 语法格式 docker run OPTIONS IM
  • springboot项目打包(exe+jdk/jre+mysql)跨平台一键安装

    SpringBoot项目打包 exe jdk jre mysql 跨平台一键安装 1 Spring Boot将javaFX应用打包为jar包 1 1 pom xml安装Spring boot maven plugin
  • 【MyBatis-Plus】详解Wrappers.<T> lambdaQuery()以及常用过滤方法

    Wrappers

随机推荐

  • Java 动态代理作用是什么?

    主要用来做方法的增强 让你可以在不修改源码的情况下 增强一些方法 在方法执行前后做任何你想做的事情 甚至根本不去执行这个方法 因为在 InvocationHandler的invoke方法中 你可以直接获取正在调用方法对应的 Method对象
  • linux kernel --component组件用法

    kernel component组件用法 linux component组件架构分析
  • 如何用mac搭建本地svn服务器(如何将mac变成版本管理服务器)

    前言 一 搭建本地svn服务器 1 建立代码库 2 配置文件修改 3 启动本地svn服务 二 搭建过程中常见问题 如果Mac os升级到10 0以上 自带的svn不支持了怎么办 三 mac本地使用svn软件管理svn库 cornerston
  • Linux多进程数据交换--共享内存

    个人博客地址 https cxx001 gitee io 基础 在linux系统开发当中 时常需要在多个进程之间交换数据 在多个进程之间交换数据 有很多方法 但最高效的方法莫过于共享内存 linux共享内存是通过tmpfs这个文件系统来实现
  • 第二十八节、基于深度学习的目标检测算法的综述(附代码,并附有一些算法英文翻译文章链接))...

    在前面几节中 我们已经介绍了什么是目标检测 以及如何进行目标检测 还提及了滑动窗口 bounding box 以及IOU 非极大值抑制等概念 这里将会综述一下当前目标检测的研究成果 并对几个经典的目标检测算法进行概述 本文内容来自基于深度学
  • APK 逆向工程 - 解析 apk 基本信息和方法调用图

    导读 在 Android 开发中 我们很少使用 Android 逆向去分析 apk 文件的 但是作为一个测试人员 我们要对这个 apk 文件进行一系列的分析 审核 测试 这篇文章讲解如何解析一个 apk 文件 主要从下面几方面介绍 解析前准
  • mysql show para_mysql中show命令的详细用法

    经过我测试的语句 show procedure status 显示数据库中所有存储的存储过程基本信息 包括所属数据库 存储过 程名称 创建时间等 show create procedure sp name 显示某一个存储过程的详细信息 a
  • MongoDB安装和批量写入

    本文主要以Ubuntu系统为例 记录安装部署MongoDB社区版 并进行批量数据写入 安装部署主要依据MongoDB官网指引 数据写入脚本为个人编写 如有需要可以直接使用 1 导入包管理系统使用的公钥 wget qO https www m
  • UML中依赖和关联,关联,聚合和组合的区别

    在UML中 依赖和关联经常无法进行区分 在类图中 不知道什么时候使用依赖 什么时候使用关联 来定义两个类之间的关系 今天看了一篇帖子 对这两种关系做了比较生动的区分 依赖指的是两个类之间发生的关系输入偶然发生的 例如人和船之间的关系就是这种
  • Video_Codec_SDK压缩编码视频并封装为MP4格式

    在深度学习处理视频过程中 通常是先解码视频获取视频帧并转为cv Mat后进行处理 本章介绍如何将处理后的图片使用GPU编码为视频码流并封装为MP4格式 开发硬件 I7 9750H GTX1660ti 操作系统 Ubuntu16 04 驱动版
  • 24种设计模式之单例模式(饿汉式、懒汉式)

    一 单例模式 单例模式 Singleton Pattern 是指确保一个类在任何情况下都绝对只有一个实例 并提供一个全局访问点 单例模式是创建型模式 单例模式在现实生活中应用也非常广泛 例如 总统 班主任等 J2EE标准中的ServletC
  • 理解SPDX

    SPDX The Software Package Data Exchange SPDE an open standard for communicating software bill of material information in
  • 基于RFID技术在物流仓储中的解决方案—铨顺宏FUWIT

    一 行业背景 2011年6月8日国务院出台物流行业新国八条 明确指出要推进物流技术创新和应用 加强物流新技术自主研发 加快仓储物流设备研制 制定和推广物流标准 适时启动物联网的应用示范 推进物流信息资源开放共享 物流信息化 指在物流活动中全
  • 基于Opencv的水位识别,液面识别、高度识别

    Update 代码已经上传到github上了 可以点这里 Cutting 一直说这要整理一下Computer Vision课程的大作业 拖了好久 这两天忙着写一个订单处理的第三方库 陷入了僵局 所以换个口味 把大作业整理一下 Require
  • python入门到精通 _7异常、模块与包

    文章目录 1 异常捕获 1 1 捕获常规异常 1 2 捕获指定异常 1 3 捕获多个异常 1 4 异常的finally 2 模块的导入与自定义 2 1 模块的导入 2 2 模块的自定义 3 安装第三方包与自定义 3 1 自定义包 3 2 安
  • 生成3d地图obj(可导入到ppt中使用)

    一 效果 二 使用 1 网址 https 3d mapper com MAP index php 2 注册 3 使用 创建3D地图 正在生成中 有以下设置功能 截图 管理你的地图
  • 按键松手检测 - 检测是否连续按下

    u8 KEY Scan void static u8 keyup 1 防止检测多次 if keyup KEY0 0 KEY1 0 KEY3 0 delay ms 50 去抖 if KEY0 0 KEY1 0 KEY3 0 keyup 0 i
  • 代码质量有哪些评判标准?

    描述代码质量的词 灵活性 flexibility 可扩展性 extensibility 可维护性 maintainability 可读性 readability 可理解性 understandability 易修改性 changeabili
  • Kruskal算法代码实现

    package com kruskal import java util Arrays public class KruskalCase private int edgeNum 边的个数 private char vertexs 顶点个数
  • 树莓派+8x32的MAX7219点阵模块显示字符串

    https blog csdn net zyaiwmy article details 70224250 utm source blogxgwz1 按照上面这篇文章进行配置了驱程 修改了一下示例代码 效果如下 这里记一下项目的github地