蓝桥杯单片机——第十二届省赛部分问题

题目要求:

 

 根据题目要求本次涉及到了数码管显示、LED、NE555测量频率、PCF8091模块、独立按键

数码管显示:共有三个界面要显示。周期界面我理解为T= \frac{1}{f} (也来自于NE555)

LED显示:

这个模块与S7的长短按键关系十分密切。其中S7长短按键的用法参考了小蜜蜂老师的定时器方法https://blog.csdn.net/ohy3686/article/details/82927113

unsigned char count_7 = 0;//用于定时器计时
unsigned char K_7 = 0;//当开关按下后变为1开关断开后变为0
unsigned char K_7_flag = 0;//用于长按键循环
void key()
{
   if(S7 == 0)
   {
   	  delay(10);
	  if(S7 == 0)
	  {
	      K_7 = 1;
		  while(S7 == 0)
		  {
		     Display();
		  }
		     K_7 = 0;
			 if(count_7 > 5)   //按键长按
             {    
               K_7_flag++;
			   if(K_7_flag > 1)
			   {
			   	 K_7_flag = 0;
			   }
             }
             else              //按键短按
             {
               temp_1_stay = temp_1;//保存当前采集到的频率数据
             }
             count_7 = 0;      //按键计数值清零
		   
	  }
   }
}
//定时器
void InitTimer() //定时器1定时,定时器0计数
{
  TMOD = 0x16;
  
  TH0 = 0xff;
  TL0 = 0xff;
  TH1 = (65536-50000)/256;
  TL1 = (65536-50000)%256;

  EA = 1;
  ET0 = 1;
  ET1 = 1;
  TR0 = 1;
  TR1 = 1;
} 
void Timer1() interrupt 3
{
  TH1 = (65536-50000)/256;
  TL1 = (65536-50000)%256;
  
  count_t++;//测量频率用
  if(count_t == 20)
  {
  	 temp_1 = count_f;
	 temp_2 = 100000/count_f;
	 count_t = 0;
	 count_f = 0;
  } 

  if(K_7 != 0)
  {
  	count_7++;
  }
}
//S7长按键的功能判断在main函数中

PCF8091 :

涉及到光敏电阻、电位器的电压AD转换结果的显示问题。需要把0~255转换为0~5V内的电压显示

unsigned char i;//选择通道变量
unsigned char date;//存放得到的数据
//==================================电压
void ad_read()
{
  IIC_Start();
  IIC_SendByte(0x90);
  IIC_WaitAck();
  IIC_SendByte(i);
  IIC_WaitAck();
  IIC_Stop();

  IIC_Start();
  IIC_SendByte(0x91);
  IIC_Stop();
  date = IIC_RecByte();
  IIC_SendAck(0);
}

在电压显示:

void work()
{
    ad_read();
	temp_3 = date*(50000/255)/100;//此时数码管显示两位小数的0~5v电压
	a = 0xc1;//1100 0001
	b = 0xbf;//1011 1111
	c = SMG[i];
	d = 0xff;
	e = 0xff;
	f = SMG_Point[temp_3/100];
	g = SMG[(temp_3/10)%10];
	h = SMG[temp_3%10];
}
//abcdefgh对于数码管的8位显示内容

主函数:

长按键循环功能判断尝试了很多方法。如果只是简单的在key函数中判断K_7_flag对应的是关灯还是显示,这样得到的结果虽然能实现长按后关灯再长按后开灯,但是LED灯不再具有实时显示的功能。最终尝试放入主函数中的while(1)后完成了题目要求。

void main()
{  
  InitSystem();
  InitTimer();
  while(1)
  {
	key();
  	Work();

	Display();

	if(K_7_flag == 1)//长按键循环功能判断
    {
  	   stat_LED = 0xff;
	   InitHC138(4);
	   P0 = stat_LED;
    }
    else 
    {
       LED ();//只有将判断放入while(1)中LED才能实时显示
    }
  }
}

如果有更简单的方法欢迎大家提出。

猜你喜欢

转载自blog.csdn.net/weixin_49640235/article/details/124076462