stm32使用四位数码管制作简易时钟(库函数版)

文章介绍了如何使用STM32微控制器通过Timer中断驱动4位共阳数码管显示时间。程序中配置了Timer2进行定时,通过GPIO端口控制数码管的段码和位选,实现了数码管的动态显示。同时,提供了初始化函数和数码管显示函数的详细代码。
摘要由CSDN通过智能技术生成

1.数码管情况介绍

数码管接线引脚:

 

 段码与上图情况,位选为:1-PB0,2-PB12,3-PB13,4-PB14。

本项目使用5461BS-1共四位数码管,为共阳型。

 2.程序部分

Timer定时器:

#include "stm32f10x.h"                  // Device header

void Timer_Init(void){
	//1.开启时钟RCC
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2,ENABLE);//TIM2
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);	
	//2.选择时基单元时钟
	TIM_InternalClockConfig(TIM2);//内部时钟
	//3.配置时基单元
	TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStruct;
	TIM_TimeBaseInitStruct.TIM_ClockDivision=TIM_CKD_DIV1;//选择时钟分频
	TIM_TimeBaseInitStruct.TIM_CounterMode=TIM_CounterMode_Up;//计数器模式(向上/向下/3种中央对齐模式)
	TIM_TimeBaseInitStruct.TIM_Period=10000-1;//ARR自动重装器的值(0-65535)
	TIM_TimeBaseInitStruct.TIM_Prescaler=7200-1;//PSC预分频器的值(0-65535);定时频率=72M/(PSC+1)/(ARR+1);72000
	TIM_TimeBaseInitStruct.TIM_RepetitionCounter=0;//重复计数器的值(高级计数器才有)
	TIM_TimeBaseInit(TIM2,&TIM_TimeBaseInitStruct);
	TIM_ClearFlag(TIM2,TIM_FLAG_Update);//将更新中断标志位清除,避免初始化完就进中断
	//4.使能更新中断
	TIM_ITConfig(TIM2,TIM_IT_Update,ENABLE);
	//5.配置NVIC
	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
	NVIC_InitTypeDef NVIC_InitStruct;
	NVIC_InitStruct.NVIC_IRQChannel=TIM2_IRQn;//选择通道
	NVIC_InitStruct.NVIC_IRQChannelCmd=ENABLE;//指定中断通道是使能/失能
	NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority=2;//设置先占(抢占)优先级
	NVIC_InitStruct.NVIC_IRQChannelSubPriority=1;//设置从占(响应)优先级
	NVIC_Init(&NVIC_InitStruct);
	//6.启动定时器
	TIM_Cmd(TIM2,ENABLE);
	
}

SMG数码管

#include "stm32f10x.h"                  // Device header
#include "Delay.h"

//5461BS-1为共阳型
u16 seg[] = {0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90};//共阳
//u16 seg[] = {0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};//共阴

extern u16 tim4Cnt;

void SMG_Init(void){
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE); //开启GPIOA的外设时钟
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE);
	
	//配置端口模式
	GPIO_InitTypeDef GPIO_InitStructureA;//定义结构体变量
	GPIO_InitStructureA.GPIO_Pin=GPIO_Pin_All;  //选择你要设置的IO口
	GPIO_InitStructureA.GPIO_Mode=GPIO_Mode_Out_PP;	 //设置推挽输出模式
	GPIO_InitStructureA.GPIO_Speed=GPIO_Speed_50MHz;	  //设置传输速率为50MHZ
	GPIO_Init(GPIOA,&GPIO_InitStructureA); 	   /* 初始化GPIO */
	
	//配置端口模式
	GPIO_InitTypeDef GPIO_InitStructureB;//定义结构体变量
	GPIO_InitStructureB.GPIO_Pin=GPIO_Pin_All;  //选择你要设置的IO口
	GPIO_InitStructureB.GPIO_Mode=GPIO_Mode_Out_PP;	 //设置推挽输出模式
	GPIO_InitStructureB.GPIO_Speed=GPIO_Speed_50MHz;	  //设置传输速率为50MHZ
	GPIO_Init(GPIOB,&GPIO_InitStructureB); 	   /* 初始化GPIO */
	
	GPIO_SetBits(GPIOA,GPIO_Pin_All);
}

void SMG_clean(){
	GPIO_WriteBit(GPIOB,GPIO_Pin_0,Bit_RESET);
	GPIO_WriteBit(GPIOB,GPIO_Pin_12,Bit_RESET);			
	GPIO_WriteBit(GPIOB,GPIO_Pin_13,Bit_RESET);			
	GPIO_WriteBit(GPIOB,GPIO_Pin_14,Bit_RESET);	
	Delay_ms(2);
}

//选择第w位,显示数字num
void SMG_Light(uint16_t w,uint16_t num){
	SMG_clean();
	//位选
	switch(w){
		case 0:
			GPIO_WriteBit(GPIOB,GPIO_Pin_0,Bit_SET);
			GPIO_WriteBit(GPIOB,GPIO_Pin_12,Bit_RESET);
			GPIO_WriteBit(GPIOB,GPIO_Pin_13,Bit_RESET);		
			GPIO_WriteBit(GPIOB,GPIO_Pin_14,Bit_RESET);	
			break;
		case 1:
			GPIO_WriteBit(GPIOB,GPIO_Pin_12,Bit_SET);
			GPIO_WriteBit(GPIOB,GPIO_Pin_0,Bit_RESET);
			GPIO_WriteBit(GPIOB,GPIO_Pin_13,Bit_RESET);
			GPIO_WriteBit(GPIOB,GPIO_Pin_14,Bit_RESET);
			break;
		case 2:
			GPIO_WriteBit(GPIOB,GPIO_Pin_13,Bit_SET);
			GPIO_WriteBit(GPIOB,GPIO_Pin_12,Bit_RESET);		
			GPIO_WriteBit(GPIOB,GPIO_Pin_0,Bit_RESET);			
			GPIO_WriteBit(GPIOB,GPIO_Pin_14,Bit_RESET);	
			break;
		case 3:
			GPIO_WriteBit(GPIOB,GPIO_Pin_14,Bit_SET);
			GPIO_WriteBit(GPIOB,GPIO_Pin_12,Bit_RESET);			
			GPIO_WriteBit(GPIOB,GPIO_Pin_13,Bit_RESET);			
			GPIO_WriteBit(GPIOB,GPIO_Pin_0,Bit_RESET);	
			break;
	}
	//段码
	GPIO_Write(GPIOA,seg[num]);
	Delay_ms(2);
}

main主函数

#include "stm32f10x.h"                  // Device header
#include "Delay.h"
#include "Key.h"
#include "SMG.h"
#include "Timer.h"

uint16_t i,Tim2Num,miao,shi,fen;

int main(void){
	Key_Init();
	SMG_Init();
	Timer_Init();
	while(1){
		//时钟
		miao=Tim2Num%60;
		SMG_Light(0,miao%10);//ge
		SMG_Light(1,miao/10);//shi
		fen=Tim2Num%3600/60;
		SMG_Light(2,fen%10);//ge
		SMG_Light(3,fen/10);//shi
		shi=Tim2Num%(24*3600)/3600;
	}
}

//每秒计时
void TIM2_IRQHandler(void){
	if(TIM_GetITStatus(TIM2,TIM_IT_Update)==SET){//更新中断
		Tim2Num++;
		TIM_ClearITPendingBit(TIM2,TIM_IT_Update);//清除标志位
	}
}

资料参考:

(75条消息) STM32F103C8T6 I/O口驱动4位共阳数码管_io口控制数码管_seaup2011的博客-CSDN博客

四位一体数码管LG5641BH共阳极引脚图,怎么读的?_百度知道 (baidu.com)

单片机数码管显示,看完这篇就够了 (zhihu.com)

  • 11
    点赞
  • 68
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 要驱动四位数码管tm,需要使用STM32的GPIO(通用输入输出端口)来控制LED的亮灭,而数字的显示需要借助定时器(TIM)的输出来扫描数码管。下面是具体的步骤: 1. 确定驱动方式:共阳极还是共阴极。STM32的GPIO输出只能为低电平或高电平,因此在连接数码管时,需要根据数码管的类型来选择适合的接口。 2. 连接数码管:将四个数码管的相应引脚连接到STM32的GPIO引脚上,并接上对应的限流电阻,以避免LED受到过大的电流而烧坏。 3. 配置GPIO输出:使用STM32库函数来配置GPIO口为输出模式,并设置其状态为高电平或低电平,以控制数码管的亮灭。 4. 配置定时器(TIM):用于控制数码管的扫描,可以使用STM32库函数来配置TIM,设定其工作模式为定时器模式,并设置定时器的计数周期和分频器等参数。 5. 编写扫描函数:使用STM32库函数来编写扫描函数,以实现对四个数码管的扫描。扫描函数需要在定时器中断中被调用,通过改变GPIO的输出状态来控制数码管的显示。 6. 编写主函数:在主函数中完成硬件初始化的工作,并调用扫描函数,以实现对四个数码管的连续显示。 总之,驱动四位数码管tm需要合理配置STM32的GPIO和定时器,编写相应的库函数和扫描函数,以实现对数码管的控制和显示。 ### 回答2: 要使用STM32驱动四位数码管TM,需要将数字信号转换为七段显示的格式,并且按照时序规则向数码管发送数据。具体实现步骤如下: 1.定义引脚:在程序开头,需要定义数码管使用的引脚。通常情况下,每个数码管有七条控制引脚,即A~G,以及一个表示位数的COM引脚。 2.编写显示函数:此函数将数字转换为七段显示的格式,并输入到引脚。 3.编写定时器中断函数:第一步中定义的COM引脚需要周期性的切换,以便依次控制每个数码管的显示。这可以通过定时器中断来完成。 4.编写主函数:在主函数中,设置定时器和中断,以及调用显示函数显示数字。 总的来说,STM32驱动四位数码管TM需要对硬件有一定的了解,并具有较强的编程能力。实现起来较为复杂,需要深入研究相关知识。同时可以借助一些开源的数码管驱动库,简化开发过程。 ### 回答3: 要驱动四位数码管,可以使用STM32的IO口和定时器来实现。首先需要连接四位数码管的引脚,将共阴(或共阳)的接到GND(或VCC),并将每个数码管的七段管对应的引脚分别接到对应的IO口,并在程序中配置为输出模式。然后需要设置一个定时器,用来刷新数码管的显示。最后,根据需要显示的数字或字母,设置对应的IO口状态和定时器刷新周期,就可以实现数码管的驱动。 具体实现步骤如下: 1. 在工程中添加定时器库文件和4位数码管驱动库文件。 2. 在程序中初始化IO口和定时器。配置IO口为输出模式,定时器的计数频率为1 kHz。 3. 在主函数中设置一个无限循环,并在其中循环显示需要显示的数字或字母。通过位运算和查表法,将数字或字母对应的控制码写入到对应的IO口中,实现四位数码管的显示。 4. 设置定时器中断,定时器每隔一定时间会触发中断函数。在中断函数中更改IO口状态,实现数码管的刷新。 5. 在主函数中延时一定时间,等待数码管显示后再显示下一个数据。 最终实现的效果是,可以通过STM32的IO口驱动四位数码管显示任意数字或字母,并且可以设置刷新频率控制显示效果。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值