这些小活动你都参加了吗?快来围观一下吧!>>
电子产品世界 » 论坛首页 » 嵌入式开发 » STM32 » 【原创】单片机学习心得--from雪

共2条 1/1 1 跳转至

【原创】单片机学习心得--from雪

工程师
2025-03-19 21:57:35     打赏

三行按键消抖

图片1.png

四舍五入保留两位小数

图片2.png

74CH573锁存器

图片3.png

传统51单片机(无锁存器设计)

直接驱动外设:10口直接连接LED、数码管等外设,无锁存器参与。

·缺点 :

信号稳定性差:动态扫描时寸(如数码管)易出现信号冲突或闪烁

IO资源浪费:每个外设需独占IO引脚,无法复用。

蓝桥杯单片机(基于74HC573锁存器)

锁存器功能:

信号保持:锁存器(如74HC573)可锁存10口状态,避免动态扫描时信号丢失,

资源复用:通过锁存器+74HC138译码器,实现多外设共享同一组10口(如PO和 P2)。

硬件设计:

锁存器使能控制:通过P2口高了位(P2.5-P2.7)控制74HC138译码器选择不同外设的锁存器使能信号(如Y4-Y7)。

典型应用:数码管段选、位选、LED、继电器等外设均通过锁存器管理。

12届省赛题练习

#include <STC15F2K60S2.H>//15单片机寄存器专属头文件
#include <Init.h>//初始化底层驱动专用头文件
#include <Key.h>//按键底层专属头文件
#include <Led.h>//Led底层驱动专用头文件
#include <Seg.h>//数码管底层专属头文件
#include <onewire.h>//温度读取底层专属头文件
#include "iic.h"
unsigned char Key_Slow_Down;//按键减速专用变量
unsigned char Key_Val,Key_Down,Key_Old,Key_Up;//按键专用变量
unsigned char Seg_Buf[8]={10,10,10,10,10,10,10,10};//数码管显示数据存放数组
unsigned char Seg_Point[8]={0,0,0,0,0,0,0,0};//数码管小数点数据存放数组
unsigned char Seg_Pos;//数码管扫描专用变量
unsigned int Seg_Slow_Down;//数码管减速专用变量
unsigned char ucLed[8]={0,0,0,0,0,0,0,0};//Led显示数据存放数组
unsigned char Seg_Disp_Mode;//数码管显示界面 0-温度显示界面 1-参数设置界面 2-DAC输出界面
float t;
unsigned char P_Data=25;
unsigned char P_Data_Ctrol=25;
float DAC_Disp;
bit OutPut_Mode;
/*键盘处理函数*/
void Key_proc()
{
 if(Key_Slow_Down) return;
 Key_Slow_Down=1;//键盘减速程序
 Key_Val = Key_Read();//实时读取按键数据
 Key_Down = Key_Val&(Key_Old^Key_Val);//捕捉按键下降沿
 Key_Up = ~Key_Val&(Key_Old^Key_Val);//捕捉按键上升沿
 Key_Old = Key_Val;//辅助按键扫描
 switch(Key_Down)
 {
  case 4://界面切换按键
   if(++Seg_Disp_Mode==3)
    Seg_Disp_Mode=0;//当前处于温度参数设置界面
      if(Seg_Disp_Mode==1)
    P_Data=P_Data_Ctrol;//将实际控制数据赋值给设置变量
   if(Seg_Disp_Mode==2)//当界面从参数设置切换出去后
    P_Data_Ctrol=P_Data;//将设置数据保存到控制变量
  break;
  case 8://参数自减按键
   if(Seg_Disp_Mode==1)//当前处于温度参数设置界面
   {
    if(--P_Data==255)//限制温度下限为0
     P_Data=0;  
   } 
  break; 
  case 9://参数自加按键
   if(Seg_Disp_Mode==1)
   {
    if(++P_Data==100)
     P_Data=99; 
   } 
  break;
  case 5://模式切换按键
   OutPut_Mode^=1;//切换输出模式
        break;  
 }
}
void Seg_Proc()
{
 if(Seg_Slow_Down) return;
 Seg_Slow_Down=1;//数码管减速程序
 /*信息获取区域*/
 t=rd_temperature();
 /*数据显示区域*/
 switch(Seg_Disp_Mode)
 {
  case 0://温度显示界面
   Seg_Buf[0]=11;//标识符C
   Seg_Buf[4]=(unsigned char)(t/10)%10;
   Seg_Buf[5]=(unsigned char)t%10;
   Seg_Point[5]=1;
   Seg_Buf[6]=(unsigned int)(t*10)%10;
   Seg_Buf[7]=(unsigned int)(t*100)%10;
  break;
  case 1://参数设置界面
   Seg_Buf[0]=12;//标识符P
   Seg_Buf[4]=Seg_Buf[5]=10;//熄灭第五、第六个数码管
   Seg_Point[5] = 0;//关闭小数点
   Seg_Buf[6]=P_Data/10%10;
   Seg_Buf[7]=P_Data%10;
  break; 
  case 2://DAC输出界面
   Seg_Buf[0]=13;
   Seg_Buf[5]=(unsigned char)DAC_Disp;
      Seg_Buf[6]=(unsigned int)(DAC_Disp*10)%10;
      Seg_Buf[7]=(unsigned int)(DAC_Disp*100)%10;
      Seg_Point[5]=1;
  break;
 }
}
void Led_Proc() 
{
 unsigned char i;//用于for循环
 if(OutPut_Mode==0)//DAC输出电压与温度相关
 {
  if(t<P_Data_Ctrol)
   DAC_Disp=0;//DAC输出0V
  else
   DAC_Disp=5;//DAC输出5V
 }
 else
 { 
  if(t<20)//当实时温度小于20度时
   DAC_Disp=1;
  else if(t>40)//当实时温度小于40度时
   DAC_Disp=4;
  else//当实时温度在20-40之间时
   DAC_Disp=0.15*(t-20)+1;//DAC输出与实时温度为一次函数关系
 }
 Da_Write(DAC_Disp*51);//实时输出DAC
 /*Led相关*/
 ucLed[0] = !OutPut_Mode;//当前处于模式 1 状态,指示灯 L1 点亮,否则熄灭
 for(i=0;i<3;i++)
 {
  ucLed[i+1]=(i==Seg_Disp_Mode);
 }
}
void Timer0Init(void)  //1毫秒@12.000MHz
{
 AUXR &= 0x7F;  //定时器时钟12T模式
 TMOD &= 0xF0;  //设置定时器模式
 TL0 = 0x18;  //设置定时初值
 TH0 = 0xFC;  //设置定时初值
 TF0 = 0;  //清除TF0标志
 TR0 = 1;  //定时器0开始计时
 ET0=1;      //定时器中断0打开
 EA=1;       //总中断打开
}
/*定时器0中断服务函数*/
void Timer0Server() interrupt 1
{
 if(++Key_Slow_Down==10)Key_Slow_Down=0;//按键减速专用
 if(++Seg_Slow_Down==500)Seg_Slow_Down=0;//数码管减速专用
 if(++Seg_Pos==8)Seg_Pos=0;//数码管显示专用
 Seg_Disp(Seg_Pos,Seg_Buf[Seg_Pos],Seg_Point[Seg_Pos]);
 Led_Disp(Seg_Pos,ucLed[Seg_Pos]);
}
void Delay750ms()  //@12.000MHz
{
 unsigned char i, j, k;
 i = 35;
 j = 51;
 k = 182;
 do
 {
  do
  {
   while (--k);
  } while (--j);
 } while (--i);
}
void main()
{
 rd_temperature();
 Delay750ms(); 
 System_Init();
 Timer0Init();
 while(1)
 {
  Key_Proc();  // 处理按键
  Seg_Proc();  // 更新数码管显示
  Led_Proc();  // 更新LED显示
 }
}



专家
2025-03-20 07:04:59     打赏
2楼

谢谢分享


共2条 1/1 1 跳转至

回复

匿名不能发帖!请先 [ 登陆 注册 ]