蓝桥杯单片机第七届国赛题目-电压频率采集设备

Posted _WILLPOWER_

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了蓝桥杯单片机第七届国赛题目-电压频率采集设备相关的知识,希望对你有一定的参考价值。

题目

要点

  1. 选取数码管闪烁
  2. NE555初始化和检测检测

  1. 矩阵按键

    其他应该就没有什么难点了,很常规这套题,只不过就是题没说清楚开机的时候应该处于什么状态,这里我默认就是时钟显示状态了

文件树

代码

init.c

#include "init.h"

uchar code table[4][4] = {0,1,1,1, 1,0,1,1, 1,1,0,1, 1,1,1,0};
void SL(uchar _dev, uchar _data)
{
  P0=_data;SEL(_dev);
}
void Timer1Init(void)		//2毫秒@12.000MHz
{
	AUXR |= 0x40;		//定时器时钟1T模式
	TMOD &= 0x0F;		//设置定时器模式
	TL1 = 0x40;		//设置定时初值
	TH1 = 0xA2;		//设置定时初值
	TF1 = 0;		//清除TF1标志
	TR1 = 1;		//定时器1开始计时
 ET1 = 1;
 EA = 1;
}
void BF(_0, _1, _2, _3, 
        _4, _5, _6, _7)
{
 buf[0] = _0; buf[1] = _1; buf[2] = _2; buf[3] = _3;
 buf[4] = _4; buf[5] = _5; buf[6] = _6; buf[7] = _7;
}
uchar FR(float _data, uchar _dig)
{
 uint i = 1;
 while(_dig--)
 {
  i = i * 10;
 }
 return((uint)_data/i%10);
}
//uchar LedChange(uchar _data, uchar _dig, uchar _en)
//{
// if(_en == 1)
// {
//  _data &= ~(1 << _dig);
// }
// else if(_en == 0)
// {
//  _data |= (1 << _dig);
// }
// else
// {
//  _data ^= (1 << _dig);
// }
// SL(4, _data);
// return _data;
//}

void Run(t_delay* time)
{
 if(time->cnt++ < time->max);
 else
 {
  time->cnt = 0; 
  time->ok = 1;
 }
}

void NE555Init()
{
 AUXR |= 0x80;
 TMOD |= 0x05;
}

void NE555Read()
{
 if(delay_500.ok == 0)
 {
  TH0 = 0; TL0 = 0; TR0 = 1;
  delay_500.ok = 2;
 }
 if(delay_500.ok == 1)
 {
  delay_500.ok = 0;
  delay_500.cnt = 0;
  TR0 = 0;
  neVal = ((uint)TH0<<8) | TL0;
 }
}

uchar GetKey()
{
 uchar i;
 C1 = 1; C2 = 1;
 for(i = 0; i < 4; i++)
 {
  R1 = table[i][0];R2 = table[i][1];
  R3 = table[i][2];R4 = table[i][3];
  if(C1 == 0) return(2*i + 1);
  if(C2 == 0) return(2*i + 2);
 }
 //!!!!!!!
 return 0;
}

main.c

#include "init.h"

enum{LED=4,EXT,SEL,CODE};
uchar ledData = 0xff;

//显示
uchar buf[8];
uchar code CA[] = {0xc0, 0xf9, 0xa4, 0xb0, 0x99,
                   0x92, 0x82, 0xf8, 0x80, 0x90,
                   0xff, 0xbf};
uchar curDig = 0;
//按键
enum{KS_GT,KS_AS,KS_WA}keyState = KS_GT;
uchar key = 0, tmpKey = 0, keyCnt = 0;
                   
//变量
t_delay delay_200 = {200, 0, 0};    
t_delay delay_500 = {500, 0, 0};
t_delay delay_250 = {250, 0, 0};
uint neVal;
uint hlv[] = {2000,1000};
uchar chlv[] = {(2000 >> 8), 2000, (1000 >> 8), 1000};
uchar timeDig = 250;
uchar volDig = 250;
uchar freDig = 0;     
uchar leiXing = 0;
uchar cxDig = 0;
uchar storetime[3] = {12, 12, 12};

//状态
enum{S_TIME, S_VOL, S_FRE, S_CX}gloSta = S_TIME;

void Timer1Handle() interrupt 3
{
 SL(CODE, 0xff); SL(SEL, 1<<curDig); SL(CODE, CA[buf[curDig]]);
 curDig = (curDig + 1)%8;
 //按键
 switch(keyState)
 {
  case KS_GT:
   keyCnt = 0; tmpKey = GetKey(); keyState = KS_AS;
  break;
  case KS_AS:
   if(keyCnt++ < 10);
   else if(tmpKey == GetKey())
   {
    if(key != tmpKey)
    {
     key = tmpKey;
     keyState = KS_WA;
    }
    else
     keyState = KS_GT;
   }
   else
   {
    keyState = KS_GT;
   }
  break;
 }
 //计时
 Run(&delay_200);
 if(delay_500.ok == 2)
 Run(&delay_500);
 Run(&delay_250);
}
//显示处理
void DisProcess()
{
 switch(gloSta)
 {
  //如果是时钟状态
  case S_TIME:
   //如果在时钟显示,则直接显示
   if(timeDig == 250)
   BF(FR(time[2], 1), FR(time[2], 0),F_SEP,
      FR(time[1], 1),FR(time[1], 0),F_SEP,FR(time[0], 1),FR(time[0], 0));
   //否则是在时钟设置状态
   else
   {
    //500ms闪烁
    if(delay_250.ok == 1)
    {
     delay_250.ok = 0;
     //根据设置的具体位置决定闪烁在哪
     switch(timeDig)
     {
      case 0:
       if(buf[0] == F_C)
       BF(FR(time[2], 1), FR(time[2], 0),F_SEP,
          FR(time[1], 1),FR(time[1], 0),F_SEP,FR(time[0], 1),FR(time[0], 0));
       else
       BF(F_C, F_C,F_SEP,
          FR(time[1], 1),FR(time[1], 0),F_SEP,FR(time[0], 1),FR(time[0], 0));
      break;
      
      case 1:
       if(buf[3] == F_C)
       BF(FR(time[2], 1), FR(time[2], 0),F_SEP,
          FR(time[1], 1),FR(time[1], 0),F_SEP,FR(time[0], 1),FR(time[0], 0));
       else
       BF(FR(time[2], 1), FR(time[2], 0),F_SEP,
          F_C,F_C,F_SEP,FR(time[0], 1),FR(time[0], 0));
      break;
      
      case 2:
       if(buf[6] == F_C)
       BF(FR(time[2], 1), FR(time[2], 0),F_SEP,
          FR(time[1], 1),FR(time[1], 0),F_SEP,FR(time[0], 1),FR(time[0], 0));
       else
       BF(FR(time[2], 1), FR(time[2], 0),F_SEP,
          FR(time[1], 1),FR(time[1], 0),F_SEP,F_C,F_C);
      break;
     }
    }
   }
  break;
   
 case S_VOL:
   if(volDig == 250)
    BF(F_SEP, 1,F_SEP,
       F_C,FR(adcVal, 3),FR(adcVal, 2),FR(adcVal, 1),FR(adcVal, 0));
   //如果是电压触发阈值设置
   else
   {
    if(delay_250.ok == 1)
    {
     delay_250.ok = 0;
     //根据设置的位置闪烁
     switch(volDig)
     {
      case 0:
       if(buf[0] == F_C)
        BF(FR(hlv[0], 3), FR(hlv[0], 2),FR(hlv[0], 1),FR(hlv[0], 0),
          FR(hlv[1], 3), FR(hlv[1], 2),FR(hlv[1], 1),FR(hlv[1], 0));
       else
        BF(F_C, F_C,F_C,F_C,
          FR(hlv[1], 3), FR(hlv[1], 2),FR(hlv[1], 1),FR(hlv[1], 0));
      break;
      
      case 1:
       if(buf[4] == F_C)
        BF(FR(hlv[0], 3), FR(hlv[0], 2),FR(hlv[0], 1),FR(hlv[0], 0),
          FR(hlv[1], 3), FR(hlv[1], 2),FR(hlv[1], 1),FR(hlv[1], 0));
       else
        BF(FR(hlv[0], 3), FR(hlv[0], 2),FR(hlv[0], 1),FR(hlv[0], 0),
           F_C, F_C,F_C,F_C);
      break;
          
    }
   }
  }
  break;
  case S_FRE:
   if(freDig == 0)
   BF(F_SEP, 2, F_SEP,FR(neVal, 4),
      FR(neVal, 3), FR(neVal, 2),FR(neVal, 1),FR(neVal, 0));
   //如果是周期显示,则显示周期
   else if(freDig == 1)
   {
    float m;
    m = 1000000/neVal; //周期
    BF(F_SEP, 2, F_SEP,FR(m, 4),
       FR(m, 3), FR(m, 2),FR(m, 1蓝桥杯单片机第七届国赛笔记

蓝桥杯单片机第七届国赛笔记

蓝桥杯单片机第七届国赛笔记

蓝桥杯单片机第七届国赛笔记

蓝桥杯单片机第九届国赛题目-多功能测量仪表

蓝桥杯单片机第九届国赛题目-多功能测量仪表