基于STM32程序万年历液晶1602显示-proteus仿真-源程序

一、系统方案
本设计采用STM32单片机作为主控器,液晶1602显示,按键设置万年历。
在这里插入图片描述
二、硬件设计
原理图如下:
在这里插入图片描述
三、单片机软件设计
1、首先是系统初始化
//通用定时器3中断初始化
//这里时钟选择为APB1的2倍,而APB1为36M
//arr:自动重装值。
//psc:时钟预分频数
//这里使用的是定时器3!
void TIM3_Init(u16 arr,u16 psc)
{
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
NVIC_InitTypeDef NVIC_InitStructure;

RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM1, ENABLE); //仿真必须加
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE); //时钟使能

//定时器TIM3初始化  C 语言结构体Struct、指针*  ->  &、类型定义typedef

TIM_TimeBaseStructure.TIM_Period = arr; //设置在下一个更新事件装入活动的自动重装载寄存器周期的值	
TIM_TimeBaseStructure.TIM_Prescaler =psc; //设置用来作为TIMx时钟频率除数的预分频值
TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1; //设置时钟分割:TDTS = Tck_tim
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;  //TIM向上计数模式
TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure); //根据指定的参数初始化TIMx的时间基数单位

TIM_ITConfig(TIM3,TIM_IT_Update,ENABLE ); //使能指定的TIM3中断,允许更新中断

//中断优先级NVIC设置
NVIC_InitStructure.NVIC_IRQChannel = TIM3_IRQn;  //TIM3中断
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;  //先占优先级0级
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3;  //从优先级3级
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //IRQ通道被使能
NVIC_Init(&NVIC_InitStructure);  //初始化NVIC寄存器

// TIM_Cmd(TIM1, ENABLE); //使能TIMx
TIM_Cmd(TIM3, ENABLE); //使能TIMx
}
2、液晶显示程序
void LCD1602_GPIO_Config(void)
{
RCC_APB2PeriphClockCmd(LCD1602_CLK, ENABLE);
GPIO_InitTypeDef LCD1602_GPIOStruct;
LCD1602_GPIOStruct.GPIO_Mode = GPIO_Mode_Out_PP;
LCD1602_GPIOStruct.GPIO_Speed = GPIO_Speed_10MHz;
LCD1602_GPIOStruct.GPIO_Pin = LCD1602_E | LCD1602_RS | LCD1602_RW ;
GPIO_Init(LCD1602_GPIO_PORT,&LCD1602_GPIOStruct);
LCD1602_GPIOStruct.GPIO_Mode = GPIO_Mode_Out_OD;
LCD1602_GPIOStruct.GPIO_Pin = DB0 | DB1 | DB2 |DB3 | DB4 | DB5|
DB6 | DB7 ; //设置为开漏输出
GPIO_Init(LCD1602_GPIO_PORT,&LCD1602_GPIOStruct);
}

void LCD1602_WaitReady(void) //检测忙状态
{
uint8_t sta;

GPIOB->ODR =0x00FF;
RSO(0);
RWO(1);
EO(1);
SysTick_Delay_Us(1);
do{
	sta=GPIO_ReadInputDataBit(LCD1602_GPIO_PORT,GPIO_Pin_7);
	EO(0);
}while(sta);

}

void LCD1602_WriteCmd(uint8_t cmd) //写指令
{
LCD1602_WaitReady();
RSO(0);
RWO(0);
EO(0);
SysTick_Delay_Us(1);
EO(1);
LCD1602_GPIO_PORT->ODR &= (cmd|0xFF00);
EO(0);
SysTick_Delay_Us(400);
}

void LCD1602_WriteDat(uint8_t dat) //写数据
{
LCD1602_WaitReady();
RSO(1);
RWO(0);
SysTick_Delay_Us(30);
EO(1);
LCD1602_GPIO_PORT->ODR &=(dat|0xFF00);
EO(0);
SysTick_Delay_Us(400);
}

3、按键程序
void KEY_Scan( void )
{

 if(KEY1==0)			//读取K1按键状态
	{
		SysTick_Delay_Ms(10);
		if(KEY1==0)
		{
			while(KEY1==0);
		 	KEY_num++;
			 TIM_ITConfig(TIM3,TIM_IT_Update,DISABLE);   //禁止TIM3中断
			TIM_Cmd(TIM3,DISABLE);        
			if( KEY_num >=8 )
			{
				KEY_num = 0;
				
			  TIM_ITConfig(TIM3,TIM_IT_Update,ENABLE);//开启定时器
			  TIM_Cmd(TIM3,ENABLE);
			} 
		
		}
	}
	if(KEY2==0)			//读取K2按键状态,加
	{
		SysTick_Delay_Ms(10);
		if(KEY2==0)
		{
			while(KEY2==0);
				if( KEY_num == 1 )
			{
				nian++;
				if( nian > 2999 )
				{
					nian = 0;
				}
			}
			if( KEY_num == 2 )
			{
				yue++;
				if( yue > 12 )
				{
					yue = 1;
				}
			}
			if( KEY_num == 3 )
			{
				ri++;
				if( ri > 30 )
				{
					ri = 1;
				}
			}
			if( KEY_num == 4 )
			{
				shi++;
				if( shi > 23 )
				{
					shi = 0;
				}
			}
			if( KEY_num ==5 )
			{
				fen++;
				if( fen > 59 )
				{
					fen = 0;
				}
			}
			if( KEY_num == 6 )
			{
				miao++;
				if( miao > 59 )
				{
					miao = 0;
				}
			}
			if( KEY_num == 7 )
			{
				week++;
				if( week > 7 )
				{
					week = 1;
				}
			}
			Display_Time();
		
		}
	}
	if(KEY3==0)			//读取K3按键状态,减
	{
		SysTick_Delay_Ms(10);
		if(KEY3==0)
		{
			while(KEY3==0);
		 	if( KEY_num == 1 )
			{
				nian--;
				if( nian < 2000 )
				{
					nian = 2999;
				}
			}
			if( KEY_num == 2 )
			{
				yue--;
				if( yue <= 0 )
				{
					yue = 12;
				}
			}
			if( KEY_num == 3 )
			{
				ri--;
				if( ri <= 0 )
				{
					ri = 30;
				}
			}
			if( KEY_num == 4 )
			{
				shi--;
				if( shi <= 0 )
				{
					shi = 23;
				}
			}
			if( KEY_num == 5 )
			{
				fen--;
				if( fen <= 0 )
				{
					fen = 59;
				}
			}
			if( KEY_num == 6 )
			{
				miao--;
				if( miao <= 0 )
				{
					miao = 59;
				}
			}
			if( KEY_num == 7 )
			{
				week--;
				if( week <= 0 )
				{
					week = 7;
				}
			}
		Display_Time();
		
		}
	}

}
4、核心算法程序
//定时器3中断服务程序
void TIM3_IRQHandler(void) //TIM3中断
{
miao++;
if( miao==60)
{
miao = 0;
fen++;
if( fen 60)
{
fen=0;
shi++;
if( shi
24 )
{
shi = 0;
week++;
if(week>7) week=1;
ri++;
if( ri > 30 )
{
ri = 0;
yue++;
if( yue > 12 )
{
yue = 0;
nian++;
if( nian > 2999 )
{
nian = 0;
}
}
}
}

	}
}

TIM_ClearITPendingBit(TIM3, TIM_IT_Update  ); //TIM_IT_Update=0
//清除TIM3更新中断标志 进中断1(硬件),为保证下次再产生中断软件清中断标志

}
四、 proteus仿真设计
Proteus软件是一款应用比较广泛的工具,它可以在没有硬件平台的基础上通过自身的软件仿真出硬件平台的运行情况,这样就可以通过软件仿真来验证我们设计的方案有没有问题,如果有问题,可以重新选择器件,连接器件,直到达到我们设定的目的,避免我们搭建实物的时候,如果当初选择的方案有问题,我们器件都已经焊接好了,再去卸载下去,再去焊接新的方案的器件,测试,这样会浪费人力和物力,也给开发者带来一定困惑,Proteus仿真软件就很好的解决这个问题,我们在设计之初,就使用该软件进行模拟仿真,测试,选择满足我们设计的最优方案。最后根据测试没问题的仿真图纸,焊接实物,调试,最终完成本设计的作品。
在这里插入图片描述

  • 2
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

bbxyliyang

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

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

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

打赏作者

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

抵扣说明:

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

余额充值