单片机
返回首页

STC12硬件SPI驱动MAX7219点阵LED

2022-08-05 来源:csdn

max7219是一个用于驱动8位7段数字LED或者8x8点阵LED的驱动芯片, 以列扫描的方式, 用16个pin管理64个发光点, 显示8个数字时刷新率为500-1300Hz, 典型值为800Hz.


pin脚功能

DIG0 - DIG7: 这个8个pin, 分别代表一个7段数字+点号

SEGA - SEGG, DP: A-G每个代表7段数字里的一段, DP代表数字间的小数点

每一段的驱动电流是40mA, 如果负载需要更大的电流, 需要外接硬件驱动

V+, GND: 电压和接地

DIN: 串行数据输入

CS: 片选, 当电平下拉后从串行口按时脉移入移位寄存器, 当电平上拉后锁存

DOUT: 串行数据输出, 这个口用于级联

级联的N个MAX7219, 可以看成有N个串联的16位移位寄存器

如果要对第N位操作, 要经过16*N个时脉后数据才能到达, 这时候CS上拉, 将命令锁存.


通信方式

通信协议为SPI, 接受SPI Master的输入, 不返回数据

MAX7219, 不管CS是什么电平, DIN的数据都会随着时脉写入移位寄存器

MAX7221, 只有当CS下拉时, 才会将数据从DIN写入, 或者往DOUT写出

CS必须在第16个数写入后, 下一个时脉上升沿到来前拉高, 否则数据会丢失

数据是MSB, 大值在前

对于16个bit, 前8个(D15-D08)为地址, 实际上使用的只有D11-D8这4个, 后8个D7-D0为数据


通信的前地址

共有14个

0x?0: No-Op, 用于将数据输出到DOUT

0x?1: 第一个数字

0x?2: 第二个

0x?3: 第三个

0x?4: 第四个

0x?5: 第五个

0x?6: 第六个

0x?7: 第七个

0x?8: 第八个

0x?9: 数字解码模式

0x?A: 亮度, 0x00到0xFF

0x?B: 扫描限制(限制显示的列数), 取值0-7, 数字越小, 单列的亮度越大, 一般情况下不要低于3.

0x?C: 状态(关闭, 普通)

0x?F: 测试状态(测试, 普通)


级联传输

使用No-Op地址操作实现级联传输

例如, 对第四块MAX7219写入

首先按预设地址写入地址, 写入值

写入三次NoOp操作(0x?0??), ?号代表随意值

当CS拉高后, 这4个MAX7219都会收到操作地址和操作值, 但是前三块看到的是NoOp, 所以前三块无动作

用STC12的硬件SPI驱动

STC12C5A60S2系列是带内建SPI支持的, 基于HML_FwLib_STC12封装库可以方便地实现MAX7219的点阵驱动, 代码:


/*****************************************************************************/

/** 

 * file        spi_max7219.c

 * author      IOsetting | iosetting@outlook.com

 * date        

 * brief       Example code of SPI driving dot matrix module

 * note        The module chip is MAX7219, pin connection:

 *              P1_3        => CS, 

 *              P1_5(MOSI)  => DIN, 

 *              P1_7(SPCLK) => CLK

 * 

 * version     v0.1

 * ingroup     example

 * remarks     test-board: Minimum System; test-MCU: STC12C5AF56S2

******************************************************************************/


/*****************************************************************************

 *                             header file                                   *

 *****************************************************************************/

#include 'hml/hml.h'


#define CS P1_3


#define DECODE_MODE  0x09

#define INTENSITY    0x0A

#define SCAN_LIMIT   0x0B

#define SHUT_DOWN    0x0C

#define DISPLAY_TEST 0x0F


const byte numbers[]={

0x00,0x00,0x7C,0xC6,0xC6,0xCE,0xD6,0xD6,  // -0-.  

0xE6,0xC6,0xC6,0x7C,0x00,0x00,0x00,0x00,

0x00,0x00,0x18,0x38,0x78,0x18,0x18,0x18,  // -1-  

0x18,0x18,0x18,0x7E,0x00,0x00,0x00,0x00,  

0x00,0x00,0x7C,0xC6,0x06,0x0C,0x18,0x30,  // -2-  

0x60,0xC0,0xC6,0xFE,0x00,0x00,0x00,0x00,  

0x00,0x00,0x7C,0xC6,0x06,0x06,0x3C,0x06,  // -3-  

0x06,0x06,0xC6,0x7C,0x00,0x00,0x00,0x00,  

0x00,0x00,0x0C,0x1C,0x3C,0x6C,0xCC,0xFE,  // -4-  

0x0C,0x0C,0x0C,0x1E,0x00,0x00,0x00,0x00,  

0x00,0x00,0xFE,0xC0,0xC0,0xC0,0xFC,0x0E,  // -5-  

0x06,0x06,0xC6,0x7C,0x00,0x00,0x00,0x00,  

0x00,0x00,0x38,0x60,0xC0,0xC0,0xFC,0xC6,  // -6-  

0xC6,0xC6,0xC6,0x7C,0x00,0x00,0x00,0x00,  

0x00,0x00,0xFE,0xC6,0x06,0x06,0x0C,0x18,  // -7-  

0x30,0x30,0x30,0x30,0x00,0x00,0x00,0x00,  

0x00,0x00,0x7C,0xC6,0xC6,0xC6,0x7C,0xC6,  // -8-  

0xC6,0xC6,0xC6,0x7C,0x00,0x00,0x00,0x00, 

0x00,0x00,0x7C,0xC6,0xC6,0xC6,0x7E,0x06,  // -9-  

0x06,0x06,0x0C,0x78,0x00,0x00,0x00,0x00};


void Write7219(byte addr, byte dat)

{

    CS = 0;

    SPI_RW(addr);

    SPI_RW(dat);

    CS = 1;

}


/*****************************************************************************/

/** 

 * author      IOsetting

 * date        

 * brief       initialize MAX7219

 * param[in]   

 * return      none

 * ingroup     example

 * remarks     

******************************************************************************/

void Init7219(void)

{

    Write7219(SHUT_DOWN,0x01);         // 0x00:shutdown, 0x01:normal

    Write7219(DECODE_MODE,0x00);       // No decode

    Write7219(SCAN_LIMIT,0x07);        // Display 8 digits

    Write7219(INTENSITY,0x00);         // 0x00:min, 0xFF:max

    Write7219(DISPLAY_TEST,0x00);      // 0x00:normal, 0x01:test mode

}


/*****************************************************************************/

/** 

 * author      IOsetting

 * date        

 * brief       initialize SPI

 * param[in]   

 * return      none

 * ingroup     example

 * remarks     

******************************************************************************/

void initSys(void)

{

    SPI_configTypeDef sc;

    sc.baudRatePrescaler = SPI_BaudRatePrescaler_64;

    sc.cpha = SPI_CPHA_1Edge;

    sc.cpol = SPI_CPOL_low;

    sc.firstBit = SPI_FirstBit_MSB;

    sc.pinmap = SPI_pinmap_P1;

    sc.nss = SPI_NSS_Soft;

    sc.mode = SPI_Mode_Master;

    SPI_config(&sc);

    SPI_cmd(ENABLE);

}


void main()

{

    initSys();

    Init7219();


    P1_3 = 1;

    byte pos = 0, size = sizeof(numbers), i, j;

    while(1)

    {

        for (i = 0; i < 8; i++)

        {

            j = (pos + i) % size;

            Write7219(i + 1, numbers[j]);

        }

        pos = (pos + 1) % size;

        sleep(100);

    }

}


参考

关于MAX7219非常有用的说明 https://wayoda.github.io/LedControl/pages/software


进入单片机查看更多内容>>
相关视频
  • RISC-V嵌入式系统开发

  • SOC系统级芯片设计实验

  • 云龙51单片机实训视频教程(王云,字幕版)

  • 2022 Digi-Key KOL 系列: 你见过1GHz主频的单片机吗?Teensy 4.1开发板介绍

  • TI 新一代 C2000™ 微控制器:全方位助力伺服及马达驱动应用

  • MSP430电容触摸技术 - 防水Demo演示

精选电路图
  • PIC单片机控制的遥控防盗报警器电路

  • 红外线探测报警器

  • 使用ESP8266从NTP服务器获取时间并在OLED显示器上显示

  • 用NE555制作定时器

  • RS-485基础知识:处理空闲总线条件的两种常见方法

  • 基于ICL296的大电流开关稳压器电源电路

    相关电子头条文章