蓝桥杯资料包
源码
强烈建议先自己做一遍,这是蓝桥杯单片机最简单的一道题。
首先从试题的系统框图开始看

如图所示,有AD转换,所以IIC肯定是需要用的
有数码管,所以数码管先写上
有按键,但确定是独立按键还是矩阵按键,往下翻

S5,S7所以使用独立按键就行
所以,我们先建立工程,然后把需要的数码管,IIC,独立按键先添加进去并且调试好。
main.c

#include <stc15f2k60s2.h>
#include "intrins.h"
#include "iic.h"#define uchar unsigned char
#define uint unsigned intvoid SMG_output(void);
void init(void);
void Delay1ms(void);
void delay5ms(void);
void Dkey_scan(void);uchar tab[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,\
0x40,0x79,0x24,0x30,0x19,0x12,0x02,0x78,0x00,0x10,0xff,0xbf};
uchar SMG[8]={20,20,20,20,20,20,20,20};//初始显示10,全息数码管void main(void)
{init();while(1){SMG_output();Dkey_scan();}
}void Dkey_scan(void) //矩阵按键
{static uchar keybyte=0;static uchar key;if(((P3&0X0F)!=0X0F)&&(keybyte==0)){delay5ms();if((P3&0X0F)!=0X0F){keybyte=1;key=P3&0x0f;}}if((keybyte==1)&&((P3&0X0F)==0X0F)){if((P3&0X0F)==0X0F){switch(key){case 0x0e:SMG[0]=1;break;case 0x0d:SMG[1]=1;break;case 0x0b:SMG[2]=1;break;case 0x07:SMG[3]=1;break;}keybyte=0;}}
}void SMG_output(void) //数码管显示函数
{uchar i;for(i=0;i<8;i++){P2=(P2&0X1F)|0Xc0;P0=(1<<i);P2=(P2&0X1F)|0Xe0;P0=tab[SMG[i]];Delay1ms();}P2=(P2&0X1F)|0Xc0;P0=0Xff;P2=(P2&0X1F)|0Xe0;P0=0Xff;
}void init(void) //初始化函数,关闭所有外设
{P2=(P2&0X1F)|0XA0;P0=0X00;P2=(P2&0X1F)|0X80;P0=0Xff;P2=(P2&0X1F)|0Xc0;P0=0Xff;P2=(P2&0X1F)|0Xe0;P0=0Xff;
}void Delay1ms(void)        //@11.0592MHz
{unsigned char i, j;_nop_();_nop_();_nop_();i = 11;j = 190;do{while (--j);} while (--i);
}void delay5ms(void)        //@11.0592MHz
{unsigned char i, j;i = 54;j = 199;do{while (--j);} while (--i);
}

iic.c

#include "iic.h"#define DELAY_TIME 40
//IIC的读函数,参数(硬件地址,寄存器地址,数据)
void IIC_write(uchar hw_address,uchar reg_address,uchar num)
{ IIC_Start();IIC_SendByte(hw_address&0xfe);IIC_WaitAck();IIC_SendByte(reg_address);IIC_WaitAck();IIC_SendByte(num);IIC_WaitAck();  IIC_Stop();
}
//IIC读函数 参数:硬件地址,寄存器地址
uchar IIC_read(uchar hw_address,uchar reg_address)
{uchar num;IIC_Start();IIC_SendByte(hw_address&0xfe);IIC_WaitAck();IIC_SendByte(reg_address);   IIC_WaitAck();IIC_Stop();IIC_Start();IIC_SendByte(hw_address|0x01);IIC_WaitAck();num=IIC_RecByte();IIC_WaitAck();IIC_Stop();   return num;
}//
void IIC_Delay(unsigned char i)
{do{_nop_();}while(i--);
}//
void IIC_Start(void)
{SDA = 1;SCL = 1;IIC_Delay(DELAY_TIME);SDA = 0;IIC_Delay(DELAY_TIME);SCL = 0;
}//
void IIC_Stop(void)
{SDA = 0;SCL = 1;IIC_Delay(DELAY_TIME);SDA = 1;IIC_Delay(DELAY_TIME);
}//
void IIC_SendAck(bit ackbit)
{SCL = 0;SDA = ackbit;                    IIC_Delay(DELAY_TIME);SCL = 1;IIC_Delay(DELAY_TIME);SCL = 0; SDA = 1;IIC_Delay(DELAY_TIME);
}//
bit IIC_WaitAck(void)
{bit ackbit;SCL  = 1;IIC_Delay(DELAY_TIME);ackbit = SDA;SCL = 0;IIC_Delay(DELAY_TIME);return ackbit;
}//
void IIC_SendByte(unsigned char byt)
{unsigned char i;for(i=0; i<8; i++){SCL  = 0;IIC_Delay(DELAY_TIME);if(byt & 0x80) SDA  = 1;else SDA  = 0;IIC_Delay(DELAY_TIME);SCL = 1;byt <<= 1;IIC_Delay(DELAY_TIME);}SCL  = 0;
}//
unsigned char IIC_RecByte(void)
{unsigned char i, da;for(i=0; i<8; i++){   SCL = 1;IIC_Delay(DELAY_TIME);da <<= 1;if(SDA) da |= 1;SCL = 0;IIC_Delay(DELAY_TIME);}return da;
}

iic.h

#ifndef _IIC_H
#define _IIC_H#include "stc15f2k60s2.h"
#include "intrins.h"#define uchar unsigned char
#define uint unsigned intsbit SDA = P2^1;
sbit SCL = P2^0;void IIC_Start(void);
void IIC_Stop(void);
bit IIC_WaitAck(void);
void IIC_SendAck(bit ackbit);
void IIC_SendByte(unsigned char byt);
unsigned char IIC_RecByte(void); uchar IIC_read(uchar hw_address,uchar reg_address);
void IIC_write(uchar hw_address,uchar reg_address,uchar num);#endif

然后编译,会发现有几个警告,*** WARNING L16: UNCALLED SEGMENT, IGNORED FOR OVERLAY PROCESS,像这中警告一般是有函数没有调用,不用理会,直接下载调试。效果应该是按下按键,数码管对应亮一。
然后接着往下看题目。

数码管显示有两种状态,所以肯定是要定义一,个变量用于切换状态的。定义好后,首先按照如图数码管一模一样显示出来,定义一个价格变量price=50,50方便显示;定义一个总价all_price=50,然后显示出来。改变之后的代码如下:

uchar SMG_mode=0; //数码管切换状态变量
uchar price=50; //价格变量
uint all_price=50,water_num=100; //总价变量 //出水量定义
void main(void)
{init();while(1){if(SMG_mode==0) //数码管模式一 售水机出水状态数码管显示{//加上10都是为了显示小数点SMG[0]=20;SMG[1]=price/100+10;SMG[2]=price%100/10;SMG[3]=price%10;SMG[4]=water_num/1000;SMG[5]=water_num%1000/100+10;SMG[6]=water_num%100/10;SMG[7]=water_num%10;}else if(SMG_mode==1) //数码管模式二 售水机出停水态数码管显示{//加上10都是为了显示小数点SMG[0]=20;SMG[1]=price/100+10;SMG[2]=price%100/10;SMG[3]=price%10;SMG[4]=all_price/1000;SMG[5]=all_price%1000/100+10;SMG[6]=all_price%100/10;SMG[7]=all_price%10;}SMG_output();Dkey_scan();}
}

如题

然后数码管需要由按键控制,所以在按键中在增加相应控制程序(S7显示数码管模式一,并且继电器接通,L10亮,S6显示数码管模式二,并且继电器断开,L10熄灭),由于只需要S7和S6,所以把独立按键另外两个按键删除。
对应独立按键修改的程序为:

void Dkey_scan(void)
{static uchar keybyte=0;static uchar key;if(((P3&0X0F)!=0X0F)&&(keybyte==0)){delay5ms();if((P3&0X0F)!=0X0F){keybyte=1;key=P3&0x0f;}}if((keybyte==1)&&((P3&0X0F)==0X0F)){if((P3&0X0F)==0X0F){switch(key){case 0x0e:if(SMG_mode==1)SMG_mode=0; //切换数码管模式P2=0XA0;P0=0X10;  //点亮L10,接通继电器break;case 0x0d:if(SMG_mode==0)SMG_mode=1;P2=0XA0;P0=0X00;  //熄灭L10,关闭继电器break;}keybyte=0;}}
}

记得下载调试!!!
然后接着看试题

由于要使用AD转换,所以要使用IIC了,首先看要求是PCF8591读取光敏电阻的电压,所以IIC读的硬件地址0x90,然后光敏电阻地址为0x01,然后输入电压小于1.25V,L1点亮,否则L1熄灭,所以首先要将读取的值转换为电压值,即255转换为5V,然后再进行判断就行。
所以主函数变为:

uchar light=0;
void main(void)
{init();while(1){light=IIC_read(0x90,0x01); //读取光敏电阻阻值light=light*1.9607; //500/255 放大100倍if(light<125) //判断条件{P2=0X80;P0=0XFE; //打开L1;}else if(light>125){P2=0X80;P0=0XFF; //关闭L1;}

然后下载调试,发现遮住光敏电阻L1点亮。
然后再看最后一个要求:

计算价格,并且给出出水量限额,100毫升/秒就是0.1升/秒,所以首先要使用定时器来计时出水。
更改代码如下:
定时器出水

void time0() interrupt 1
{t++;if(t==1000) //1ms计时1000次==1s{t=0;if(SMG_mode==0) //数码管模式0才加水 即出水模式才加水water_num+=10; //每一秒出水}
}

按键计算价格和清零

             case 0x0e:if(SMG_mode==1){SMG_mode=0;water_num=0;}//切换数码管模式,出水量清零P2=0XA0;P0=0X10;  //点亮L10,接通继电器break;case 0x0d:if(SMG_mode==0)SMG_mode=1;P2=0XA0;P0=0X00;  //熄灭L10,关闭继电器all_price=((water_num*price)/100); //计算价格break;

出水限制

     if(water_num>9999){SMG_mode=1;P2=0XA0;P0=0X00;  //熄灭L10,关闭继电器all_price=((water_num*price)/100); //计算价格}

最后别忘记更改初始出水量和价格,删除没用的函数。
完整代码

#include <stc15f2k60s2.h>
#include "intrins.h"
#include "iic.h"#define uchar unsigned char
#define uint unsigned intvoid SMG_output(void);
void init(void);
void Delay1ms(void);
void delay5ms(void);
void Dkey_scan(void);
void Timer0Init(void);
uchar tab[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,\
0x40,0x79,0x24,0x30,0x19,0x12,0x02,0x78,0x00,0x10,0xff,0xbf};
uchar SMG[8]={20,20,20,20,20,20,20,20};//初始显示10,全息数码管uchar SMG_mode=0; //数码管切换状态变量
uchar price=50; //价格变量
uint all_price=0,water_num=0; //总价变量 //出水量定义
uint light=0;
uint t=0;  //定时器变量
void main(void)
{init(); //初始开发板Timer0Init(); //初始化定时器while(1){light=IIC_read(0x90,0x01); //读取光敏电阻阻值light=light*1.9607; //500/255 放大100倍if(light<125) //判断条件{P2=0X80;P0=0XFE; //打开L1;}else if(light>125){P2=0X80;P0=0XFF; //关闭L1;}if(SMG_mode==0) //数码管模式一 售水机出水状态数码管显示{//加上10都是为了显示小数点SMG[0]=20;SMG[1]=price/100+10;SMG[2]=price%100/10;SMG[3]=price%10;SMG[4]=water_num/1000;SMG[5]=water_num%1000/100+10;SMG[6]=water_num%100/10;SMG[7]=water_num%10;}else if(SMG_mode==1) //数码管模式二 售水机出停水态数码管显示{//加上10都是为了显示小数点SMG[0]=20;SMG[1]=price/100+10;SMG[2]=price%100/10;SMG[3]=price%10;SMG[4]=all_price/1000;SMG[5]=all_price%1000/100+10;SMG[6]=all_price%100/10;SMG[7]=all_price%10;}if(water_num>9999){SMG_mode=1;P2=0XA0;P0=0X00;  //熄灭L10,关闭继电器all_price=((water_num*price)/100); //计算价格}SMG_output();Dkey_scan();}
}void Dkey_scan(void)
{static uchar keybyte=0;static uchar key;if(((P3&0X0F)!=0X0F)&&(keybyte==0)){delay5ms();if((P3&0X0F)!=0X0F){keybyte=1;key=P3&0x0f;}}if((keybyte==1)&&((P3&0X0F)==0X0F)){if((P3&0X0F)==0X0F){switch(key){case 0x0e:if(SMG_mode==1){SMG_mode=0;water_num=0;}//切换数码管模式,出水量清零P2=0XA0;P0=0X10;  //点亮L10,接通继电器break;case 0x0d:if(SMG_mode==0)SMG_mode=1;P2=0XA0;P0=0X00;  //熄灭L10,关闭继电器all_price=((water_num*price)/100); //计算价格break;}keybyte=0;}}
}void time0() interrupt 1
{t++;if(t==1000) //1ms计时1000次==1s{t=0;if(SMG_mode==0) //数码管模式0才加水 即出水模式才加水water_num+=10; //每一秒出水}
}void Timer0Init(void)      //1毫秒@11.0592MHz
{AUXR |= 0x80;     //定时器时钟1T模式TMOD &= 0xF0;       //设置定时器模式TL0 = 0xCD;       //设置定时初值TH0 = 0xD4;        //设置定时初值TF0 = 0;       //清除TF0标志TR0 = 1;      //定时器0开始计时EA=1;ET0=1; //打开中断
}void SMG_output(void)
{uchar i;for(i=0;i<8;i++){P2=(P2&0X1F)|0Xc0;P0=(1<<i);P2=(P2&0X1F)|0Xe0;P0=tab[SMG[i]];Delay1ms();}P2=(P2&0X1F)|0Xc0;P0=0Xff;P2=(P2&0X1F)|0Xe0;P0=0Xff;
}void init(void)
{P2=(P2&0X1F)|0XA0;P0=0X00;P2=(P2&0X1F)|0X80;P0=0Xff;P2=(P2&0X1F)|0Xc0;P0=0Xff;P2=(P2&0X1F)|0Xe0;P0=0Xff;
}void Delay1ms(void)        //@11.0592MHz
{unsigned char i, j;_nop_();_nop_();_nop_();i = 11;j = 190;do{while (--j);} while (--i);
}void delay5ms(void)        //@11.0592MHz
{unsigned char i, j;i = 54;j = 199;do{while (--j);} while (--i);
}

最后演示视频

最后可以有问题可以私信和评论。

蓝桥杯单片机第三届省赛题详细讲解(自动售水机)相关推荐

  1. 蓝桥杯单片机第四届省赛题详细讲解(模拟智能灌溉系统)

    看之前强烈建议先自己做一遍!!! 整个工程文件(有注释讲解) 网盘链接 先上演示效果 蓝桥杯单片机第五届模拟智能灌溉系统 首先依旧从赛题的系统框图开始讲起 首先需要做的是将系统框图里的各部分模块提前调 ...

  2. 蓝桥杯单片机第三届省赛自动售水机

    #蓝桥杯单片机省三自动售水机 提示:能力有限仅供参考 本人能力有限仅供新手使用,第一次发表博客难免有错误仅供参考. 提示:以下是本篇文章正文内容,下面案例可供参考 一.main.c 代码如下: #in ...

  3. 十三届蓝桥杯单片机组省赛真题程序解析

    第一次参加蓝桥杯,线上比赛,记录一下 比赛刚开始了十分钟才做上客观题,做上了之后才发现看一次题警告一次,当时就蚌埠住了,随便做了做就交了,手册也没怎么查(查一下直接给了3次黄牌,就没敢查了)其实老师1 ...

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

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

  5. 蓝桥杯单片机历年初赛真题练习

    蓝桥杯单片机历年初赛真题练习第三届-自动售水机 文章目录 蓝桥杯单片机历年初赛真题练习第三届---自动售水机 前言 一.题目要求 二.具体代码 1.驱动部分 2.主程序部分 总结 前言 我参加了第十二 ...

  6. 2013第四届蓝桥杯Java组省赛题解析

    2013第四届蓝桥杯Java组省赛题解析 目录 第一题:高斯日记 第二题:马虎的算式 第三题:第39级台阶 第四题:黄金连分数 ​第五题:前缀判断 第六题:三部排序 ​第七题:错误票据 第八题:翻硬币 ...

  7. 【第十四届蓝桥杯单片机组模拟赛1】

    第十四届蓝桥杯单片机组模拟赛1 距第十四届蓝桥杯单片机还有不到一个月的时间啦,加油 源码 /*------------------------------第十四届蓝桥杯单片机模式赛---------- ...

  8. 蓝桥杯单片机第三届初赛程序设计——“自动售水机”设计任务书

    程序设计流程 综述 模板搭建 根据此题要求对模板做出的改变 程序设计 IIC A/D光敏电阻板块程序设计 系统设计 主函数代码 综述 第三届初赛赛题除了基础的独立按键.数码管显示.继电器和蜂鸣器的控制 ...

  9. 蓝桥杯单片机第七届省赛题详细讲解(模拟风扇控制系统)

    看之前强烈建议先自己做一遍!!! 演示视频 题目讲解 完整程序 main.c onewire.h onewire.c 工程文件 演示视频 题目讲解 首先还是从整个赛题的程序框图开始看起,如图. 做题之 ...

最新文章

  1. WIN7如何替换开机登录画面
  2. 《Neural networks and deep learning》概览
  3. linux用户和组帐户管理
  4. 分酒问题matlab代码,matlab葡萄酒分类数据归一化问题
  5. Maven 使用 Tomcat7
  6. 200815-C指针高级和链表
  7. LLVM完整参考安装
  8. ROS笔记(31) ArbotiX关节控制器
  9. 统一异常处理ControllerAdvice
  10. python模块time_python模块之time和datetime
  11. 报表服务框架:WEB前端UI
  12. Office 2007中的config.xml个性定制说明
  13. rabbitmq启动报错,TCP connection succeeded but Erlang distribution failed
  14. pythonrender函数_Render函数
  15. ubuntu 安装eclipes
  16. HtmlUnit的简单例子
  17. 远距离蓝牙路由器产品:桂花网Cassia S2000介绍
  18. 基于微信平台的学生信息管理系统
  19. 小米机型TWRP_recovery合集分享-支持米9等新机
  20. AOC AG273QXP 评测

热门文章

  1. 如何给博客园添加访问统计
  2. 北、上、深交易所分别发布北交所上市公司转板办法,北交所上市公司87家
  3. SSM毕设项目羽毛球场预约系统axx7m(java+VUE+Mybatis+Maven+Mysql)
  4. gvim c语言,gvim+tdm-gcc设置c语言编译环境
  5. 西安全国计算机等级考试,全国计算机等级考试 西安电子.pdf
  6. oracle ebs ar 表,Oracle EBS R12 常用表表结构总结之AR应收模块
  7. Python图像处理库PIL中的convert函数的用法
  8. PythonOCC基础使用:建模——基础三维实体(球体,长方体,棱柱/台/锥,圆柱/锥/台,环形)
  9. LTE MAC2 SR-BSR
  10. 哪个专业就业前景最好?