MAX7219驱动数码管学习记录(有源码)

一、7219datasheet阅读

1.引脚定义:

重点介绍5个引脚

1.DIN:

        串行数据总线输入引脚,每个时钟的上升沿将数据移入至芯片内部的移位寄存器中

2.DIG0-DIG7:

        共阴极管的GND连接的便是DIG0-7,该引脚起作用时,便输出低电平,即共阴极数码管的GND端为低电平。不起作用时为高电平,即数码管无法被点亮。

3. LOAD:

        装载信号(LOAD),在load的上升沿,16位数据被锁存器锁存,数据不发生变化        

4.CLK 

        串行时钟输入,在每次CLK的上升沿,数据被移位至MAX7219内部的移位寄存器,配合上述的LOAD信号,便可以将数据锁存;下降沿时,数据从DOUT引脚输出(用于级联的情况)。

5.SEGA-SEGG,DP :

        数码管的7段(a,b,c,d,e,f)以及一个小数点dp的驱动信号,当功能关闭时,段(seg)输出低电平,即无法点亮(由于是共阴极接法,前期已经将DIG置为低电平,只有当SEG为高电平时才能使得数码管内部的发光二极管点亮)

2. 串行数据格式:

        前面提到,一次交互我们需要发送16位数据(2个字节),由上图可以看出,高字节表示着需要操作的寄存器地址,低字节表示写入的数据。对于7219来说,无论load何种状态,数据都会由于CLK的上升沿被移入数据寄存器。在发送完16位数据之后,一定要使得LOAD产生上升沿,否则在下一个CLK到来之后,移位寄存器的数据便会丢失。同时,对于数据格式来说,发送的数据总是MSB。

3.数据和控制寄存器 

        上表列出了14个可寻址的寄存器(8个数据寄存器和5个控制寄存器),控制寄存器由一个8*8的SRAM组成,控制寄存器由译码模式寄存器,亮度控制寄存器,扫描位数限制寄存器,关机控制寄存器,显示测试寄存器(所以LED全亮)组成。通过上述表可以看出,每个寄存器实地址由一位16进制数(4位二进制)组成,这样对应了前面数据格式中高8位中只有4位数据是有效的。

        对于数据寄存器digit0-digit7便对应八位数码管,在该寄存器上写入相应的数据即可点亮对应的数码管。

4. 译码寄存器

        该寄存器可以设定对输入的数据进行BCD译码。注意,由于BCD是通过四位二进制数来表示一位十进制数,因此对于输入的数据,译码寄存器只会将第四位当作BCD码,而不关心其他高位,并将这四位数进行译码得到对应的二进制数。对于第八位数据(D7),这一位是单独设置的,并不参与译码,当数据为高是,小数点自然点亮

5.扫描位数限制寄存器

        该寄存器用来配置显示数码管的个数,即0x00-0x07。

6.亮度设置寄存器 

        数值越大,数码管越亮

二、代码编写

1.初始化工作 

1.定义引脚

        这里的load和cs是相同含义

#define clk GPIO_Pin_0
#define load  GPIO_Pin_1
#define din GPIO_Pin_2

#define LOAD(x) 	GPIO_WriteBit (GPIOB,load,(BitAction)x);
#define CLK(x) 	    GPIO_WriteBit (GPIOB,clk ,(BitAction)x);
#define DIN(x) 		GPIO_WriteBit (GPIOB,din ,(BitAction)x);

2.写一个字节

        原理即为不断翻转CLK电平,使得移位寄存器工作将其读入

void MAX7219_WriteByte (uint8_t byte)
{
	for(int i =0;i<8;i++)
	{
		CLK(0);
		DIN(byte&0x80);
		byte=byte<<1;
		CLK(1);
	}
}

3.写寄存器

        通过此前分析可知,MAX7219为16位传输方式,且先发寄存器地址,再发数据,注意这里先拉低load引脚,等待16位数据传输完毕后,在将load拉高,使得数据锁存。

void MAX7219_WriteReg(uint8_t Reg,uint8_t data)
{
	LOAD(0);
	MAX7219_WriteByte (Reg);
	MAX7219_WriteByte (data);
	LOAD(1);
}

4.数码管显示

        由手册可知,小数点是单独配置的,只需要将最高位置1即可

/**
  * 函    数 显示内容 该函数为在BCD译码下的显示
  * 参    数 uint8_t location:在几位显示 1~8。
  * 参    数 uint8_t num:显示的数字(0~9,Line,E,H,L,P,blank)
  * 参    数 uint8_t dot: 是否需要小数点
  */
void MAX7219_ShowNum(uint8_t location,uint8_t num,uint8_t dot)
{
	if(dot==0)	MAX7219_WriteReg (location,num);
	else	
	{
		num |=0x80;
		MAX7219_WriteReg (location,num);		
	}
}

/**
  * 函    数 MAX7219_Clear 数码管清屏
  */
void MAX7219_Clear(void)
{
	for(int i=1;i<=8;i++)
	{
		MAX7219_ShowNum(i,blank,0);
	}
}

5.引脚初始化

        思路是先把5个控制寄存器配置好。

/**
  * 函    数 初始化MAX7219
  * 参    数 uint8_t BCD:D7~D0控制对于的数码管参与BCD译码。
  * 参    数 uint8_t Intensity:控制数码管的亮度 0~15(0表示熄灭)
  * 参    数 uint8_t DisplayNum: 数码管显示的个数:1~8
  */
void MAX7219_Init (uint8_t BCD,uint8_t Intensity,uint8_t DisplayNum)
{
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE);
	GPIO_InitTypeDef GPIO_InitStructure;
	GPIO_InitStructure.GPIO_Mode=GPIO_Mode_Out_PP;
	GPIO_InitStructure.GPIO_Pin=GPIO_Pin_0|GPIO_Pin_1|GPIO_Pin_2;
	GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;
	GPIO_Init (GPIOB,&GPIO_InitStructure );

	/*先配置五个控制寄存器*/
	MAX7219_WriteReg (0x0c,0x01);//设置为正常模式
	MAX7219_WriteReg (0x09,BCD);//设置BCD译码,8个数码管均使用BCD译码
	MAX7219_WriteReg (0x0a,Intensity);//设置亮度
	
	DisplayNum-=1;
	MAX7219_WriteReg (0x0b,DisplayNum);//8个数码管参与显示
	
	MAX7219_WriteReg (0x0f,0x01);//测试模式,所有数码管全亮
	delay_ms(5000);
	MAX7219_WriteReg (0x0f,0x00);//正常显示模式
	
	MAX7219_Clear();//再清屏
}

2.实际应用——秒表

1.配置定时器,开启中断计时

uint16_t time;
uint16_t count;

void Timer_Init(uint16_t ARR,uint16_t PSC)
{
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM4,ENABLE);
	
	TIM_TimeBaseInitTypeDef Tim4_InitStructure;
	Tim4_InitStructure.TIM_ClockDivision=TIM_CKD_DIV1;//不分频
	Tim4_InitStructure.TIM_CounterMode=TIM_CounterMode_Up;//向上计数
	Tim4_InitStructure.TIM_Period=ARR;
	Tim4_InitStructure.TIM_Prescaler=PSC;
	Tim4_InitStructure.TIM_RepetitionCounter=0x00;
	TIM_TimeBaseInit(TIM4,&Tim4_InitStructure);
	TIM_ClearFlag(TIM4, TIM_FLAG_Update); //清除由于初始化而置的标志位
	TIM_Cmd(TIM4,ENABLE);
	
	TIM_ITConfig(TIM4,TIM_IT_Update,ENABLE);
	
	NVIC_InitTypeDef TIM4_IT_InitStructure;
	TIM4_IT_InitStructure.NVIC_IRQChannel=TIM4_IRQn;
	TIM4_IT_InitStructure.NVIC_IRQChannelCmd=ENABLE;
	TIM4_IT_InitStructure.NVIC_IRQChannelPreemptionPriority=4;
	TIM4_IT_InitStructure.NVIC_IRQChannelSubPriority=4;
	NVIC_Init(&TIM4_IT_InitStructure);
}
void TIM4_IRQHandler(void)
{
	if(TIM_GetITStatus(TIM4,TIM_IT_Update)==SET)
	{
		count ++;
		if(count==100)
		{
			count=0;
			time++;
		}
		TIM_ClearITPendingBit(TIM4,TIM_IT_Update);

	}
}

2.数码管显示

/**
  * 函    数 秒表
  * 参    数 定时器总时间
  */
void MAX7219_Stopwatch(uint16_t time)
{
		uint16_t times=time;
		uint16_t weishu;
		weishu=1+log10(times);
		for(int i=weishu;i>0;i--)
		{
			if(i==2) MAX7219_ShowNum(i,times/(int)(pow(10,i-1)),1);
			else 	 MAX7219_ShowNum(i,times/(int)(pow(10,i-1)),0);
			times=times%(int)pow(10,i-1);
		}
}

三、结果

源码自取

链接:https://pan.baidu.com/s/1y_ins_xLHj9oJFgG9AhzLw?pwd=hcoi 
提取码:hcoi

相关推荐

最近更新

  1. TCP协议是安全的吗?

    2024-04-06 14:24:02       16 阅读
  2. 阿里云服务器执行yum,一直下载docker-ce-stable失败

    2024-04-06 14:24:02       16 阅读
  3. 【Python教程】压缩PDF文件大小

    2024-04-06 14:24:02       15 阅读
  4. 通过文章id递归查询所有评论(xml)

    2024-04-06 14:24:02       18 阅读

热门阅读

  1. 【数据结构】串

    2024-04-06 14:24:02       17 阅读
  2. 达梦体系结构:进程架构

    2024-04-06 14:24:02       14 阅读
  3. 设计模式:观察者模式示例

    2024-04-06 14:24:02       19 阅读
  4. 算法复习|修剪二叉搜索树

    2024-04-06 14:24:02       17 阅读
  5. 单片机学习day1

    2024-04-06 14:24:02       15 阅读
  6. 反转链表(leetcode 206)

    2024-04-06 14:24:02       14 阅读
  7. LeetCode207、210 课程表(图 dfs 拓扑排序)

    2024-04-06 14:24:02       15 阅读