GD32F407VE天空星开发板的MAX7219的8x8点阵屏驱动的实现
GD32F407VE天空星开发板的MAX7219的8x8点阵屏驱动的实现
MAX7219芯片引脚

8*8点阵屏共阴

一、硬件基础
1.1 共阴与共阳结构
点阵屏根据LED连接方式分为共阴极和共阳极两种:
| 特性 | 共阴极 (Common Cathode) | 共阳极 (Common Anode) | 
|---|---|---|
| 公共端接法 | 所有 阴极(-) 接 地 (GND) | 所有 阳极(+) 接 电源 (VCC) | 
| MCU控制端 | 控制 阳极(+) | 控制 阴极(-) | 
| 点亮条件 | MCU输出 高电平 (HIGH) | MCU输出 低电平 (LOW) | 
| 电流方向 | MCU -> 灯 -> 地 | 电源 -> 灯 -> MCU | 
| 俗称 | 源电流 驱动 (Source Current) | 灌电流 驱动 (Sink Current) | 
1.2 段和位概念
- 
段 (Segment):构成显示内容的基本单元,在点阵屏中通常指一行中的LED灯
-
 - 
位 (Digit/Position):显示位置,在点阵屏中表示选择哪一行进行显示

 
1.3 MAX7219驱动芯片
MAX7219是一款集成化的LED显示驱动芯片,具有以下特点:
- 支持驱动8位7段数码管或8x8点阵屏
 - 3线串行接口(SPI兼容)
 - 可编程亮度控制
 - 支持多芯片级联(菊花链)
 
二、软件驱动实现
2.1 硬件初始化
首先需要初始化SPI接口和GPIO引脚:
//////////////////// 点阵屏接线定义 ////////////////////
#define DM_NUM				3			// 点阵屏数量#define DM_CS_RCU			RCU_GPIOC
#define DM_CS_PIN			GPIOC, GPIO_PIN_9
#define DM_CS(val)			gpio_bit_write(DM_CS_PIN, (val) ? SET : RESET)#define DM_WR(dat)			SPI2_hard_write(dat)void DM_init() {printf("==DM_init==\n");// CS引脚配置为推挽输出GPIO_output(DM_CS_RCU, DM_CS_PIN, GPIO_OTYPE_PP, 1);// 配置MAX7219寄存器DM_configure();
}
2.2 MAX7219寄存器配置
MAX7219通过配置寄存器来实现各种功能:
void DM_configure() {uint8_t i = 0;// 译码模式:不译码(用于点阵屏)DM_CS(0);for(i = 0; i < DM_NUM; i++) {DM_WR(0x09);  // 地址:译码模式寄存器DM_WR(0x00);  // 数据:不译码模式}DM_CS(1);// 亮度设置(0x00-0x0F,共16级)DM_CS(0);for(i = 0; i < DM_NUM; i++) {DM_WR(0x0a);  // 地址:亮度寄存器DM_WR(0x01);  // 数据:亮度级别1}DM_CS(1);// 扫描界限:显示8位DM_CS(0);for(i = 0; i < DM_NUM; i++) {DM_WR(0x0b);  // 地址:扫描界限寄存器DM_WR(0x07);  // 数据:显示0-7位}DM_CS(1);// 工作模式:正常模式DM_CS(0);for(i = 0; i < DM_NUM; i++) {DM_WR(0x0c);  // 地址:关闭模式寄存器DM_WR(0x01);  // 数据:正常模式}DM_CS(1);// 显示测试:关闭测试模式DM_CS(0);for(i = 0; i < DM_NUM; i++) {DM_WR(0x0f);  // 地址:显示测试寄存器DM_WR(0x00);  // 数据:正常显示}DM_CS(1);
}
2.3 数据显示函数
实现数字和自定义数据的显示功能:
// 数字0-9的点阵显示编码表
static uint8_t table[10][8] = {{0x3C, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x3C}, // 0{0x08, 0x18, 0x28, 0x08, 0x08, 0x08, 0x08, 0x3E}, // 1{0x3C, 0x42, 0x02, 0x04, 0x18, 0x20, 0x40, 0x7E}, // 2{0x3C, 0x42, 0x02, 0x1C, 0x02, 0x02, 0x42, 0x3C}, // 3{0x04, 0x0C, 0x14, 0x24, 0x44, 0x7E, 0x04, 0x04}, // 4{0x7E, 0x40, 0x7C, 0x02, 0x02, 0x02, 0x42, 0x3C}, // 5{0x3C, 0x42, 0x40, 0x7C, 0x42, 0x42, 0x42, 0x3C}, // 6{0x7E, 0x02, 0x04, 0x08, 0x10, 0x10, 0x10, 0x10}, // 7{0x3C, 0x42, 0x42, 0x3C, 0x42, 0x42, 0x42, 0x3C}, // 8{0x3C, 0x42, 0x42, 0x42, 0x3E, 0x02, 0x42, 0x3C}  // 9
};/*** @brief 设置点阵显示数字* @param index 点阵索引(0~DM_NUM-1)* @param num   要显示的数字(0-9)*/
void DM_set_num(uint8_t index, uint8_t num) {if (index >= DM_NUM || num > 9) return;DM_set_data(index, table[num]);
}/*** @brief 设置点阵显示数据* @param index 点阵索引* @param dat   点阵数据(8字节)*/
void DM_set_data(uint8_t index, uint8_t dat[8]) {if (index >= DM_NUM) return;memcpy(buff[index], dat, 8);
}/*** @brief 刷新显示*/
void DM_display() {uint8_t i = 0, j = 0;for(i = 1; i < 9; i++) { // 遍历1-8行DM_CS(0); // CS拉低开始传输for(j = 0; j < DM_NUM; j++) { // 遍历所有点阵屏DM_WR(i);              // 发送行地址DM_WR(buff[j][i-1]);   // 发送该行数据}DM_CS(1); // CS拉高结束传输}
}
三、高级功能实现
3.1 动画显示
通过多帧数据实现动画效果:
// 定义动画帧数据(圆形缩放动画)
static uint8_t animation_frames[3][8] = {{0x18, 0x24, 0x42, 0x81, 0x81, 0x42, 0x24, 0x18}, // 大爱心{0x00, 0x3C, 0x42, 0x42, 0x42, 0x42, 0x3C, 0x00}, // 中爱心{0x00, 0x00, 0x18, 0x24, 0x24, 0x18, 0x00, 0x00}  // 小爱心
};void DM_animation_demo() {for(int frame = 0; frame < 3; frame++) {DM_set_data(0, animation_frames[frame]);DM_display();delay_ms(500); // 延时500ms}
}
3.2 菊花链级联
MAX7219支持菊花链连接,可以节省MCU的IO资源:
//////////////////// 菊花链接线说明 ////////////////////
/*  接线说明
交互板           GD32F407CLK ===>  PC10CS  ===>  PC9IN  ===>  PC125V  ===>  5VGND  ===>  GND级联交互板	     上面的交互板CLK ===>  CLKCS  ===>  CSIN  ===>  OUT5V  ===>  5VGND  ===>  GND
*/
菊花链连接的特点:
- 优势:节省I/O口,布线简单
 - 劣势:更新速度慢,必须整体更新
 - 可靠性:链中一个设备故障会影响后续所有设备
 
四、SPI驱动实现
MAX7219使用SPI通信协议,需要正确配置SPI接口:
// SPI配置
#define SPI2H_PSC		      SPI_PSC_4          // 预分频
#define SPI2H_CPOL_CPHA		  SPI_CK_PL_LOW_PH_1EDGE  // 模式0
#define SPI1H_PARAM_ENDIAN	  SPI_ENDIAN_MSB     // 大端模式void SPI2_hard_init() {// GPIO初始化GPIO_output_af(SPI2H_SCL_RCU, SPI2H_SCL_PORT, SPI2H_SCL_PIN, GPIO_OTYPE_PP, SPI2H_SCL_AF);GPIO_output_af(SPI2H_MOSI_RCU, SPI2H_MOSI_PORT, SPI2H_MOSI_PIN, GPIO_OTYPE_PP, SPI2H_MOSI_AF);// SPI初始化rcu_periph_clock_enable(RCU_SPI2);spi_parameter_struct spi_struct;spi_struct_para_init(&spi_struct);spi_struct.device_mode          = SPI_MASTER;spi_struct.trans_mode           = SPI_TRANSMODE_FULLDUPLEX;spi_struct.frame_size           = SPI_FRAMESIZE_8BIT;spi_struct.nss                  = SPI_NSS_SOFT;spi_struct.clock_polarity_phase = SPI2H_CPOL_CPHA;spi_struct.prescale             = SPI2H_PSC;spi_struct.endian               = SPI1H_PARAM_ENDIAN;spi_init(SPI2, &spi_struct);spi_enable(SPI2);
}
五、应用示例
5.1 基本数字显示
void main() {// 初始化SPI2_hard_init();DM_init();// 显示数字DM_set_num(0, 3);DM_set_num(1, 5);DM_set_num(2, 7);DM_display();while(1) {// 主循环}
}
5.2 自定义图案显示
// 自定义心形图案
uint8_t heart[8] = {0x00, 0x66, 0xFF, 0xFF, 0xFF, 0x7E, 0x3C, 0x18
};void show_heart() {DM_set_data(0, heart);DM_display();
}
