单片机proteus原理图,基于proteus的51单片机开发实例31-MAX7219驱动8位数码管
单片机proteus原理图,基于proteus的51单片机开发实例31-MAX7219驱动8位数码管CLK:时钟输入引脚DIN:串行数据输入引脚MAX7219是一种串行输入/输出的共阴极显示驱动器,可以驱动8位共阴极数码管,也可以连接64个独立的LED等。MAX7219内部包含了bcd编码器、多路扫描回路、段字驱动器以及一个8*8的静态RAM(用来存储临时数据),还有一个外部寄存器可以用来设置每个段输出的电流的大小。下图所示是MAX7219的引脚图。我们来详细了解一下MAX7219各引脚的功能。图2 MAX7219引脚图
1. 基于proteus的51单片机开发实例31-MAX7219驱动8位数码管1.1. 实验目的图1 MAX7219驱动8位数码管
从本实例开始,我们将要学习一系列51单片机项目开发中常用的外设芯片。本实例我们来了解数码管驱动芯片MAX7219的电路设计和程序实现。使用MAX7219芯片驱动8位数码管显示数字。
1.2. 设计思路首先设计使用MAX7219驱动数码管的电路,了解掌握MAX7219与单片机和数码管的接口电路是如何连接的,然后编程实现单片机通过MAX7219驱动8位数码管显示数字。
1.3. 基础知识MAX7219是一种常用的数码管驱动芯片,它不但可以节省单片机的I/O口,还可以提供足够的驱动电流点亮数码管显示。
MAX7219是一种串行输入/输出的共阴极显示驱动器,可以驱动8位共阴极数码管,也可以连接64个独立的LED等。MAX7219内部包含了bcd编码器、多路扫描回路、段字驱动器以及一个8*8的静态RAM(用来存储临时数据),还有一个外部寄存器可以用来设置每个段输出的电流的大小。
1.3.1. MAX7219的引脚说明下图所示是MAX7219的引脚图。我们来详细了解一下MAX7219各引脚的功能。
图2 MAX7219引脚图
DIN:串行数据输入引脚
CLK:时钟输入引脚
DOUT:串行数据输出引脚,用于多片MAX7219级联扩展。
DIG0~DIG7:数码管位选择引脚
LOAD:数据锁存控制引脚,在LOAD上升沿时,片内数据被锁定。
SEGA~SEGG、DP:数码管段驱动引脚,没有输入时为低电平。
ISET:段电流控制引脚,可以通过一个电阻连接到电源来增大段驱动电流,使数码管亮度更高。
VCC、GND:电源、地引脚。
MAX7219使用串行移位方式与51单片机进行通信,其串行数据大小为2字节(这2字节包含4位无效数据、4位地址数据、8位有效数据位)。这些数据从DIN引脚输入,在每一个CLK时钟信号的上升沿被移入内部移位寄存器,然后在LOAD信号的上升沿时,数据被送到数据寄存器或控制寄存器。数据发送过程中按照高位在前、低位在后的原则发送。
1.3.2. MAX7219驱动控制MAX7219内部有14个可位寻址的数据/控制寄存器,单片机通过这些寄存器控制MAX7219进行各种操作。
这14个寄存器包含:8个数据寄存器(组成一个8*8的内存空间),5个控制寄存器(控制编码模式、显示亮度、扫描限制、关闭模式、显示检测)。
MAX7219的内部寄存器如下图所示。
图3 MAX7219寄存器
MAX7219的模式编码寄存器用于设置对显示内存中的待显示数据进行BCD译码或不译码。当选择编码模式时,其内置的译码器只对数据的第四位D3~D0进行译码,D4~D6无效,D7位用来设置小数点,不受译码器的控制且始终为高电平。
MAX7219可以通过加在VCC和ISET引脚之间的电阻来控制数码管的显示亮度。该电阻最小值是9.53kΩ。显示亮度可以用亮度寄存器的低4位用脉宽调制的方法控制。脉宽调制将段电流平均分为16级。
扫描控制寄存器用来控制需要显示的数码管的位数,最多8位,最低1位。如果数码管少于3位,ISET外加的电阻的大小必须根据显示数据的个数来确定,从而限制个别数据驱动对功耗的浪费。
1.3.3. 51单片机驱动MAX7219的初始化流程1、设置模式编码寄存器;
2、设置显示亮度寄存器;
3、设置扫描控制寄存器;
4、设置自关闭模式寄存器。
1.4. 电路设计本实例的电路图如图1所示。单片机的P2.3,P2.4,P2.5端口分别连接MAX7219的DIN,LOAD,CLK引脚。8为共阴极数码管的8个段分别连接MAX7219的SEGA~SEGG、DP。8个位分别连接MAX7219的DIG0~DIG7。MAX7219的ISET引脚通过一个10K电阻连到VCC。
1.5. 程序设计程序代码如下。根据上一实例中的模块化程序设计方法,将程序分为主程序模块、延时程序模块、MAX7219控制程序模块。
主程序代码
//实例72:DS18B20温度检测及其液晶显示
#include<reg51.h> //包含单片机寄存器的头文件
#include<intrins.h> //包含_nop_()函数定义的头文件
#include"MAX7219.h" //
#include"Delay.h" //
//MAX7219的输出缓冲
unsigned char Disp_Buffer1[8] = {0 0 0 0 0 0 0 0};
unsigned char Disp_Buffer2[8] = {0 0 0 0 0 0 0 1};
unsigned char Disp_Buffer3[8] = {0 0 0 0 0 0 1 2};
unsigned char Disp_Buffer4[8] = {0 0 0 0 0 1 2 3};
unsigned char Disp_Buffer5[8] = {0 0 0 0 1 2 3 4};
unsigned char Disp_Buffer6[8] = {0 0 0 1 2 3 4 5};
unsigned char Disp_Buffer7[8] = {0 0 1 2 3 4 5 6};
unsigned char Disp_Buffer8[8] = {0 1 2 3 4 5 6 7};
unsigned char Disp_Buffer9[8] = {1 2 3 4 5 6 7 8};
/*****************************************************
函数功能:主函数
***************************************************/
void main(void)
{
unsigned char i;
InitMAX7219(); //首先初始化MAX7129
DelayMs(1); //延时1毫秒
while(1)
{
for(i=0;i<8;i )
{
WriteMAX7219(i 1 Disp_Buffer1[i]); //将显示缓冲区内的数据循环送出
}
DelayMs(800);
for(i=0;i<8;i )
{
WriteMAX7219(i 1 Disp_Buffer2[i]); //
}
DelayMs(800);
for(i=0;i<8;i )
{
WriteMAX7219(i 1 Disp_Buffer3[i]); //
}
DelayMs(800);
for(i=0;i<8;i )
{
WriteMAX7219(i 1 Disp_Buffer4[i]); //
}
DelayMs(800);
for(i=0;i<8;i )
{
WriteMAX7219(i 1 Disp_Buffer5[i]); //
}
DelayMs(800);
for(i=0;i<8;i )
{
WriteMAX7219(i 1 Disp_Buffer6[i]); //
}
DelayMs(800);
for(i=0;i<8;i )
{
WriteMAX7219(i 1 Disp_Buffer7[i]); //
}
DelayMs(800);
for(i=0;i<8;i )
{
WriteMAX7219(i 1 Disp_Buffer8[i]); //
}
DelayMs(800);
for(i=0;i<8;i )
{
WriteMAX7219(i 1 Disp_Buffer9[i]); //
}
DelayMs(800);
}
}
MAX7219.h代码
//MAX7219.h
sbit MAX7219DIN= P2^3; //MAX7219的数据引脚
sbit MAX7219LOAD = P2^4; //MAX7219的控制引脚
sbit MAX7219CLK = P2^5; //MAX7219的时钟引脚
//写MAX7219函数,Addr为MAX7219的内部寄存器地址,Dat为待写入的数据
void WriteMAX7219(unsigned char MA//MAX7219.c
#include<reg51.h> //包含单片机寄存器的头文件
#include<intrins.h> //包含_nop_()函数定义的头文件
#include"MAX7219.h" //
#include"Delay.h" //
extern unsigned char Disp_Buffer[8];
//写MAX7219函数,Addr为MAX7219的内部寄存器地址,Dat为待写入的数据
void WriteMAX7219(unsigned char MAX7219Addr unsigned char MAX7219Data)
{
unsigned char i;
MAX7219LOAD = 0;
for(i=0;i<8;i ) //先送出8位地址
{
MAX7219CLK = 0; //时钟拉低
MAX7219Addr <<= 1; //移位送出地址
MAX7219DIN = CY; //送出数据
MAX7219CLK = 1; //时钟上升沿
_nop_();
_nop_();
MAX7219CLK = 0;
}
for(i=0;i<8;i ) //再送出8位数据
{
MAX7219CLK = 0;
MAX7219Data <<= 1; //移位送出数据
MAX7219DIN = CY;
MAX7219CLK = 1;
_nop_();
_nop_();
MAX7219CLK = 0;
}
MAX7219LOAD = 1;
}
//MAX7129的初始化函数
void InitMAX7219()
{
WriteMAX7219(0x09 0xff); //编码模式寄存器
WriteMAX7219(0x0a 0x07); //显示亮度控制
WriteMAX7219(0x0b 0x07); //扫描控制
WriteMAX7219(0x0c 0x01); //关闭模式控制寄存器设置
}
X7219Addr unsigned char MAX7219Data);
//MAX7129的初始化函数
void InitMAX7219();//MAX7219.c
#include<reg51.h> //包含单片机寄存器的头文件
#include<intrins.h> //包含_nop_()函数定义的头文件
#include"MAX7219.h" //
#include"Delay.h" //
extern unsigned char Disp_Buffer[8];
//写MAX7219函数,Addr为MAX7219的内部寄存器地址,Dat为待写入的数据
void WriteMAX7219(unsigned char MAX7219Addr unsigned char MAX7219Data)
{
unsigned char i;
MAX7219LOAD = 0;
for(i=0;i<8;i ) //先送出8位地址
{
MAX7219CLK = 0; //时钟拉低
MAX7219Addr <<= 1; //移位送出地址
MAX7219DIN = CY; //送出数据
MAX7219CLK = 1; //时钟上升沿
_nop_();
_nop_();
MAX7219CLK = 0;
}
for(i=0;i<8;i ) //再送出8位数据
{
MAX7219CLK = 0;
MAX7219Data <<= 1; //移位送出数据
MAX7219DIN = CY;
MAX7219CLK = 1;
_nop_();
_nop_();
MAX7219CLK = 0;
}
MAX7219LOAD = 1;
}
//MAX7129的初始化函数
void InitMAX7219()
{
WriteMAX7219(0x09 0xff); //编码模式寄存器
WriteMAX7219(0x0a 0x07); //显示亮度控制
WriteMAX7219(0x0b 0x07); //扫描控制
WriteMAX7219(0x0c 0x01); //关闭模式控制寄存器设置
}
MAX7219.c代码
//MAX7219.c
#include<reg51.h> //包含单片机寄存器的头文件
#include<intrins.h> //包含_nop_()函数定义的头文件
#include"MAX7219.h" //
#include"Delay.h" //
//写MAX7219函数,Addr为MAX7219的内部寄存器地址,Dat为待写入的数据
void WriteMAX7219(unsigned char MAX7219Addr unsigned char MAX7219Data)
{
unsigned char i;
MAX7219LOAD = 0;
for(i=0;i<8;i ) //先送出8位地址
{
MAX7219CLK = 0; //时钟拉低
MAX7219Addr <<= 1; //移位送出地址
MAX7219DIN = CY; //送出数据
MAX7219CLK = 1; //时钟上升沿
_nop_();
_nop_();
MAX7219CLK = 0;
}
for(i=0;i<8;i ) //再送出8位数据
{
MAX7219CLK = 0;
MAX7219Data <<= 1; //移位送出数据
MAX7219DIN = CY;
MAX7219CLK = 1;
_nop_();
_nop_();
MAX7219CLK = 0;
}
MAX7219LOAD = 1;
}
//MAX7129的初始化函数
void InitMAX7219()
{
WriteMAX7219(0x09 0xff); //编码模式寄存器
WriteMAX7219(0x0a 0x07); //显示亮度控制
WriteMAX7219(0x0b 0x07); //扫描控制
WriteMAX7219(0x0c 0x01); //关闭模式控制寄存器设置
}
Delay.h代码
//Delay.h
/*****************************************************
函数功能:延时1ms
(3j 2)*i=(3×33 2)×10=1010(微秒),可以认为是1毫秒
***************************************************/
void Delay1ms();
/*****************************************************
函数功能:延时若干毫秒
入口参数:n
***************************************************/
void DelayMs(unsigned int DelayCounter);
Delay.c代码
//Delay.c
#include<reg51.h> //包含单片机寄存器的头文件
#include<intrins.h> //包含_nop_()函数定义的头文件
#include"Delay.h" //
/*****************************************************
函数功能:延时1ms
(3j 2)*i=(3×33 2)×10=1010(微秒),可以认为是1毫秒
***************************************************/
void Delay1ms()
{
unsigned char i j;
for(i=0;i<10;i )
for(j=0;j<33;j )
;
}
/*****************************************************
函数功能:延时若干毫秒
入口参数:n
***************************************************/
void DelayMs(unsigned int DelayCounter)
{
unsigned int i;
for(i=0;i<DelayCounter;i )
Delay1ms();
}
1.6. 实例仿真
在Proteus环境下建立图1所示的电路,将编译完成的hex文件装载到单片机中,开始仿真,观察8位数码管的显示变化情况。
1.7. 总结
通过本实例,我们学习了数码管驱动芯片MAX7219驱动8位共阴极数码管的电路设计、编程方法。