Blue Bridge Cup SCM——Part of the 12th Provincial Competition

Topic requirements:

 

 According to the requirements of the topic, this time involves digital tube display, LED, NE555 measurement frequency, PCF8091 module, and independent buttons

Digital tube display: There are three interfaces to be displayed. I understand the cycle interface as T= \frac{1}{f} (also from NE555)

LED display:

This module is closely related to the long and short keys of S7. Among them, the usage of the S7 long and short keys refers to the timer method of the little bee teacher 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 :

It involves the display of the voltage AD conversion results of photoresistors and potentiometers. It is necessary to convert 0~255 to a voltage display within 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);
}

On the voltage display:

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位显示内容

main function:

Many methods have been tried to judge the long-press cycle function. If it is simply judged in the key function whether K_7_flag corresponds to turning off the light or displaying, although the result obtained in this way can turn off the light after a long press and then turn on the light after a long press, the LED light no longer has the function of real-time display. Finally, I tried to put it into the while (1) in the main function and completed the topic requirements.

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才能实时显示
    }
  }
}

If there is an easier way, please suggest it.

Guess you like

Origin blog.csdn.net/weixin_49640235/article/details/124076462