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