今天给大家带来第七届(2016)省赛题目的解析,题目总体不算难,我们一起来看看吧。

题目

这次省赛题整体还是不难的,做起来除了PWM不是很好理解以外,其他的还是很好理解的,最重要的是编程的逻辑。题目考察了LED显示、按键、数码管显示(这三个模块是每套题目都会考的,我们应该要很熟悉了)、PWM、DS18B20。

1 数码管显示

数码管有两种模式,一种是工作模式,一种是室温模式。我们可以写两个界面函数,一个用来显示工作模式,另一个显示室温模式,通过按键来选择显示哪种模式。

2 LED显示

定义一个变量mode,通过按键来控制mode的值让它在1-3之间循环。mode为1时L1亮,mode为2时L2亮,mode为3时L3亮。

3 按键模块

题目是用了s4,s5,s6,s7四个按键,是独立键盘。s4用来控制mode的值。s5用来控制倒计时,也定义一个countdown_mode变量在1-3之间循环,countdown_mode为1时倒计时为0,countdown_mode为2时倒计时为60,countdown_mode为3时倒计时为120。s6就是把countdown_mode设置为1。s7有两个状态,定义一个temp_m变量来控制,为1时显示室温模式,为0时显示工作模式。

4 pwm

由于pwm的信号频率为1KHz,就是1ms。P34引脚有连接定时器0,我们用1ms的定时器0来控制pwm的占空比,比如当pwm的占空比为20%时,就可以用定时器0控制让L1亮0.2ms,灭0.8ms来显示pwm的占空比。具体看代码。

5 DS18B20

就是改写底层驱动代码部分(onewire),然后放在定时器里,每隔一段时间去测量一次。

onewire.c

#include"onewire.h"#define u8 unsigned char
#define u16 unsigned int bit initflag;
sbit DQ=P1^4;void Delay1us()
{_nop_();_nop_();_nop_();
}void delay_us(unsigned int us)
{while(us--){Delay1us();}
}bit init_ds18b20()
{DQ=0;delay_us(500);DQ=1;delay_us(20);initflag=DQ;delay_us(50);return initflag;
}unsigned int get_temp()
{unsigned char low,high;unsigned int result;float i;init_ds18b20();//³õʼ»¯ds18b20_wirteByte(0xcc);ds18b20_wirteByte(0x44);init_ds18b20();ds18b20_wirteByte(0xcc);ds18b20_wirteByte(0xbe);low=ds18b20_readByte();high=ds18b20_readByte();result=high&0x0f;result<<=8;result=result|low;i=result*0.0625;result=i*100;return result;}void ds18b20_wirteByte(unsigned char dat)
{unsigned char i=0;for(i;i<8;i++){DQ=0;DQ=dat&0x01;delay_us(65);DQ=1;dat=dat>>1;}
}u8 ds18b20_readByte()
{unsigned char i=0;unsigned char dat;for (i;i<8;i++){DQ=0;dat=dat>>1;DQ=1;if(DQ){dat|=0x80; }delay_us(15);}return dat;
}

onewire.h

#ifndef _ONEWIRE_H_
#define _ONEWIRE_H_#define u8 unsigned char
#define u16 unsigned int #include<STC15F2K60S2.h>
#include"intrins.h"void Delay1us();
void delay_us(u16 us);
bit init_ds18b20();
u16 get_temp();
void ds18b20_wirteByte(u8 dat);
u8 ds18b20_readByte();#endif

INIT.c

个人喜欢把初始化、定时器、数码管显示、键盘放在一个模块里。

#include"INIT.h"#define u8 unsigned char
#define u16 unsigned int
#define state P3
#define state_0 0
#define state_1 1
#define state_2 2u8 tab[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0xbf,0xff,0xc6};
u8 seg[]={11,11,11,11,11,11,11,11};static  u8 key_state=0;
static  u8 segadder=0;u8 row=0,key_press=0,key_num=0;void all_init()  //关闭无关的外设
{P2=(P2&0x1f)|0x80;P0=0xff;P2&=0x1f;P2=(P2&0x1f)|0xa0;P04=0;P06=0;P2&=0x1f;P2=(P2&0x1f)|0xc0;P0=0x00;P2&=0x1f;P2=(P2&0x1f)|0xe0;P0=0xff;P2&=0x1f;
}void display()    //数码管显示函数
{P2=(P2&0x1f)|0xe0;  //消隐P0=0xff;P2&=0x1f;P2=(P2&0x1f)|0xc0;   //位选P0=1<<segadder;P2&=0x1f;P2=(P2&0x1f)|0xe0;  //段选P0=tab[seg[segadder]];P2&=0x1f;if(++segadder==8)segadder=0;
}u8 read_key()   //独立键盘
{switch(key_state){case state_0:state=0x0f;key_press=state;if(key_press!=0x0f)key_state=state_1;break;case state_1:key_press=state;    if(key_press!=0x0f){if((key_press & 0x08)==0) row=4;if((key_press & 0x04)==0) row=5;if((key_press & 0x02)==0) row=6;if((key_press & 0x01)==0) row=7;key_state=state_2;}elsekey_state=state_0;break;case state_2:state=0x0f;key_press=state;if(key_press==0x0f)key_state=state_0;    break;      }key_num=row;row=0;return key_num;
}void Timer0Init(void)      //100us
{AUXR |= 0x80;     TMOD &= 0xF0;      TL0 = 0xAE;        TH0 = 0xFB;        TF0 = 0;       TR0 = 1;       EA = 1;
}void Timer1Init(void)      //1ms
{AUXR |= 0x40;     TMOD &= 0x0F;      TL1 = 0xCD;        TH1 = 0xD4;        TF1 = 0;       TR1 = 1;   ET1 = 1;EA = 1;
}

INIT.h

#ifndef _INIT_H_
#define _INIT_H_#define u8 unsigned char
#define u16 unsigned int #include<STC15F2K60S2.h>
#include"intrins.h"void all_init();
void display();
u8 read_key();
void Timer0Init(void);
void Timer1Init(void);#endif

jm.c

这个模块是每个按键所控制的功能。

#include"jm.h"
#include"onewire.h"#define u8 unsigned char
#define u16 unsigned intextern u8 seg[],countdown,moude,temp_flag; // extern表示此变量是在别处定义的,要在此处引用u16 temp;void jm4()  //s4所控制的功能
{seg[0]=10;seg[1]=moude;seg[2]=10;seg[3]=11;
}void jm5()  //s5所控制的功能
{seg[4]=countdown/1000;seg[5]=countdown/100%10;seg[6]=countdown/10%10;seg[7]=countdown%10;
}void jm6()   //s6所控制的功能
{seg[4]=countdown/1000;seg[5]=countdown/100%10;seg[6]=countdown/10%10;seg[7]=countdown%10;
}void jm7()   //s7所控制的功能
{if(temp_flag==1){temp_flag=0;temp=get_temp();}seg[0]=10;seg[1]=4;seg[2]=10;seg[3]=11;seg[4]=11;seg[5]=temp/1000;seg[6]=temp/100%10;seg[7]=12;
}

jm.h

#ifndef _JM_H_
#define _JM_H_#define u8 unsigned char
#define u16 unsigned int #include<STC15F2K60S2.h>
#include"intrins.h"void jm4();
void jm5();
void jm6();
void jm7();#endif

main.c

#include"INIT.h"
#include"jm.h"
#include"onewire.h"#define u8 unsigned char
#define u16 unsigned intstatic u16 moude_count=0,pwm;
u8 num=0,moude=1,countdown=0,temp_m=0,countdown_moude=1;
u8 temp_flag=0;
u8 jma,jmb;
u16 countdown_count=0,temp_count=0;extern seg[];void main()
{all_init();Timer0Init();Timer1Init();while(1){if(countdown>0) ET0 = 1; //倒计时大于0打开定时器0              else ET0 = 0;      num=read_key();switch(num){case 4:if(++moude==4) moude=1;  //三种工作模式if(moude==1) pwm=2;if(moude==2) pwm=3;if(moude==3) pwm=7;jma=0,jmb=0;break;case 5:if(++countdown_moude==4) countdown_moude=1;   //设定倒计时if(countdown_moude==1) countdown=0;if(countdown_moude==2) countdown=60;if(countdown_moude==3) countdown=120;jma=0,jmb=1;break;case 6:    //停止,清零countdown=0;jma=1,jmb=0;break;case 7:   //工作或室温界面temp_m^=1;if(temp_m==1){jma=1,jmb=1;}else{jma=0,jmb=0;}break;}num=0;if(jma==0&&jmb==0) {jm4();jm5();}if(jma==0&&jmb==1) jm5();    if(jma==1&&jmb==0) jm6();if(jma==1&&jmb==1) jm7();}
}void Timer1() interrupt 3
{display();countdown_count++;temp_count++;if(countdown_count==1000)    //每一秒倒计时减一{if(countdown>0) countdown--; countdown_count=0;}if(temp_count==200)   //每200ms获取一次室温{temp_flag=1;temp_count=0;}
}void Timer0() interrupt 1
{if(moude_count<pwm)      pwm的占空比越大,led灯越亮。{if(moude==1&&countdown!=0){P2=(P2&0x1f)|0x80;P0=0xfe;P2&=0x1f;}if(moude==2&&countdown!=0){P2=(P2&0x1f)|0x80;P0=0xfd;P2&=0x1f;}if(moude==3&&countdown!=0){P2=(P2&0x1f)|0x80;P0=0xfb;P2&=0x1f;}}else{P2=(P2&0x1f)|0x80;P0=0xff;P2&=0x1f;   }if(++moude_count>=10) moude_count=0;
}

最后,这是本人第一次写博客,写的不好的地方,还希望大家指正。我也会往后写,打算写完一题,就和大家讨论一下。

第七届蓝桥杯单片机省赛题目解析相关推荐

  1. 第十届蓝桥杯单片机省赛题目解析

    话不多说,我们一起来看看第十届(2019)的题目吧. 题目 这次的题目还是三大模块(数码管.LED.按键),还用到了ADC.DAC.NE555,除了NE555之前没有见过,其他也都是一些常见的外设,只 ...

  2. 第九届蓝桥杯单片机省赛题目解析

    别的话也不多说,一起来看看第九届(2018)的题目吧. 题目 这次的题目依然还是用到了三大模块(数码管.LED.按键),还用到了EEPROM和模拟输入(ADC),也都是一些常见的外设,只要平常都练习过 ...

  3. 第十一届蓝桥杯单片机省赛题目解析

    最近也是刚把第十一届的题目写完,我们一起来看看2020年的省赛题目吧. 题目 这次题目照样还是LED.数码管.按键三大模块 ,还有模拟电压输入(ADC).AT24C02(EEPROM),都是常见的外设 ...

  4. 第八届蓝桥杯单片机省赛题目解析

    今天终于有空可以写第八届省赛的题目解析了,第八届(2017)总体也不算难,我们一起来看看吧. 题目 这次题目还是一样用到了三大模块(按键.LED.数码管),还用了实时时钟(DS1302)和DS18B2 ...

  5. 【第十三届蓝桥杯单片机省赛模拟冲刺01】

    第十三届蓝桥杯单片机省赛模拟冲刺 赛前一两周一定要多练习,把之前写过的程序在好好看看,把每个模块的代码都多敲几遍,把常考的每个模块部分都吃透,如果理解不了的趁时间还比较充足该背的背牢.同时在准备编程题 ...

  6. 【蓝桥杯】第十三届蓝桥杯单片机国赛 代码程序

    第十三届蓝桥杯单片机国赛 程序 题目 hex文件 代码 工程文件 B站视频 更多资料 题目 历届的省赛和国赛的题目我已经在前面的文章(点击查看)里给大家分享了(网盘资源),需要的话,直接去下载,我在这 ...

  7. 第十三届“蓝桥杯”单片机省赛——程序设计题

    第十三届"蓝桥杯"单片机省赛--程序设计题 在比赛时候编写,代码仅供参考 如有不足,多多指教 1.题目 2.代码 main.c程序 #include "reg52.h&q ...

  8. 【蓝桥杯】第九届蓝桥杯单片机国赛 代码程序

    第九届蓝桥杯单片机国赛 程序 题目 hex文件 代码 工程文件 B站视频 更多资料 题目 历届的省赛和国赛的题目我已经在前面的文章(点击查看)里给大家分享了(网盘资源),需要的话,直接去下载,我在这里 ...

  9. 第jiu届蓝桥杯单片机省赛真题_第九届蓝桥杯单片机组省赛试题.pdf

    第九届蓝桥杯单片机组省赛试题 "彩灯控制器"的程序设计与调试 (70 分) 一.基本要求 1.1 使用CT107D 单片机竞赛板,完成"彩灯控制器"功能的程序设 ...

最新文章

  1. Andrej Karpathy发文谈神经网络:这不仅仅是分类器,这是一种新的软件开发思想
  2. Android之EventBus框架源码解析下(源码解析)
  3. 大学生应该学习python和linux而不是matlab和windows
  4. 软件设计中的具体问题
  5. 【Spring-AOP-1】AOP相关概念
  6. 通过ID查询一个用户的两种开发方法
  7. 输入圆的半径,计算并输出圆的周长和面积
  8. 计算机安全加固自动检查,Windows主机安全加固检查列表.doc
  9. 改写教科书!Science揭示:为什么你体内的癌细胞没发展成癌症?
  10. Android 成用户隐私安全问题严重
  11. 创建.NET Core程序的Nuget Package
  12. nps内网穿透_内网穿透工具:NPS的使用
  13. ubuntu下锐捷客户端提示多个ip地址
  14. 行列转换的SQL语句
  15. 网络直播延迟该如何解决这个问题
  16. 雅虎新频道Buzz截图,Digg竞争者?
  17. AES16位密钥加密解密
  18. ZZULIOJ 1000~1009(oj入门题)
  19. lighttpd隐藏index.php,lighttpd开启rewrite伪静态方法 - 老牛博客
  20. android 获取年月日

热门文章

  1. 用SSN生成器注册好square账户后,如何获得square刷卡器?
  2. 用什么软件学计算机一级考试,计算机一级考试软件 v15.1 官方版
  3. 健身App应该具备的功能模块
  4. python问题锦集
  5. c语言写类似饥荒的游戏,饥荒MOD lua编程0基础入门
  6. java class和this_类和对象系列教材 (五)- Java 中的this 是什么意思?
  7. MATLAB-CATIA导入多段直线段
  8. 高等数学强化 1.函数、极限、连续、间断点
  9. 黑客攻陷拉斯维加斯,赌城燃起雄心焰火
  10. 腾讯:暑假只能周五六日打游戏,最多玩21小时