蓝桥杯单片机学习记录3——第11届省赛真题练习1

蓝桥杯单片机学习记录3——第11届省赛真题练习1

前言

上一篇我们练习了第5届的省赛题,虽然这一届用的外设还挺多的,有ADC,RTC,EEPROM及基础外设全用上,但难度依然不是很高。
这次我们来练习第11届的省赛题,这一届的赛题有两题,温度采集与输出和模拟电压计数,这两题我都会出一篇讲解。这两题用的外设和功能要求都不是很多,但拿来练手还是可以的。

赛题要求

硬件框图

图1

基础外设这部分数码管和LED两题都有用到,区别是按键,这里用的是BTN独立按键。
这里还用了温度测量和DAC的功能

功能描述

  1. 显示功能
    图2
  2. 按键功能
    图3
    图4
  3. DAC输出功能和LED指示灯功能
    图5
  4. 初始状态说明

初始状态上电默认处于数据显示界面。
温度上限参数 TMAX = 30℃
温度下限参数 TMIN = 20℃

设计思路

功能逻辑框图

yysy这个功能要求的确实少…对比第五届就显得过于简单了一点吧…
图6

代码实现框图

依旧是四线一区的框架
图7

代码分析

main.c

#include <STC15F2K60S2.H>
#include "hardware.h"
#include "iic.h"
#include "onewire.h"

bit StateFlag=0,TSFalg=0,TFlag=1,addFlag=0,subFlag=0;
u8 KeyNum, T, State=0, Page=0, TSelect=0;
u8 TMAX=30, TMIN=20;

void main()
{
  InitInterrupt();
  InitSystem();
  DS18B20_ConvertT();
  
  while(1)
  {
    Date_Task();
    Key_Task();
    Logic_Task();
    Seg_Task();
  }
}
  • 定时器功能函数
void InitInterrupt(void)
{
  TMOD = 0x01;
  TH0 = (65535 - 10000) / 256;
  TL0 = (65535 - 10000) % 256;
  ET0 = 1;
  TR0 = 1;
  EA = 1;
}
void Timer0() interrupt 1
{
  static u8 cnt;
  TL0 = (65535 - 10000) / 256;
  TH0 = (65535 - 10000) % 256;
  
  cnt++;
  if(cnt >= 1)
  {
    KeyLoop();
    cnt = 0;
  }
}
  • 数据更新函数
void Date_Task(void)
{
  T = DS18B20_ReadT();	//读取DS18B20测量的温度
  KeyNum = Key();		//读取按键键值
}
  • 按键任务函数
void Key_Task(void)
{
  if(KeyNum == 4)   //按键S4功能
  {
    StateFlag = 1;TFlag = 1; 	//状态和温度选择标志位打开
  }
  if(KeyNum == 5)   //按键S5功能
  {
    if(Page == 1)				//设置页面时温度选择标志位打开
    {
      TSFalg = 1;
    }
  }
  if(KeyNum == 6)   //按键S6功能
  {
    if(Page == 1)				//设置页面时温度加1标志位打开
    {
      addFlag = 1;
    }
  }
  if(KeyNum == 7)   //按键S7功能
  {
    if(Page == 1)				//设置页面时温度减1标志位打开
    {
      subFlag = 1;
    }
  }
}
  • 显示任务函数
void Seg_Task(void)
{
  switch(Page)			//0为显示页面,1为设置页面
  {
    case 0:
    Nixie(1,10);
    Nixie(7,T/10);
    Nixie(8,T%10);
    break;
    case 1:
    Nixie(1,11);
    Nixie(4,TMAX/10);
    Nixie(5,TMAX%10);
    Nixie(7,TMIN/10);
    Nixie(8,TMIN%10);
    break;
  }
  
}

-逻辑任务函数

void Logic_Task(void)
{
  Page_Task();
  DAC_Task();
  LED_Task();
}

//页面任务函数
void Page_Task(void)
{
  if(StateFlag)		//当状态标志位打开,选择状态
  {
    switch(State)
    {
      case 0:Page=0;State=1;StateFlag=0;break;  //显示页面,状态标志位关闭
      case 1:Page=1;State=0;StateFlag=0;break;  //设置页面,状态标志位关闭
    }
  }
  
  if(TSFalg)		//当温度标志位打开,选择温度
  {
    switch(TSelect)
    {
      case 0:TFlag=0;TSelect=1;TSFalg=0;break;  //选择TMAX,温度标志位关闭
      case 1:TFlag=1;TSelect=0;TSFalg=0;break;  //选择TMIN,温度标志位关闭
    }
  }
  
  if(TFlag==0&&addFlag==1)	//TMAX+1
  {
    ++TMAX;
    addFlag = 0;
  }
  if(TFlag==1&&addFlag==1)	//TMIN+1
  {
    ++TMIN;
    addFlag = 0;
  }
  if(TFlag==0&&subFlag==1)	//TMAX-1
  {
    --TMAX;
    subFlag = 0;
  }
  if(TFlag==1&&subFlag==1)	//TMIN-1
  {
    --TMIN;
    subFlag = 0;
  }
  
  if(TMAX > 99) TMAX = 1;			//使TMAX和TMIN在一个合理的数值范围间调节
  else if(TMAX < 1) TMAX = 99;
  if(TMIN > 99) TMIN = 1;
  else if(TMIN < 1) TMIN = 99;
  
  if(Page == 0)			//在返回显示页面时当TMAX<TMIN,不能返回显示页面
  {
    if(TMAX < TMIN)
    {
      Page=1;State=0;
    }
  }
}

//DAC任务函数
void DAC_Task(void)
{
  if(T > TMAX)  DAC(204);	//输出4.0V,0xcc
  else if((T<=TMAX) && (T>=TMIN))  DAC(156);	//输出3.0V,0x99
  else if(T < TMIN)  DAC(102);	//输出2.0V,0x66
}

//LED任务函数
void LED_Task(void)
{
  if(TMAX < TMIN) OutputP0(4,~0x08);
  else
  {
    if(T > TMAX)  OutputP0(4,~0x01);
    else if((T<=TMAX) && (T>=TMIN))  OutputP0(4,~0x02);
    else if(T < TMIN)  OutputP0(4,~0x04);
  }
}

harwdare.c,iic.c,OneWire.c这些文件的API函数我就不放出来了跟之前发过的一样,后面也是会考虑出一个合集的。

小结

总结一下就是非常简单,基本上是没什么难度的,任务要求我也是全部都完成了。
后面会接着更新第二题,觉得对你有帮助的话记得点赞加关注哦 >_< !

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值