文章目录
- 一、MAX7219是什么?
- 二、使用步骤
- 1.硬件
- 1.1 引脚说明
- 1.2 应用电路
- 1.2.1 驱动数码管
- 1.2.2 驱动点阵
- 2.软件
- 2.1 时序
- 2.2 寄存器
- 2.2.1 掉电寄存器
- 2.2.2 译码模式寄存器
- 2.2.3 亮度寄存器
- 2.2.4 扫描寄存器
- 2.2.5 显示测试寄存器
- 2.3 初始化
- 2.4 控制左侧灯环特定位置中的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点阵的行列上,88点阵其实就是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)。
示例代码如下:
/******************************************************************************** 函数名: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的情况下每个数据都可以独立的修改或保持。控制寄存器包括译码模式、显示亮度、扫描限制、掉电模式、显示测试五个寄存器。
示例代码如下:
/* 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表示正常模式。
示例代码如下:
#define SHUTDOWN 0x0C//掉电寄存器
//0x00:掉电模式
//0x01:正常模式Write_Max7219_Date(SHUTDOWN,0x01);//掉电模式:0;普通模式:1
2.2.2 译码模式寄存器
可以从下表看出译码模式寄存器的地址位0x09,写入数据0x00表示不采用BCD译码,这里我实际电路接的是16个独立的LED组成的灯环,所有选择非译码模式。
示例代码如下:
#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,根据写入数据多少来设置亮度也就是电流的大小。
示例代码如下:
#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,根据写入数据多少来设置扫描数量。
示例代码如下:
#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,7Write_Max7219_Date(SCAN_LIMIT,0x07);//扫描界限:8个数码管显示
2.2.5 显示测试寄存器
可以从下表看出显示测试存器的地址位0x0F,写入数据0x00表示正常模式,写入数据0x01表示显示测试模式,如果选择显示测试模式,灯会全部点亮。
示例代码如下:
#define DISPLAY_TEST 0x0F//显示测试寄存器
//0x00:正常模式
//0x01:显示测试模式Write_Max7219_Date(DISPLAY_TEST,0x00);//显示测试:1;测试结束,正常显示:0
2.3 初始化
示例代码如下:
/******************************************************************************** 函数名: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灯的状态
示例代码如下:
/******************************************************************************** 函数名: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灯的状态
示例代码如下:
/******************************************************************************** 函数名: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)驱动灯环的简单应用。
感谢你的观看!