Stm32管脚控制共阳数码管LED数码管

Stm32管脚控制共阳数码管LED数码管
总体电路部分。

LED数码管驱动部分
在这里插入图片描述
MCU控制部分
在这里插入图片描述

下面为程序部分
程序用定时器定时扫描出每一位的数码管。

对所需要的变量进行定义

extern u32  Timer4_overrun;		//定时器自加计数值
extern uint32_t Timer4_count;		//定时器自加计数值

//--- 显示0~9笔段代码表 ---
unsigned char  LEDSEG[] =                          
{
0x03,0x9F,0x25,0x0D,0x99,0x49,0x41,0x1F,0x01,0x09,
};

//--- 数码管显示的位选通段代码表 ---
unsigned char  LEDDIG[] =        
{
0x80,0x40,0x20,0x10
};

unsigned char LEDBuffer[4];                               //--- 定义的显示缓冲区 ---
unsigned char LEDPointer = 0;                             //--- 定义的扫描计数变量 ---

unsigned int msCounter = 0;
u32 Counter = 0;                              						 //计数
u16 Twinkle = 0;
u16 Twinkle_ms = 0;
u16 Twinkle_cq = 0;

将引脚和定时器进行初始化。

/**
  * 函数功能: 配置TIM4定时器初始化
  * 输入参数: 无
  * 返 回 值: 无
  * 说    明:无
  */
void Tim4_init(void)
{
	TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;
	NVIC_InitTypeDef NVIC_InitStructure; 
	
	/*-------------------中断优先级配置初始化-------------------*/
  /* 设置中断组为0 */
  NVIC_PriorityGroupConfig(NVIC_PriorityGroup_0);		
  /* 设置中断来源 */
  NVIC_InitStructure.NVIC_IRQChannel = ADVANCE_TIM4_IRQ;	
  /* 设置主优先级为 0 */
  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 2;	 
  /* 设置抢占优先级为3 */
  NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
  NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
  NVIC_Init(&NVIC_InitStructure);	
	
	/*-------------------TIM4配置初始化-------------------*/	
  /* 开启TIM4_CLK即内部时钟CK_INT=72M */
  RCC_APB1PeriphClockCmd(ADVANCE_TIM4_CLK, ENABLE);	
  /* 自动重装载寄存器周的值(计数值) */
  TIM_TimeBaseStructure.TIM_Period=ADVANCE_TIM4_PERIOD;
  /* 累计 TIM_Period个频率后产生一个更新或者中断
     时钟预分频数为71,则驱动计数器的时钟CK_CNT = CK_INT / (71+1)=1M */
  TIM_TimeBaseStructure.TIM_Prescaler= ADVANCE_TIM4_PRESCALER;
  /* 计数器计数模式,基本定时器TIM8向上计数 */
  TIM_TimeBaseStructure.TIM_CounterMode=TIM_CounterMode_Up; 
  /* 初始化定时器TIM4 */
  TIM_TimeBaseInit(ADVANCE_TIM4, &TIM_TimeBaseStructure);

  /* 清除计数器中断标志位 */
  TIM_ClearITPendingBit(ADVANCE_TIM4, TIM_IT_Update);
  /* 开启计数器中断 */
  TIM_ITConfig(ADVANCE_TIM4,TIM_IT_Update,ENABLE);

  /* 使能计数器 */
  TIM_Cmd(ADVANCE_TIM4, ENABLE);	

}

 /**
  * 函数功能: LED灯管脚初始化
  * 输入参数: 无
  * 返 回 值: 无
  * 说    明:此处用到了特殊引脚,需要将RTC和外部低速时钟引脚作为普通引脚定义。
  */
void Hxeled_init(void)
{
 GPIO_InitTypeDef  GPIO_InitStructure;	
 RCC_APB2PeriphClockCmd(LED_SCK_CLK, ENABLE);	 				 //使能PA端口时钟
 RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE);
 GPIO_PinRemapConfig(GPIO_Remap_SWJ_JTAGDisable,ENABLE);//失能JTAG

 PWR_BackupAccessCmd( ENABLE );/* 允许修改RTC和后备寄存器*/
 RCC_LSEConfig( RCC_LSE_OFF ); /* 关闭外部低速时钟,PC14+PC15可以用作普通IO*/
 BKP_TamperPinCmd(DISABLE);  /* 关闭入侵检测功能,PC13可以用作普通IO*/
	
 GPIO_InitStructure.GPIO_Pin = LED1_A_OUT | LED1_B_OUT | LED1_C_OUT | LED1_D_OUT |LED1_E_OUT |LED1_F_OUT | LED1_G_OUT | LED1_DP_OUT | LED2_G_OUT | LED2_DP_OUT | LED2_C_OUT | LED_WE1 | LED_WE2 | LED_WE3;
 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; 		 //推挽输出
 GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;		 //IO口速度为50MHz
 GPIO_Init(GPIOA, &GPIO_InitStructure);					 			 //根据设定参数初始化 

 GPIO_InitStructure.GPIO_Pin = LED2_A_OUT | LED2_B_OUT | LED2_D_OUT |LED2_E_OUT |LED2_F_OUT;
 GPIO_Init(GPIOB, &GPIO_InitStructure);	  				 		 //推挽输出 ,IO口速度为50MHz
 PWR_BackupAccessCmd(DISABLE);/* 禁止修改RTC和后备寄存器*/

 GPIO_InitStructure.GPIO_Pin = LED_WE4;
 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; 		 //推挽输出
 GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;		 //IO口速度为50MHz
 GPIO_Init(GPIOC,&GPIO_InitStructure);	  				 		 
 
	DIG1=0;
	DIG2=0;
	DIG3=0;
	DIG4=0;
	
	A_out = 0;
	B_out = 0;
	C_out = 0;
	D_out = 0;
	E_out = 0;
	F_out = 0;
	G_out = 0;
	DP_out = 1;

}

显示的数字和闪烁时间

 /**
  * 函数功能: 将数据传递给数码管显示,
  * 输入参数1: data:所显示的数据 
  * 输入参数2:twinkle:闪烁时间;单位 
  * 返 回 值: 无
  * 说    明:无
  */
void Display_data(u32 data , u16 twinkle)	
{
	Counter = data;
	Twinkle = twinkle;
}

此作为核心部分。

 /**
  * 函数功能: Timer4定时器服务中断函数
  * 输入参数: 无
  * 返 回 值: 无
  * 说    明:无
  */
void TIM4_IRQHandler(void)
{
	if(TIM_GetITStatus(ADVANCE_TIM4,TIM_IT_Update)!= RESET)  	//检查指定的TIM中断发生与否:TIM 中断源 
	{
		Timer4_count++;
		Twinkle_ms++;
		TIM_ClearITPendingBit(ADVANCE_TIM4,TIM_IT_Update);  		//清除TIMx的中断待处理位:TIM 中断源 
	//-----------------------------------------------------------------------------------------------

		//--- 动态数码管显示扫描驱动程序段 ---
		//--- 显示数字 ---
		DIG1= 0;							//数码管消影
		DIG2= 0;							//数码管消影
		DIG3= 0;							//数码管消影
		DIG4= 0;							//数码管消影
		if(0==Twinkle)//不闪烁
		{
			A_out=((LEDSEG[LEDBuffer[LEDPointer]]>>7) & 0x01);
			B_out=((LEDSEG[LEDBuffer[LEDPointer]]>>6) & 0x01);
			C_out=((LEDSEG[LEDBuffer[LEDPointer]]>>5) & 0x01);
			D_out=((LEDSEG[LEDBuffer[LEDPointer]]>>4) & 0x01);
			E_out=((LEDSEG[LEDBuffer[LEDPointer]]>>3) & 0x01);
			F_out=((LEDSEG[LEDBuffer[LEDPointer]]>>2) & 0x01);
			G_out=((LEDSEG[LEDBuffer[LEDPointer]]>>1) & 0x01);
			//DP_out=((LEDSEG[LEDBuffer[LEDPointer]]>>0) & 0x01);
			
			 //--- 数码管的位选段选择 ---
			DIG1= ((LEDDIG[LEDPointer]>>7) & 0x01);
			DIG2= ((LEDDIG[LEDPointer]>>6) & 0x01);
			DIG3= ((LEDDIG[LEDPointer]>>5) & 0x01);
			DIG4= ((LEDDIG[LEDPointer]>>4) & 0x01);		
		}
		else if(Twinkle_ms > Twinkle)
		 {
			DIG1= 0;							//数码管消影
			DIG2= 0;							//数码管消影
			DIG3= 0;							//数码管消影
			DIG4= 0;							//数码管消影
			
			A_out  = 0;
			B_out  = 0;
			C_out  = 0;
			D_out  = 0;
			E_out  = 0;
			F_out  = 0;
			G_out	 = 0;
			DP_out = 0;
			
			Twinkle_cq++;	
			 if(Twinkle_cq > Twinkle)
			 {
				Twinkle_ms = 0;
				 Twinkle_cq = 0;
			 }
		 }
		else
		 {
		
		A_out=((LEDSEG[LEDBuffer[LEDPointer]]>>7) & 0x01);
		B_out=((LEDSEG[LEDBuffer[LEDPointer]]>>6) & 0x01);
		C_out=((LEDSEG[LEDBuffer[LEDPointer]]>>5) & 0x01);
		D_out=((LEDSEG[LEDBuffer[LEDPointer]]>>4) & 0x01);
		E_out=((LEDSEG[LEDBuffer[LEDPointer]]>>3) & 0x01);
		F_out=((LEDSEG[LEDBuffer[LEDPointer]]>>2) & 0x01);
		G_out=((LEDSEG[LEDBuffer[LEDPointer]]>>1) & 0x01);
		DP_out=((LEDSEG[LEDBuffer[LEDPointer]]>>0) & 0x01);
		
		 //--- 数码管的位选段选择 ---
		DIG1= ((LEDDIG[LEDPointer]>>7) & 0x01);
		DIG2= ((LEDDIG[LEDPointer]>>6) & 0x01);
		DIG3= ((LEDDIG[LEDPointer]>>5) & 0x01);
		DIG4= ((LEDDIG[LEDPointer]>>4) & 0x01);
		 }
		
		}
		
	
		LEDPointer++;                                           //--- 动态扫描计数变量加1 ---
		if(LEDPointer==3)
		{
			DP_out=0;
		}
		else
		{
			DP_out=1;
		}
		if(sizeof(LEDBuffer) == LEDPointer)LEDPointer = 0;      //--- 所有数码管扫描完,计数归0 ---
		//-----------------------------------------------------------------------------------------------
		//--- 毫秒计数变量加1,并判断1秒是否已到,若到则计数器变量加1并将结果送显示缓冲区 ---
		msCounter ++;                                           //--- 毫秒计数变量加1 ---
		if(1 == msCounter)                                   		//--- 加到1000,表示1秒时间到 ---
			{
				msCounter = 0;
				LEDBuffer[3] =   Counter % 10;                    //--- 将计数器变量的值送到显示缓冲区 ---
				LEDBuffer[2] =  (Counter/10) % 10;
				LEDBuffer[1] =  (Counter/100) % 10;
				LEDBuffer[0] =  (Counter/1000) % 10;
			}
}
  • 2
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

自小吃多

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值