蓝桥杯第3届省赛(单片机)_自动售水机
蓝桥杯第3届省赛(单片机)_自动售水机
题目
这是2012年蓝桥杯的省赛的题目,也是单片机第一次加入蓝桥杯比赛系列,由于是初次加入蓝桥杯,所以这次比赛的自动售水机的题目(自动售水机)也比较简单,主要考察了IIC,独立按键,数码管显示,继电器和AD转化。
题目讲解
刚拿到比赛题目时我们首先要看清楚每次比赛对我们的要求,一般比赛的主要要求都会在设计任务及要求这一部分,所以看懂这一部分尤为重要,在这次的比赛设计比赛要求中,比赛方要求我们实现三大部分
1.按键控制单元
2.数码管显示
3.AD转化
那么我们现在就对这三部分进行讲解吧!
按键控制单元
有题可知,但我们按下S7这按钮时,数码管的DS2部分开始出水(也就是说S7按下时,DS2部分开始数据变化,开始显示出水毫升),当然在系统说明部分也告诉我们最大只可显示9999,并且S7按下时继电器是打开的——L10打开,所以当我们写代码的时候我们些S7按键控制的变量也要与继电器相联系。
同样S6也是,按下S6时,DS2部分显示我们的水价,而且继电器断开——L10熄灭。
数码管显示
数码管显示部分我认为是这道题里最简单的,当按键**S7,S6,**不同时,其数码管显示的也不同,当要记住,DS1部分是不变的,而且数码管在这里的数据变化我认为只要在定时器里加个变量连来改变就行了(可能有点模糊下面的代码我会详细讲解的,其实很简单的)
AD转化
这里主要涉及的是IIC的知识,通过IIC控制PCF89C51来控制光密电阻的电压从而控制led1的亮闪,其实也不难,只要把底层驱动代码修改一下就行了,然后再把相应的函数加到main函数就行。
代码
time.c
#include "time.h"void Timer0Init(void) //1毫秒@12.000MHz
{AUXR &= 0x7F; //定时器时钟12T模式TMOD &= 0xF0; //设置定时器模式TL0 = 0x18; //设置定时初值TH0 = 0xFC; //设置定时初值TF0 = 0; //清除TF0标志TR0 = 1; //定时器0开始计时EA=ET0=1; //打开定时器中断
}
(在这里我喜欢用12Mhz,因为比较精确)
time.h
#ifndef _TIME_H_ //格式——.h
#define _TIME_H_ //格式——.h#include <STC15F2K60S2.H>
void Timer0Init(void); #endif //格式——.h
smg.c
# include "smg.h"unsigned char code tab []={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0xff,
0x40,0x79,0x24,0x30,0x19,0x12,0x02,0x78,0x00,0x10};//这里主要是小数部分
unsigned char dspbuf[8]={10,10,10,10,10,10,10,10};void smg_display(void)
{static unsigned char i; //静态变量P0=0XFF;P2=(P2&0X1F)|0XE0; //关闭段选P2&=0X1F;P0=(1<<i); //自左移i,== (0X01<<i)P2=(P2&0X1F)|0XC0; //打开位选P2&=0X1F;P0=tab[dspbuf[i]]; //打开段选P2=(P2&0X1F)|0XE0;P2&=0X1F;if(++i==8)i=0;}
smg.h
#ifndef _SMG_H_
#define _SMG_H_#include <STC15F2K60S2.H>
#include <absacc.h>#define uchar unsigned char //这里是定义,uchar=unsigned char
#define uint unsigned int //uint = unsigned intvoid smg_display(void);
extern uchar dspbuf[8]; //如果主函数要用到的变量可以用extern来调用#endif
key.c
# include "key.h"unsigned char key_value;
unsigned char flag_realy;void key_mode(void)
{static unsigned char key_times;if(P30!=1||P31!=1){key_times++;if(key_times==1){if(P30==0)key_value=1;flag_realy=1;if(P31==0)key_value=2;flag_realy=2;}else if(key_times>=33){key_times=1;key_value=0;}elsekey_times=0;}
}
key.h
# ifndef _KEY_H
# define _KEY_H# include <STC15F2K60S2.H>void key_mode(void);
extern unsigned char key_value;
extern unsigned char flag_realy;# endif
iic.c
# include "iic.h"
#include "intrins.h"//总线引脚定义
sbit SDA = P2^1; /* 数据线 */
sbit SCL = P2^0; /* 时钟线 */# define somenop{_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();}//总线启动条件
void IIC_Start(void)
{SDA = 1;//确保SDA线为高电平SCL = 1;somenop;SDA = 0;//在SCL为高时拉低SDA线,即为起始信号somenop;SCL = 0;//将SCL线拉低,为后面SDA的电平变化做准备
}//总线停止条件
void IIC_Stop(void)
{SDA = 0; //确保SDA线为低电平SCL = 1; //确保SCL高电平somenop;SDA = 1; //在SCL为高电平时拉高SDA线,即为停止信号,此时SDA和SCL均为高,同时完成IIC初始化过程
}//等待应答
bit IIC_WaitAck(void)
{SCL=1;//确保SDA线为低电平,应答相应时,SDA为高somenop;SDA=1;//确保SCL高电平,应答相应时,SCL为高somenop;if(SDA){SCL=0;IIC_Stop();//停止传输return 0;//应答}else{SCL=0;//继续传输return 1;//非应答}}//通过I2C总线发送数据
void IIC_SendByte(unsigned char byt)
{unsigned char i;for(i=0;i<8;i++){ if(byt&0x80) { SDA = 1;}else {SDA = 0;}somenop;SCL = 1;byt <<= 1;somenop;SCL = 0;}
}//从I2C总线上接收数据
unsigned char IIC_RecByte(void)
{unsigned char da;unsigned char i;for(i=0;i<8;i++){ SCL = 1;somenop;da <<= 1;if(SDA) da |= 0x01;SCL = 0;somenop;}return da;
}unsigned char adc_read(unsigned char add) //这里是在底层驱动那量加上去的,主要是对于PCF8591选取端口,蓝桥杯多次选取的是1,3端口
{unsigned char dat=0; IIC_Start();IIC_SendByte(0X90); //写 IIC_WaitAck(); //应答 IIC_SendByte(add);IIC_WaitAck(); IIC_Stop();IIC_Start();IIC_SendByte(0X91); //读IIC_WaitAck();dat=IIC_RecByte(); IIC_Stop();return dat;
}
iic.h
# ifndef _IIC_H
# define _IIC_H# include <STC15F2K60S2.H>unsigned char adc_read(unsigned char add);# endif
main.c
# include <STC15F2K60S2.H>
# include "time.h"
# include "smg.h"
# include "key.h"
# include "iic.h"unsigned char key_allow;
unsigned char water_sum=0;
unsigned char smg_key;
unsigned char flag_adc;
unsigned char light;
unsigned char water_sum;
unsigned char water_price;
unsigned char water_read;void realy_on(void)
{ P2=(P2&0X1F)|0XA0;P0=0X10; P2&=0X1F;// P0=0x10;
// P2=0xa0; P0=0x10; P2=0;
}void realy_off(void)
{ P2=(P2&0X1F)|0XA0;P0=0X00;P2&=0X1F;// P0=0;
// P2=0xa0; P0=0; P2=0;
}void allinit(void)
{P0=0XFF;P2=(P2&0X1F)|0X80;P2&=0X1F;P0=0X00;P2=(P2&0X1F)|0XA0;P2&=0X1F;}void main (void)
{allinit();Timer0Init();while(1){/******key******/if(key_allow){key_allow=0;key_mode();}switch(key_value){case 1:smg_key=1;flag_realy=1;break;case 2:smg_key=2;flag_realy=2;break;}/******adc******/
// light=adc_read(0X01);
// }
// if(light<64){// P2=0X80;P0=0XFE;P2=(P2&0X1F)|0X80; P0=0XFE;P2&=0X1F;} else {
// P2=0X80;P0=0XFF;P2=(P2&0X1F)|0X80;P0=0xFF; P2&=0X1F;}// /*********realy*********/ if(flag_realy==1)//继电器{realy_on();} else {realy_off();}/***********water************/ if(flag_realy==1) {if(water_read==1){water_read=0;water_sum=water_sum+1;water_price=water_sum/2;}if(water_sum==9999){flag_realy=0;smg_key=2; } }/**************smg***************/if(smg_key==1){dspbuf[0]=10;dspbuf[1]=11;dspbuf[2]=5;dspbuf[3]=0;dspbuf[4]=water_sum/1000;dspbuf[5]=(water_sum%1000/100+11);dspbuf[6]=water_sum%100/10;dspbuf[7]=water_sum%10;}if(smg_key==2){dspbuf[0]=10;dspbuf[1]=11;dspbuf[2]=5;dspbuf[3]=0;dspbuf[4]=water_price/1000;dspbuf[5]=(water_price%1000/100+11);dspbuf[6]=water_price%100/10;dspbuf[7]=water_price%10; water_sum=0;//将之前数据清理,不然再次按下S7时会跟上之前的数值}}}void timer0_isr() interrupt 1
{static unsigned char key_30_times;static unsigned char water_allow;static unsigned char adc_allow;if(++key_30_times==30) //定时器的消抖{key_30_times=0;key_allow=1;}if(++water_allow==100) //售水机时间的间隔{water_allow=0;water_read=1;}smg_display();
}
结语
这是我第一次写博客,可能会有写错的的地方,如有错误请指正,而且我的代码烧进CT107D可能会有一点点小bug,(光敏电阻的不灵敏,蜂鸣器的可能会发出一点点的微声音,但不大),这些bug我会尽快处理,但总体来说基本可以实现题目的要求。
我是hwh,一个刚入单片机的小萌新,希望在CSDN博客能与各位大佬交流,感谢观看。
蓝桥杯第3届省赛(单片机)_自动售水机相关推荐
- 蓝桥杯第十三届国赛PythonB组题解
蓝桥杯第十三届国赛PythonB组题解 [写在前边] 这次的题还是比较难的,只做出来7道,交上去6道,还有一半是暴力做的
- 【蓝桥杯第六届省赛题-简易温度采集与控制装置】
蓝桥杯第六届省赛题-简易温度采集与控制装置 #include "reg52.h" #include "onewire.h" #include "int ...
- Python代码解蓝桥杯第十三届省赛(C/C++大学B组)赛题
Python代码解蓝桥杯第十三届省赛(C/C++大学B组)赛题. [学习的细节是欢悦的历程] Python 官网:https://www.python.org/ Free:大咖免费"圣经&q ...
- 蓝桥杯第十届省赛java组解析(灵能传输 四星难度,后缀表达式 两星难度)
第一题太简单懒得复制题目了 答案是:490 第二题: 试题 B: 不同子串 本题总分:5 分 [问题描述] 一个字符串的非空子串是指字符串中长度至少为 1 的连续的一段字符组成 的串.例如,字符串aa ...
- 基于15单片机模拟自动售水机——蓝桥杯
通过竞赛硬件平台模拟小区自动售水机的工作流程:通过按键控制售水机水流出和停止:通过数码管显示费率.出水量及总费用:通过光敏电阻检测环境亮度,在亮度过低的情况下,自动开灯.系统硬件电路主要由单片机控制电 ...
- 蓝桥杯嵌入式-第九届省赛-电子定时器
/*程序说明: 蓝桥杯大赛嵌入式-第九届省赛-电子定时器软件环境: Keil uVision 4.11 硬件环境: CT117E嵌入式竞赛板(代码兼容ILI932X系列.uc8230液晶控制器)日 期 ...
- 蓝桥杯第七届省赛JAVA真题----剪邮票
剪邮票 如[图1.jpg], 有12张连在一起的12生肖的邮票. 现在你要从中剪下5张来,要求必须是连着的. (仅仅连接一个角不算相连) 比如,[图2.jpg],[图3.jpg]中,粉红色所示部分就是 ...
- 蓝桥杯第七届省赛JAVA真题----压缩变换
压缩变换 小明最近在研究压缩算法. 他知道,压缩的时候如果能够使得数值很小,就能通过熵编码得到较高的压缩比. 然而,要使数值很小是一个挑战. 最近,小明需要压缩一些正整数的序列,这些序列的特点是,后面 ...
- 蓝桥杯第六届国赛JAVA真题----切开字符串
标题:切开字符串 Pear有一个字符串,不过他希望把它切成两段. 这是一个长度为N(<=10^5)的字符串. Pear希望选择一个位置,把字符串不重复不遗漏地切成两段,长度分别是t和N-t(这两 ...
最新文章
- 小米note3无线显示电脑连接服务器,小米note3如何连接电脑 小米note3连接电脑没反应怎么办...
- 为什么要假设变量为正态分布?
- python3 uuid模块
- java51游戏_简单实现美空军也得玩的游戏-谁能坚持超过50秒?(Java)
- java 银行项目对于金额的面试题_2019年面试题小结
- 自带flash的浏览器_解决Flash插件已被屏蔽的问题(谷歌、火狐、IE、Edge)
- mysql数据库 day01
- 设置 git/npm/bower/gem 镜像或代理的方法
- 有关Silverlight TreeView组件的研究[3]——Silverlight学习笔记(8)
- 【转载】推荐系统的十大挑战
- so(3) se(3) optimization
- linux命令大全私房菜,linux命令大全(自己制作,基于鸟书私房菜以及man)-D
- (3)《Head First HTML与CSS》学习笔记---CSS入门
- sklearn——一元线性回归
- 2023USNews美国加州系大学排名
- CC++笔面试知识点
- 【Hello Linux】Linux入门
- 中科院上海王二涛组招聘助理研究员1名-植物微生物组学
- 杨卫华:新浪微博的架构发展历程
- Gitlab-ci:从零开始的前端自动化部署