完整Max7219点阵屏驱动代码Stm32标准库

一 最重要的地址操作

MAX7219 :多位LED显示驱动器。是一种集成化的 串行 输入/输出 共阴极 显示驱动器。

通过 SPI 接口与微控制器通信,3条引线:DIN(即MOSI主设输出从设备接受)、CLK(时钟)、CS(片选)

1 基本模式

  • 模式介绍:MAX7219 内部有多个寄存器:包括 8 个数字显示寄存器、译码模式寄存器、亮度控制寄存器、扫描界限寄存器、关闭模式寄存器和测试模式寄存器等。可以通过写入地址,可以对这些模式及进行开关或调整。
  • 数据传输:在 CLK 的上升沿,DIN 引脚上的数据被锁存到内部移位寄存器中。当 16 位数据发送完毕后,在 LOAD 引脚的上升沿,将移位寄存器中的数据锁存到对应的寄存器中。
  • 要点:每次传输16位数据,CS拉低–>传输16位数据–>每传输一位:产生时钟脉冲 1-0–> 拉高CS引脚,结束通信

每个数字显示寄存器对应一个 8 段 LED 数码管或一个 8×8 点阵的一个字节,用于存储要显示的数据。而当代表点阵屏的时候,可以不考虑译码模式,因为需要手动设置驱动代码控制显示图案,或使用取模软件把信息保存到二维数组中。

(1)寄存器-模式地址
在这里插入图片描述

以下面发送16位数据的函数为例;
void Max7219_SendByte(uint8_t address, uint8_t data)
模式名称作用地址案例/解释
REG1-8简易理解:选中第1-8行某行, 若设为0为代表关闭(行地址1-8,用1字节表示该行的灯亮灭(1,0xff)第一行全亮
译码方式数码管可用,点阵屏不用考虑(0X09,0)开启后,能更方便显示数字,不用再挨个编辑设计
亮度设置0-15可选16级亮度(0X0A,0-15)(0X0A,8)8级亮度
扫描界限设置0-7,代表扫描1-8列,未扫描的地方不亮灯(0X0B,0-7)(0X0B,7)设为7全开即可
停机模式1:正常工作 0:掉电模式(别称)(0X0C,0-1)(0X0C,1)设1就可以,0会直接熄屏
显示模式可设0或1,开启后,以最大亮度全亮(0X0F,0-1)(0X0F,0)没特殊需求不用开

初始化代码设定:

Max7219_SendByte(0X0A,5); //设置初始亮度,可选 0-15
Max7219_SendByte(0X0C,1);//工作模式选择   1:正常工作  0:掉电模式(熄屏但不丢数据)  
Max7219_SendByte(0X0F,0);//测试模式开关   1:开测试模式  0:正常工作
Max7219_SendByte(0X0B,7);	//扫描方式选择  0-7 设置扫描1-8个LED
Max7219_SendByte(0X09,0);	//译码方式  0:为不解码
Max7219_Clear(); 

(2)十进制地址解释
由于地址的巧妙,很多地址在数值上可以直接用十进制代替,所以有了上表格中的0-7,0-15等。如下图,由于D7-D4为0,D3-D0 的四位二进制16级亮度,刚好对应数字:0-15:

亮度寄存器:
在这里插入图片描述

扫描模式寄存器:
原理同上
在这里插入图片描述


2 显示数据

(1)提前取模法

  • 选中某行:即寄存器地址(0x01-0x08分别对应8行)
  • 加上用1字节值表示一行1*8灯的亮灭
  • 即每一行对应一个8个数的数组,显示一个图案至少需要8*8的二位数组,使用取模软件提提前生成:效果如下:
    请添加图片描述

(2)封装函数法

  • 通过二进制计算,设计一个公式:
效果如:
ShowGraph(l,x,y);
  • 效果为:点亮:第L行,【x,y】区间式的点亮Led灯,并支持覆盖操作与单行清除操作,即可通过设定区间,与循环搭配直接一行一行去构建需要的图形,如:

<1> 拼凑数字1:

for(int i=1;i<=8;i++)
	Max7219_ShowGraph(i,4,5); //第i行,点亮[4-5]的灯
	//覆盖
	Max7219_ShowGraph(1,3,3);
	Max7219_ShowGraph(2,2,3);
	Max7219_ShowGraph(8,2,7);
	Max7219_Clear();

在这里插入图片描述
<2 > 支持具备一定规律,或要求动态变化的图案

如:蛇形矩阵

//循环便可实现
for(int i=1;i<=8;i++)
      for(int st=i,ed=1; ;st--,ed++){
          if(st==0&&ed==i+1) break;
				  Max7219_ShowGraph(st,ed,ed); //凡有规律的图形,或动态变化,皆可实现
					Delay_ms(270);
      }
		Max7219_Clear();

请添加图片描述


二 封装功能与测试样例

1 封装函数一览

(1)头文件:完整功能函数

//#include "Max7219.h"
#ifndef __MAX7219_H
#define __MAX7219_H

//接线:Din-A6 Cs-A4  Clk-A5
//模拟SPI,如有需求自己改动即可
#define MAX7219_CS_PIN GPIO_Pin_4
#define MAX7219_CS_PORT GPIOA
#define MAX7219_CLK_PIN GPIO_Pin_5
#define MAX7219_CLK_PORT GPIOA
#define MAX7219_DIN_PIN GPIO_Pin_6
#define MAX7219_DIN_PORT GPIOA

void Max7219_InitDisplay(void); //初始化点阵屏:亮度、模式、测试、扫描、译码方式
void Max7219_Bright(uint8_t dt);//16级亮度:dt=0-15
void Max7219_Clear(void);       //全部清空
void Max7219_Clearline(uint8_t l);//仅清空第L行,L:1-8
void Max7219_SendByte(uint8_t address, uint8_t data);//二进制值点亮灯阵;SPI通信,发送2字节
void Max7219_ShowGraph(uint8_t line,uint8_t x,uint8_t y);//点亮第line行,x-y的点,三者皆:1-8

#endif

(2)预处理数组:图案库:0-9,A-Z

/*
图案模数组
*/
//#include "Preprocessdesign.h" 
//心
uint8_t Heart[8] = {0x38,0x7C,0x7E,0x3F,0x3F,0x7E,0x7C,0x38};


uint8_t data[36][8]={
	{0x3C,0x42,0x42,0x42,0x42,0x42,0x42,0x3C},//0
	{0x10,0x18,0x14,0x10,0x10,0x10,0x10,0x10},//1
	{0x7E,0x2,0x2,0x7E,0x40,0x40,0x40,0x7E},//2
	{0x3E,0x2,0x2,0x3E,0x2,0x2,0x3E,0x0},//3
	{0x8,0x18,0x28,0x48,0xFE,0x8,0x8,0x8},//4
	{0x3C,0x20,0x20,0x3C,0x4,0x4,0x3C,0x0},//5
	{0x3C,0x20,0x20,0x3C,0x24,0x24,0x3C,0x0},//6
	{0x3E,0x22,0x4,0x8,0x8,0x8,0x8,0x8},//7
	{0x0,0x3E,0x22,0x22,0x3E,0x22,0x22,0x3E},//8
	{0x3E,0x22,0x22,0x3E,0x2,0x2,0x2,0x3E},//9
	{0x8,0x14,0x22,0x3E,0x22,0x22,0x22,0x22},//A
	{0x3C,0x22,0x22,0x3E,0x22,0x22,0x3C,0x0},//B
	{0x3C,0x40,0x40,0x40,0x40,0x40,0x3C,0x0},//C
	{0x7C,0x42,0x42,0x42,0x42,0x42,0x7C,0x0},//D
	{0x7C,0x40,0x40,0x7C,0x40,0x40,0x40,0x7C},//E
	{0x7C,0x40,0x40,0x7C,0x40,0x40,0x40,0x40},//F
	{0x3C,0x40,0x40,0x40,0x40,0x44,0x44,0x3C},//G
	{0x44,0x44,0x44,0x7C,0x44,0x44,0x44,0x44},//H
	{0x7C,0x10,0x10,0x10,0x10,0x10,0x10,0x7C},//I
	{0x3C,0x8,0x8,0x8,0x8,0x8,0x48,0x30},//J
	{0x0,0x24,0x28,0x30,0x20,0x30,0x28,0x24},//K
	{0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x7C},//L
	{0x81,0xC3,0xA5,0x99,0x81,0x81,0x81,0x81},//M
	{0x0,0x42,0x62,0x52,0x4A,0x46,0x42,0x0},//N
	{0x3C,0x42,0x42,0x42,0x42,0x42,0x42,0x3C},//O
	{0x3C,0x22,0x22,0x22,0x3C,0x20,0x20,0x20},//P
	{0x1C,0x22,0x22,0x22,0x22,0x26,0x22,0x1D},//Q
	{0x3C,0x22,0x22,0x22,0x3C,0x24,0x22,0x21},//R
	{0x0,0x1E,0x20,0x20,0x3E,0x2,0x2,0x3C},//S
	{0x0,0x3E,0x8,0x8,0x8,0x8,0x8,0x8},//T
	{0x42,0x42,0x42,0x42,0x42,0x42,0x22,0x1C},//U
	{0x42,0x42,0x42,0x42,0x42,0x42,0x24,0x18},//V
	{0x0,0x49,0x49,0x49,0x49,0x2A,0x1C,0x0},//W
	{0x0,0x41,0x22,0x14,0x8,0x14,0x22,0x41},//X
	{0x41,0x22,0x14,0x8,0x8,0x8,0x8,0x8},//Y
	{0x0,0x7F,0x2,0x4,0x8,0x10,0x20,0x7F},//Z
};


2 功能实现

(1)CPP文件:功能实现代码,完整注释

//" Max7219.c "
#include "stm32f10x.h"                  // USE_STDPERIPH_DRIVER
#include "delay.h"
#include "Max7219.h"
#include "math.h"

uint8_t graph[10]={0};//函数调用内部:每一行的二进制值,记忆化,防止每次修改闪屏

/*
功能:初始化引脚参数
参数:-
介绍:注意 引脚模式
*/
void Max7219_SpiInit(void) {
    GPIO_InitTypeDef GPIO_InitStructure;

    // 使能GPIOA时钟
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);

    // 配置CS引脚为推挽输出模式
    GPIO_InitStructure.GPIO_Pin = MAX7219_CS_PIN;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_Init(MAX7219_CS_PORT, &GPIO_InitStructure);

    // 配置CLK引脚为推挽输出模式
    GPIO_InitStructure.GPIO_Pin = MAX7219_CLK_PIN;
    GPIO_Init(MAX7219_CLK_PORT, &GPIO_InitStructure);

    // 配置DIN引脚为推挽输出模式-Mosi
    GPIO_InitStructure.GPIO_Pin = MAX7219_DIN_PIN;
    GPIO_Init(MAX7219_DIN_PORT, &GPIO_InitStructure);
}


/*
功能:初始化Max7219
参数:-
介绍:有需求可自己调参,一般不需改动
*/
void Max7219_InitDisplay(void) {
		Max7219_SpiInit();
		Max7219_Bright(3); //设置初始亮度,可选 0-15
		Max7219_SendByte(0X0C,1);//工作模式选择   1:正常工作  0:掉电模式(熄屏但不丢数据)  
		Max7219_SendByte(0X0F,0);//测试模式开关   1:开测试模式  0:正常工作
	  Max7219_SendByte(0X0B,7);	//扫描方式选择  0-7 设置扫描1-8个LED
		Max7219_SendByte(0X09,0);	//译码方式  0:为不解码,点阵屏没这个功能。
	  Max7219_Clear();             //MA7219数码管中,开启译码可以用Send(DIGX,num)一键显示
}

//清空全部内容,熄灭
void Max7219_Clear(void){
	for(int i=1;i<=8;i++){
		Max7219_SendByte(i,0);
		graph[i]=0;
	}
}

/*
功能:仅清空一行
参数:某一行:1-8
介绍:防止多数覆盖少数,如:先点亮第一行【1,6】的灯,再点【2,4】
      若不事先清空,则效果被覆盖。仅用于有覆盖性的变化需求时,仅一个图案则用不到。
*/
void Max7219_Clearline(uint8_t l){
	graph[l]=0;
	Max7219_SendByte(l,graph[l]);
	//Max7219_SendByte(l,0)也可以,但无法让数组保存记忆,只能做到即时显示
}

/*
功能1:模拟SPI通信
参数1:地址
参数2:数据值
介绍:SPI为16位通信,将片CS信号拉低开始发送,数据位发送后,将时钟信号置高再置低产生
      时钟脉冲发送完成后,将片选信号拉高结束通信。

功能2:二进制值,设定某行的灯阵
参数1:选中某一行,1-8(地址恰为0x01-0x08,可直接用十进制)
参数2:数据值的二进制形式,对应每一行8个LEd的亮灭
介绍:可用取模软件得图案值,然后快速输出
*/
void Max7219_SendByte(uint8_t address, uint8_t data) {
    uint8_t i;
	// 拉低CS引脚,选中Max7219
    GPIO_ResetBits(MAX7219_CS_PORT, MAX7219_CS_PIN);


    // 发送地址字节
    for (i = 0; i < 8; i++) {
        // 设置DIN引脚数据位-写入数据
        if (address & 0x80) {
            GPIO_SetBits(MAX7219_DIN_PORT, MAX7219_DIN_PIN);
        } else {
            GPIO_ResetBits(MAX7219_DIN_PORT, MAX7219_DIN_PIN);
        }
        // 产生时钟脉冲 1-0
        GPIO_SetBits(MAX7219_CLK_PORT, MAX7219_CLK_PIN);
        Delay_us(1); // 延迟1微秒
        GPIO_ResetBits(MAX7219_CLK_PORT, MAX7219_CLK_PIN);
        Delay_us(1); // 延迟1微秒
        address <<= 1;
    }

    // 发送数据字节
    for (i = 0; i < 8; i++) {
        // 设置DIN引脚数据位
        if (data & 0x80) {
            GPIO_SetBits(MAX7219_DIN_PORT, MAX7219_DIN_PIN);
        } else {
            GPIO_ResetBits(MAX7219_DIN_PORT, MAX7219_DIN_PIN);
        }
        // 产生时钟脉冲 1-0
        GPIO_SetBits(MAX7219_CLK_PORT, MAX7219_CLK_PIN);
        Delay_us(1); // 延迟1微秒
        GPIO_ResetBits(MAX7219_CLK_PORT, MAX7219_CLK_PIN);
        Delay_us(1); // 延迟1微秒
        data <<= 1;
    }
    
    // 拉高CS引脚,结束通信
    GPIO_SetBits(MAX7219_CS_PORT, MAX7219_CS_PIN);
		
}


//设置点阵屏亮度:0-15
void Max7219_Bright(uint8_t dt){
		Max7219_SendByte(0X0A,dt);
}

/*
功能:点亮某一行的【x,y】间的LED灯,支持重复操作同一行,效果覆盖。
参数1:第几行:1-8
参数2:起始LEd位置:1-8
参数3:结束LEd位置:1-8
介 绍:原理是计算出仅[x,y]点亮对应的二进制值,写入对应行。
*/
void Max7219_ShowGraph(uint8_t line,uint8_t x,uint8_t y){
		uint8_t tem=pow(2,9-x) - pow(2,8-y);
	  graph[line]|=tem;
		Max7219_SendByte(line,graph[line]);
}


3 主函数:demo全面测试

(1)拖出来册注释代码,即可观察效果

#include "stm32f10x.h"                  // USE_STDPERIPH_DRIVER
#include "delay.h"
#include "OLED.h"//无需
#include "Max7219.h"
#include "Preprocessdesign.h" //预处理二维图案数组

int main(void)
{
	OLED_Init();//oled非必要
	OLED_Clear();
	OLED_ShowString(1,1,"Max7219 string");
	OLED_ShowString(2,1,"SPI_case");
	
	Max7219_InitDisplay();//初始化
	//Max7219_Bright(15);//0-15亮度
	
	while (1)
	{
		/*<1> 图案0-9,A-Z:预处理二进制取模
		
		uint8_t t=0;
		 do{
			for(int j=0;j<8;j++)
			 Max7219_SendByte(j+1,data[t][j]); //data[0-35][~]: 0-9,A-Z,
		  Delay_ms(300);
			t++;
		 }while(t<36);
		 Max7219_Clear();
		*/
		
		 
		/*<2> 图案 心:预处理二进制取模
		for(int j=0;j<8;j++)
			 Max7219_SendByte(j+1,Heart[j]);
		  Delay_ms(500);
		 Max7219_Clear();
		*/
			
		
		/*<3> 使用封装函数:数字1
		for(int i=1;i<=8;i++)
			Max7219_ShowGraph(i,4,5); //第i行,点亮[4-5]的灯
		Max7219_ShowGraph(1,3,3);
		Max7219_ShowGraph(2,2,3);
		Max7219_ShowGraph(8,2,7);
		Delay_ms(800);
		Max7219_Clear();
		*/
		
		
		/*<4> 使用封装函数:蛇形矩阵
		
		for(int i=1;i<=8;i++)
      for(int st=i,ed=1; ;st--,ed++){
          if(st==0&&ed==i+1) break;
				  Max7219_ShowGraph(st,ed,ed); //凡有规律的图形,或动态变化,皆可实现
					Delay_ms(270);
      }
		Max7219_Clear();
		*/
		
			
	}
}


三 取模软件

粘贴生成的:C语言数组,共阳或共阴TABH或TABL其中一个的数据即可,取模软件有很多款,网上也可直接搜索下载。
在这里插入图片描述

完全开源,愿与君共勉

下载链接:

8X8点阵屏取模软件


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值