`
iaiai
  • 浏览: 2203263 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

树莓派 - MAX7219

 
阅读更多
1.基础:认识MAX7219

拿到MAX7219驱动的LED矩阵,第一件事是先连接并尝试显示图案。使用MAX7219除了需要提供GND以及VCC外,只需要再提供三根引脚即可点亮矩阵。其中,DIN引脚输入数据,CS(LOAD)引脚控制数据输入,CLK引脚用于区分每个bit。

MAX的整个写入流程为,首先CS引脚置0,表示允许写入。而后从高位顺序写入16个bit。每个bit的写入方式为首先DIN置为要写入的bit值,而后CLK产生一个下降沿(图中为上升沿,不知道为何有差别)即被读入。最后CS引脚置1表示写入结束。

时序图如下:

在运行之前,需要进行一次初始化,其行为是向某几个特定的地址写入特定的值。至少需要写入两个地址,第一个是0x0b,写入0x07表示扫描显示所有行。第二个是0x0c,写入1表示进入工作模式。

而后点阵上每一行都有其地址,如第一行是0x01到第八行是0x08,每次向固定行的地址写入一个8位二进制数即可在指定行上显示图案。



2.      树莓派对GPIO的访问——虚拟文件系统访问

Linux可以通过访问sys/class/gpio下的一些文件,通过对这些文件的读写来实现对于GPIO的访问。

树莓派下面的可用的GPIO如右图所示,需要注意树莓派一代和二代的区别。

这里根据大大的博客攻略,我首先尝试用shell。代码直接参考了大大的。先试着玩一下。
!/bin/bash

# DIN, CS, CLK的GPIO口位置
DIN=4
CS=3
CLK=2

# 一些文件路径
GPIO_BASE=/sys/class/gpio
GPIO_EXPORT=${GPIO_BASE}/export
GPIO_UNEXPORT=${GPIO_BASE}/unexport

BIN=(00000001 00000010 00000011 00000100 00000101 00000110 00000111 00001000)

# 生成指定GPIO引脚的文件夹位置
function GPIO(){
    echo ${GPIO_BASE}/gpio$1
}

# 将某个引脚export到用户态
function GPIO_export(){
    if [ -d `GPIO $1` ]; then
        echo GPIO pin $1 found in folder.
    else
        echo $1 > ${GPIO_EXPORT}
    fi
}

# unexport某个引脚
function GPIO_unexport(){
    if [ -d `GPIO $1` ]; then
        echo $1 > ${GPIO_UNEXPORT}
    else
        echo GPIO pin $1 not found.
    fi
}

# 改变某个引脚的方向
function GPIO_direction(){
    echo $2 > `GPIO $1`/direction
}

# 改变某个引脚的值
function GPIO_set(){
    echo $2 > `GPIO $1`/value
}

# 改变DIN的值
function GPIO_DIN(){
    GPIO_set $DIN $1
}

# 改变CS的值
function GPIO_CS(){
    GPIO_set $CS $1
}

# 改变CLK的值
function GPIO_CLK(){
    GPIO_set $CLK $1
}

# 向MAX7219发送一个byte的值
function Matrix_send_char(){
    local i=1
    for ((i=1;i<=8;i++)); do
        chr=`expr substr $1 $i 1`
        GPIO_DIN $chr
        GPIO_CLK 1
        GPIO_CLK 0
    done
}

# 向MAX7219发送一次完整的信号
function Matrix_send_word(){
    GPIO_CS 1
    GPIO_CS 0
    GPIO_CLK 0
    Matrix_send_char $1
    Matrix_send_char $2
    GPIO_CS 1
}

# 初始化GPIO引脚
function GPIO_init(){
    GPIO_export $DIN
    GPIO_export $CS
    GPIO_export $CLK

    sleep 2

    GPIO_direction $DIN out
    GPIO_direction $CS out
    GPIO_direction $CLK out
}

# 清除GPIO引脚
function GPIO_clear(){
    GPIO_unexport $DIN
    GPIO_unexport $CS
    GPIO_unexport $CLK
}

# 在点阵上显示数据
function Matrix_render(){
    local i=1
    for ((i=0;i<8;i++)); do
        echo $i $1
        Matrix_send_word ${BIN[$i]} $1
        shift
    done
}

# 使用文件中的数据进行显示
function Matrix_render_file(){
    local tmp=(`cat $1`)
    Matrix_render "${tmp[@]}"
}

# 使用某个图案清屏
function Matrix_clear(){
    local STR=(
        00000000
        01100110
        11111111
        11111111
        11111111
        01111110
        00111100
        00011000
    )
    Matrix_render "${STR[@]}"
}

# 初始化点阵
function Matrix_init(){
    # 编码模式
    Matrix_send_word 00001001 00000000
    # 亮度
    Matrix_send_word 00001010 00000011
    # 扫描数码管个数
    Matrix_send_word 00001011 00000111
    # 工作模式
    Matrix_send_word 00001100 00000001

    # 初始化完毕后清屏显示默认图案
    Matrix_clear
}


在终端中:
source matrix.sh  
GPIO_init  
Matrix_init  

效果如图:

3.      树莓派对GPIO的访问——使用库

这里我使用了wiring库,非常容易上手。关键函数:digitalWrite()写GPIO;pinMode()设置GPIO方向;

需要注意的是它的管脚编号和树莓派不同。

上代码:
#include <wiringPi.h>
#include <stdio.h>

#define uchar unsigned char
#define uint unsigned int

#define DecodeMode      0x09  //译码模式寄存器
#define Intensity       0x0a  //亮度寄存器
#define ScanLimit       0x0b  //扫描位数寄存器
#define ShutDown        0x0c  //低功耗模式寄存器
#define DisplayTest     0x0f  //显示测试寄存器

#define ShutdownMode    0x00  //低功耗方式
#define NormalOperation 0x01  //正常操作方式
#define ScanDigit       0x07  //扫描位数设置,显示8位数码管
#define DecodeDigit     0x00  //译码设置,8位均为非译码
#define IntensityGrade  0x0a  //亮度级别设置
#define TestMode        0x01  //显示测试模式
#define TextEnd         0x00  //显示测试结束,恢复正常工作模式

#define DIN 8
#define CS 9
#define CLK 7

uchar buffer[8]={0x00,0x66,0xff,0xff,0xff,0xff,0x7e,0x3c,0x18};
void delay(uint t){
	uint i;
	while(t--)
		for (i = 0; i < 125; i++);
}

void sendChar(char ch){
	char i, tmp;
	for(i = 0; i < 8; i++){
		tmp = ch & 0x80;
		
		if(tmp) 
			digitalWrite(DIN, HIGH);
		else 
			digitalWrite(DIN, LOW);
		ch = ch << 1;
		digitalWrite(CLK, HIGH:);
		digitalWrite(CLK, LOW);
	}
}

void writeWord(char addr, char num){
	digitalWrite(CS, HIGH);
	digitalWrite(CS, LOW);
	digitalWrite(CLK, LOW);
	sendChar(addr);
	sendChar(num);
	digitalWrite(CS, HIGH);
}

void write(){
	char i;
	for(i = 0; i < 8; i++){
		printf("%d %d\n",i, buffer[i]);
		writeWord(i + 1, buffer[i]);
	}
}

void init(){
	writeWord(0x09, 0x00);
	writeWord(0x0a, 0x03);
	writeWord(0x0b, 0x07);
	writeWord(0x0c, 0x01);
}


int main(){
	wiringPiSetup();

	pinMode(DIN, OUTPUT);
	pinMode(CS, OUTPUT);
	pinMode(CLK, OUTPUT);

	init();
	wirte();


	return 0;

}

Makefile:
matrix:matrix.o    
      gcc matrix.c -o matrix -lwiringPi    
clean:    
      rm -f matrix matrix.o

结果和前面一样。LED矩阵上显示了爱心。

把上面代码改为python
#!/usr/bin/env python
# encoding: utf-8

import RPi.GPIO as GPIO
import time

DIN = 12
CS = 16
CLK = 18

GPIO.setmode(GPIO.BOARD)
GPIO.setup(DIN,GPIO.OUT)
GPIO.setup(CS,GPIO.OUT)
GPIO.setup(CLK,GPIO.OUT)

buffer = ['00000000','01100110','11111111','11111111','11111111','01111110','00111100','00011000']
#buffer = [0x00,0x66,0xff,0xff,0xff,0x7e,0x3c,0x18]

def send(byteData):
    for bit in range(0,8):
        if(byteData & 0x80):
            GPIO.output(DIN,True)
        else:
            GPIO.output(DIN,False)
        byteData = byteData<<1
        GPIO.output(CLK,True)
        GPIO.output(CLK,False)

def writeWord(addr,num):
    GPIO.output(CS,True)
    GPIO.output(CS,False)
    GPIO.output(CLK,False)
    send(addr)
    send(num)
    GPIO.output(CS,True)

def wt():
    for i in range(0,8):
        print("%d %d" %(i,int(buffer[i],2)))
        writeWord(i+1,int(buffer[i],2))

def initData():
    writeWord(0x09,0x00)
    writeWord(0x0a,0x03)
    writeWord(0x0b,0x07)
    writeWord(0x0c,0x01)
    writeWord(0xff,0x00)

try:
    initData()
    wt()
except KeyboardInterrupt:
    pass

time.sleep(2)
GPIO.cleanup()
  • 大小: 75.6 KB
  • 大小: 129.7 KB
  • 大小: 506.6 KB
  • 大小: 283.1 KB
分享到:
评论
1 楼 liangzai_cool 2019-04-01  
请教一下,文中,shell、C、Python三种方式控制led点阵,对应的树莓派版本分别是多少呢?

相关推荐

    基于树莓派和max7219模块的LED矩阵钟表及闹铃设计源码

    该项目为基于树莓派和max7219模块的LED矩阵钟表及闹铃设计源码,包含335个文件,包括280个Java源文件、24个WAV音频文件、14个XML配置文件、5个JPG图片文件、2个YML配置文件、2个PNG图片文件、1个.gitignore文件、1个...

    rpi_pico_max7219:Raspberry Pico MAX7219驱动程序和接线

    Raspberry Pico MAX7219矩阵LED 与的Pico集成。 这个脚本有一种方法可以使文本滚动灵感来自接线Pico没有5v引脚,但是VBUS连接到电源输入。 MAX7219需要5v输入,因此Pico的电源必须为5v。 这是SPI0的默认引脚。 MAX...

    DS18B20 + max7219

    标题中的“DS18B20 + max7219”指的是两个电子元件的组合,它们在物联网(IoT)和嵌入式系统中经常被用到,用于温度监测和显示。DS18B20是一款由达拉斯半导体(现为TI德州仪器)制造的一线总线数字温度传感器,而MAX...

    max7219-clj:clojure 的 max7219 库(树莓派)

    最大7219 用于 max7219 LED 矩阵驱动器的 Clojure 库(在树莓派上)。[max7219 " 0.1.2 " ] max7219 是串行接口的 8x8(或 7 段)LED 驱动器。 几个驱动器可以串联起来。 您可以通过 SPI 向驱动程序发送命令和数据...

    毕设&课设&项目&竞赛-基于Stm32 HAL库的Max7219点阵显示驱动库.zip

    基于Stm32 HAL库的Max7219点阵显示驱动库 Max7219 dot matrix display driver library based on Stm32 HAL librar 单片机设计,工具源码,适合毕业设计、课程设计作业,所有源码均经过严格测试,可以直接运行,可以...

    MAX30102测试资料完整版 (2)_max30102_

    **MAX30102测试资料完整版 (2)_max30102_** MAX30102是一款集成了光学心率传感器和环境光传感器的IC,由Maxim Integrated公司生产。这款传感器主要用于健康监测设备,如智能手环、智能手表以及医疗设备中,能够实现...

    树莓派从RS485设备读取信息

    在树莓派上,通常会使用一个RS485转换器(如MAX485)来连接到GPIO引脚,以便与RS485设备通信。 在树莓派上配置RS485通信需要完成以下步骤: 1. **硬件连接**:将RS485转换器连接到树莓派的GPIO引脚,通常使用3.3V...

    max7219rpi2:MAX7219与Raspberry Pi 2接口

    【标题】:“MAX7219与Raspberry Pi 2接口”是指将MAX7219驱动芯片与树莓派2代(Raspberry Pi 2)进行连接,以实现LED矩阵显示或者其他数字输出功能。MAX7219是一款集成了串行输入、并行输出的LED驱动器,常用于控制...

    Max6675-Raspberry-pi-nodejs:用K型热电偶读取温度。 树莓派NodeJS

    最高6675 用K型热电偶读取温度。 Raspberry pi NodeJS。 从npmjs获取代码。 npm i max6675-raspi --save PIN值为BCM GPIO(绿色)。 通用输入输出

    Lab 7:字符设备驱动程序1

    总之,Lab 7的目的是让学生熟悉Linux系统下的GPIO编程,掌握使用C++和Wiring Pi库控制GPIO以及通过MAX7219驱动器控制LED矩阵显示屏的方法。通过这些实践,不仅可以理解底层硬件交互,还能提升在嵌入式系统中的软件...

    Adafruit_MAX31855-1.6.1-py2-none-any.whl.zip

    这个库使得开发人员能方便地在树莓派或其他支持Python的硬件平台上读取和处理这些温度数据。 **热电偶放大器MAX31855功能:** 1. 内部冷结补偿,减少了测量误差。 2. 高精度,提供±0.25°C的分辨率。 3. 内置热电...

    RaspberryDMX:树莓派 HTTP 到 GPIO DMX

    它只花费你的树莓派和 MAX485 RS-485 模块的价格(大约 2 美元)。 该脚本将帮助您创建一种通过网页 HTTP 页面控制 DMX 设备的方法。 你需要什么? 物品 价值 树莓派 MAX485 RS-485 模块 电缆 一些 0.1 针头...

    MAX7219点阵显示模块16屏显示IP

    标题中的“MAX7219点阵显示模块16屏显示IP”指的是使用MAX7219驱动的LED点阵显示屏模块,通过串联16个这样的模块来展示IP地址。这种技术常用于创建大型显示屏或者可视化项目,可以显示数字、字母和其他简单图形。 ...

    BIGTREETECH Octopus 用户手册1

    - 支持Klipper固件,可以与树莓派联机进行3D打印。 - 最多可驱动8路步进电机,4路加热棒,6路可控风扇,其中2路为常开风扇,支持24V, 12V, 5V电源选择。 - 采用Type-C接口,支持联机打印和SD卡脱机打印。 - 电源...

    在树莓派上设置分辨率,修改触摸屏.pdf

    在树莓派上设置分辨率和修改触摸屏是一个关键的操作,特别是在使用非标准分辨率的LCD显示器时。树莓派,一种基于Linux操作系统的微型计算机,有时可能会遇到无法正确识别显示器分辨率导致“无信号”或“蓝屏”问题。...

    Python基于树莓派的垃圾分类识别

    - 将写入好系统的SD卡插入树莓派,启动树莓派。 **1.2 安装必要的软件** - **基础软件安装:** - 在树莓派的终端中运行命令 `sudo apt update` 和 `sudo apt install python3-pip` 更新软件源并安装Python 3的...

    基于树莓派的智能老人监护系统设计.pdf

    该系统的硬件组成包括树莓派、MAX30102模块、GSM模块、4Air530模块等。树莓派B+型作为主控芯片,需要驱动各模块正常工作,且需要串口以便数据有效通信。MAX30102模块是一个集成的脉搏血氧仪和心率监测仪生物传感器的...

    MAX17043锂电池电量计树莓派驱动程序及教程等

    MAX17043/MAX17044是用于手持和便携式设备中锂离子电池的超紧凑、低成本主机侧燃油表系统。MAX17043配置为单锂电池,MAX17044配置为双电池2S电池组。   MAX17043/MAX17044使用一种复杂的锂电池建模方案,...

    Pico-2CH-RS485

    在硬件层面,我们需要一个RS485转换器,如MAX485或SP3485,将其连接到树莓派RP2040-ZERO的GPIO引脚。通常,转换器的RO(Receiver Output)和DI(Driver Input)连接到GPIO引脚,而DE(Driver Enable)和RE(Receiver...

Global site tag (gtag.js) - Google Analytics