MAX7219(模拟SPI)驱动灯环的简单应用

文章目录

  • 一、MAX7219是什么?
  • 二、使用步骤
    • 1.硬件
      • [1.1 引脚说明](#1.1 引脚说明)
      • [1.2 应用电路](#1.2 应用电路)
        • [1.2.1 驱动数码管](#1.2.1 驱动数码管)
        • [1.2.2 驱动点阵](#1.2.2 驱动点阵)
    • 2.软件
      • [2.1 时序](#2.1 时序)
      • [2.2 寄存器](#2.2 寄存器)
        • [2.2.1 掉电寄存器](#2.2.1 掉电寄存器)
        • [2.2.2 译码模式寄存器](#2.2.2 译码模式寄存器)
        • [2.2.3 亮度寄存器](#2.2.3 亮度寄存器)
        • [2.2.4 扫描寄存器](#2.2.4 扫描寄存器)
        • [2.2.5 显示测试寄存器](#2.2.5 显示测试寄存器)
      • [2.3 初始化](#2.3 初始化)
      • [2.4 控制左侧灯环特定位置中的LED灯的状态](#2.4 控制左侧灯环特定位置中的LED灯的状态)
      • [2.5 控制右侧灯环特定位置中的LED灯的状态](#2.5 控制右侧灯环特定位置中的LED灯的状态)
  • 三、总结

一、MAX7219是什么?

MAX7219是一个集成化的串行输入/输出共阴极显示驱动芯片,它一般驱动8位数字的7段数码管或者连接8*8点阵又或者是64个独立的LED。它可以通过亮度寄存器来设置LED的电流,又或者是通过硬件上修改V+和ISET直接的电阻阻值大小来设置。同时,它还拥有译码模式寄存器,可以选择采用BCD译码或不采用。

有些人可能不清楚什么是BCD译码,下面简单解释下,

BCD译码 是一种将二进制数转换成BCD(Binary-Coded Decimal)格式的过程。BCD码是一种特殊的二进制编码方式,用于表示十进制数,其中每一位十进制数由4位二进制数表示,范围从0到9。例如,十进制数13在BCD码中表示为0001 0011。BCD码的优点是可以直接对每个十进制位进行处理,而无需进行二进制到十进制的转换,这在数字显示、计算机存储和控制系统等领域中具有重要意义。

二、使用步骤

1.硬件

1.1 引脚说明

1.2 应用电路

1.2.1 驱动数码管

MAX7219通过加在V+和ISET之间的一个外部电阻来控制显示亮度,段驱动电流一般是流入ISET端电流的100倍,这里用的电阻是9.53K,它设定的段电流为40mA。显示亮度也可以通过亮度寄存器来设置。

MAX7219的SPI只需要用到串行信号时钟CLK,片选信号CS以及主机输出从机输入数据DIN(MOSI),和常规相比少了个主机输入从机输出DO(MISO)。

1.2.2 驱动点阵

和上面的驱动数码管相比,无非就是把接在数码管的段和位接到了88点阵的行列上,8 8点阵其实就是64个LED组成,之前我的一篇文章有提及到,感兴趣可以自行去看下基于51单片机的点阵显示的proteus仿真(附源码)

这里级联没有涉及,先不讲。

2.软件

2.1 时序

对MAX7219来说,串行数据在DIN输入16为数据包,无论LOAD端处于何种状态,在时钟的上升沿数据均移入到内部16位移位寄存器。无论数据输入或输出CS必须为低电平,然后数据在LOAD/CS上升沿被载入数据寄存器或控制寄存器。LOAD/CS端在第16个时钟的上升沿同时或之后,下个时钟上升沿之前变为高电平,否则数据将会丢失。在DIN端的数据传输到移位寄存器在16.5个时钟周期之后出现在DOUT端。在时钟的下降沿数据将被输出。

数据位标记位D0-D15(如下表1所示)。其中D8-D11为寄存器地址位,D0-D7为数据位,D12-D15为无效位。在传输过程中,首先接收到的是D15位。是非常重要的一位(MSB)。

示例代码如下:

c 复制代码
/*******************************************************************************
 * 函数名:Write_Max7219_Date
 * 描述  :向Max7219写入数据
 * 输入  :addr地址,dat数据
 * 输出  :void
 * 调用  :内部调用
 * 备注  :
*******************************************************************************/
void Write_Max7219_Date(uint8_t addr,uint8_t dat)
{
	uint8_t i;	
	
	SPI2_CLK_LOW();		
	SPI2_CS_LOW();//拉低CS,选中器件	
	
	//发送地址
	for(i=0;i<8;i++)
	{
		  if(addr & 0x80)
			{
		    SPI2_SI_HIGH();			
			}
			else
			{
		    SPI2_SI_LOW();					
			}
			addr <<= 1;
			SPI2_CLK_HIGH();	
	        SPI2_CLK_LOW();					
	}
	
	//发送数据
	for(i=0;i<8;i++)
	{
		  if(dat & 0x80)
			{
		    SPI2_SI_HIGH();			
			}
			else
			{
		    SPI2_SI_LOW();					
			}
			dat <<= 1;
			SPI2_CLK_HIGH();	
	       SPI2_CLK_LOW();					
	}	
	
	SPI2_CS_HIGH();//发送结束,上升沿锁存数据	
	SPI2_CLK_LOW();			
    SPI2_SI_LOW();	
}

2.2 寄存器

MAX7219如下表所示有14个可寻址的数据寄存器和控制寄存器。数据寄存器由一个在片上的8X8的双向SRAM来实现。它们可以直接寻址所有只要在V+大于2V的情况下每个数据都可以独立的修改或保持。控制寄存器包括译码模式、显示亮度、扫描限制、掉电模式、显示测试五个寄存器。

示例代码如下:

c 复制代码
/* Defines ------------------------------------------------------------------*/
#define DIG0_Registe  0x01//选位0寄存器
#define DIG1_Registe  0x02//选位1寄存器
#define DIG2_Registe  0x03//选位2寄存器
#define DIG3_Registe  0x04//选位3寄存器
#define DIG4_Registe  0x05//选位4寄存器
#define DIG5_Registe  0x06//选位5寄存器
#define DIG6_Registe  0x07//选位6寄存器
#define DIG7_Registe  0x08//选位7寄存器

#define DECODE_MODE   0x09//译码模式寄存器
//0x00:7-0不采用译码
//0x01:0采用BCD译码,7-1不采用
//0x0F:3-0采用BCD译码,7-4不采用
//0xFF:7-0采用BCD译码
//当选择BCD译码模式时,译码器只对数据的低四位进行译码(D3-D0),D4-D6为无效位。D7位用来设置小数点,不受译码器的控制且为高电平。
//当选择不译码时,数据的八位与MAX7219的各段线上的信号一致。

#define INTENSITY    0x0A//亮度寄存器
//亮度等级设置 0x00-0x0F 设置电流为最大电流的 1/32 - 31/32(间隔2/32)
//也可以通过硬件来改变,修改V+和ISET之间的电阻阻值大小,最小阻值为9.53kΩ,它设定段电流为40mA。

#define SCAN_LIMIT   0x0B//扫描寄存器
//0x00:只显示数字0
//0x01:显示数字0&1
//0x02:显示数字0,1,2
//0x03:显示数字0,1,2,3
//0x04:显示数字0,1,2,3,4
//0x05:显示数字0,1,2,3,4,5
//0x06:显示数字0,1,2,3,4,5,6
//0x07:显示数字0,1,2,3,4,5,6,7

#define SHUTDOWN 0x0C//掉电寄存器
//0x00:掉电模式
//0x01:正常模式

#define DISPLAY_TEST  0x0F//显示测试寄存器
//0x00:正常模式
//0x01:显示测试模式
2.2.1 掉电寄存器

可以从下表看出掉电寄存器的地址位0x0C,写入数据0x00表示掉电模式,写入数据0x01表示正常模式。

示例代码如下:

c 复制代码
#define SHUTDOWN 0x0C//掉电寄存器
//0x00:掉电模式
//0x01:正常模式

Write_Max7219_Date(SHUTDOWN,0x01);//掉电模式:0;普通模式:1	
2.2.2 译码模式寄存器

可以从下表看出译码模式寄存器的地址位0x09,写入数据0x00表示不采用BCD译码,这里我实际电路接的是16个独立的LED组成的灯环,所有选择非译码模式。

示例代码如下:

c 复制代码
#define DECODE_MODE   0x09//译码模式寄存器
//0x00:7-0不采用译码
//0x01:0采用BCD译码,7-1不采用
//0x0F:3-0采用BCD译码,7-4不采用
//0xFF:7-0采用BCD译码
//当选择BCD译码模式时,译码器只对数据的低四位进行译码(D3-D0),D4-D6为无效位。D7位用来设置小数点,不受译码器的控制且为高电平。
//当选择不译码时,数据的八位与MAX7219的各段线上的信号一致。

Write_Max7219_Date(DECODE_MODE,0x00);//译码方式:非BCD译码
2.2.3 亮度寄存器

可以从下表看出亮度寄存器的地址位0x0A,根据写入数据多少来设置亮度也就是电流的大小。

示例代码如下:

c 复制代码
#define INTENSITY    0x0A//亮度寄存器
//亮度等级设置 0x00-0x0F 设置电流为最大电流的 1/32 - 31/32(间隔2/32)
//也可以通过硬件来改变,修改V+和ISET之间的电阻阻值大小,最小阻值为9.53kΩ,它设定段电流为40mA。

Write_Max7219_Date(INTENSITY,0x0C);//亮度
2.2.4 扫描寄存器

可以从下表看出扫描寄存器的地址位0x0B,根据写入数据多少来设置扫描数量。

示例代码如下:

c 复制代码
#define SCAN_LIMIT   0x0B//扫描寄存器
//0x00:只显示数字0
//0x01:显示数字0&1
//0x02:显示数字0,1,2
//0x03:显示数字0,1,2,3
//0x04:显示数字0,1,2,3,4
//0x05:显示数字0,1,2,3,4,5
//0x06:显示数字0,1,2,3,4,5,6
//0x07:显示数字0,1,2,3,4,5,6,7

Write_Max7219_Date(SCAN_LIMIT,0x07);//扫描界限:8个数码管显示	
2.2.5 显示测试寄存器

可以从下表看出显示测试存器的地址位0x0F,写入数据0x00表示正常模式,写入数据0x01表示显示测试模式,如果选择显示测试模式,灯会全部点亮。

示例代码如下:

c 复制代码
#define DISPLAY_TEST  0x0F//显示测试寄存器
//0x00:正常模式
//0x01:显示测试模式

Write_Max7219_Date(DISPLAY_TEST,0x00);//显示测试:1;测试结束,正常显示:0	

2.3 初始化

示例代码如下:

c 复制代码
/*******************************************************************************
 * 函数名:User_Max7219_Init
 * 描述  :MAX7219配置初始化
 * 输入  :void
 * 输出  :void
 * 调用  :初始化
 * 备注  :
*******************************************************************************/
void User_Max7219_Init(void)
{
	User_SPI2_Init();//SPI引脚配置初始化	
	Write_Max7219_Date(SHUTDOWN,0x01);//掉电模式:0;普通模式:1	
	Write_Max7219_Date(DISPLAY_TEST,0x00);//显示测试:1;测试结束,正常显示:0			
    Write_Max7219_Date(DECODE_MODE,0x00);//译码方式:非BCD译码
	Write_Max7219_Date(SCAN_LIMIT,0x07);//扫描界限:8个数码管显示	
	Write_Max7219_Date(INTENSITY,0x0C);//亮度
}

2.4 控制左侧灯环特定位置中的LED灯的状态

示例代码如下:

c 复制代码
/*******************************************************************************
 * 函数名:ConLeft
 * 描述  :控制左侧灯环特定位置中的LED灯的状态
 * 输入  :num代表要控制的LED灯的位置,status代表LED灯的状态,0表示关闭,1表示打开
 * 输出  :void
 * 调用  :内部调用
 * 备注  :
*******************************************************************************/
void ConLeft(uint8_t num, uint8_t Status)	// num 从 0 开始 (中间位置)
{
    if ( ( Status != 0 ) &&	( Status != 1 ) )
    {
        Sendstr_U1 ( "*_ERR: Status$" );
        return;
    }
    if ( num > 15 )
    {
        Sendstr_U1 ( "*_ERR: num > 15$" );
        num = 15;
    }

    if ( Status == 0 )
    {
        LeftStatus &= ( ~ ( 0x0001 << num ) );
        Left_RegVal[ ( num >> 2 )] &= ( ~Left_Val[num] );
    }
    else
    {
        LeftStatus |= ( 0x0001 << num );
        Left_RegVal[ ( num >> 2 )] |= ( Left_Val[num] );
    }
    Write_Max7219_Date ( Left_Reg[num], Left_RegVal[ ( num >> 2 )] );
}

2.5 控制右侧灯环特定位置中的LED灯的状态

示例代码如下:

c 复制代码
/*******************************************************************************
 * 函数名:ConRight
 * 描述  :控制右侧灯环特定位置中的LED灯的状态
 * 输入  :num代表要控制的LED灯的位置,status代表LED灯的状态,0表示关闭,1表示打开
 * 输出  :void
 * 调用  :内部调用
 * 备注  :
*******************************************************************************/
void ConRight(uint8_t num, uint8_t Status )	// num 从 0 开始 (中间位置)
{
    if ( ( Status != 0 ) &&	( Status != 1 ) )
    {
        Sendstr_U1 ( "*_ERR: Status$" );
        return;
    }
    if ( num > 15 )
    {
        Sendstr_U1 ( "*_ERR: num > 15$" );
        num = 15;
    }

    if ( Status == 0 )
    {
        RightStatus &= ( ~ ( 0x0001 << num ) );
        Right_RegVal[ ( num >> 2 )] &= ( ~Right_Val[num] );
    }
    else
    {
        RightStatus |= ( 0x0001 << num );
        Right_RegVal[ ( num >> 2 )] |= ( Right_Val[num] );
    }
    Write_Max7219_Date ( Right_Reg[num], Right_RegVal[ ( num >> 2 )] );
}

三、总结

今天主要讲了MAX7219(模拟SPI)驱动灯环的简单应用。

感谢你的观看!

相关推荐
国科安芯1 小时前
ASP4644芯片低功耗设计思路解析
网络·单片机·嵌入式硬件·安全
充哥单片机设计2 小时前
【STM32项目开源】基于STM32的智能厨房火灾燃气监控
stm32·单片机·嵌入式硬件
CiLerLinux9 小时前
第四十九章 ESP32S3 WiFi 路由实验
网络·人工智能·单片机·嵌入式硬件
时光の尘9 小时前
【PCB电路设计】常见元器件简介(电阻、电容、电感、二极管、三极管以及场效应管)
单片机·嵌入式硬件·pcb·二极管·电感·三极管·场效应管
Lu Zelin9 小时前
单片机为什么不能跑Linux
linux·单片机·嵌入式硬件
宁静致远202110 小时前
stm32 freertos下基于hal库的模拟I2C驱动实现
stm32·嵌入式硬件·freertos
Wave84514 小时前
STM32--智能小车
stm32·单片机·嵌入式硬件
wdfk_prog17 小时前
[Linux]学习笔记系列 -- lib/timerqueue.c Timer Queue Management 高精度定时器的有序数据结构
linux·c语言·数据结构·笔记·单片机·学习·安全
helesheng19 小时前
用低成本FPGA实现FSMC接口的多串口(UART)控制器
stm32·fsmc·fpga·uart控制器
充哥单片机设计20 小时前
【STM32项目开源】基于STM32的智能家居环境(空气质量)检测系统
stm32·单片机·嵌入式硬件