蓝桥杯单片机 自动售水机
题目要求
main.c
#include <stc15f2k60s2.h>
#include <absacc.h>
#include <delay.h>
#include <iic.h>
sbit S6=P3^1;
sbit S7=P3^0;
unsigned char code SMG_NoDot[11] = {0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0xff};
unsigned char code SMG_IsDot[11] = {0x40,0x79,0x24,0x30,0x19,0x12,0x02,0x78,0x00,0x10,0xff};
unsigned char code SMG_position[9]={0x00,0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80};
unsigned char flag=0; //flag为1,出水状态,begin=0,停水状态
unsigned char count=0;//定义50ms定时中断累计变量
int water_amount=0;//定义水量
int water_money=0;//定义价钱
unsigned char yi,er,san,si,wu,liu,qi,ba;
/****************系统初始化函数*******************/
void InitSystem()
{
XBYTE[0X8000]=0XFF; //关闭LED灯
XBYTE[0XA000]=0X00; //关闭蜂鸣器和继电器
XBYTE[0XC000]=0XFF; //选通数码管8个管子
XBYTE[0XE000]=0XFF; //关闭数码管
}
/*****************定时器T0初始化函数**************/
void InitTimer0()
{
TMOD=0X01; //T0工作方式1,50ms定时
TH0=(65535-50000)/256; //设置初值
TL0=(65536-50000)%256; //设置初值
ET0=1; //使能定时器T0
EA=1; //开启总中断
}
/****************定时器T0中断服务函数*************/
void ServiceTimer0(void)interrupt 1
{
TH0=(65535-50000)/256; //重新装载初值
TL0=(65535-50000)%256;
count++;
if(count==20)
{
count=0;
water_amount++; //扩大十倍,便于显示,1s出水1L
if(water_amount>999) //水量超过99.99L,停止出水,
{
XBYTE[0XA000]=0X00; //关闭继电器
flag=0; //切换为停止出水状态
}
}
}
/****************AD转换模块函数*******************/
void ADC()
{
if(val<1.25)
{
XBYTE[0X8000]=0XFE;
}
else XBYTE[0X8000]=0XFf;
}
/****************数码管选通函数*******************/
void SMG_Select(unsigned char pos,unsigned char dat)
{
XBYTE[0XC000]=SMG_position[pos];
XBYTE[0XE000]=dat;
}
void SMG_control()
{
yi=SMG_NoDot[10];er=SMG_IsDot[0];san=SMG_NoDot[5];si=SMG_NoDot[0];
if(flag==1)
{
wu=SMG_NoDot[water_amount/100];liu=SMG_IsDot[water_amount/10%10];
qi=SMG_NoDot[water_amount%10]; ba=SMG_NoDot[0];
}
else if(flag==0)
{
water_money=water_amount*5;//扩大100倍,便于显示数据
wu=SMG_NoDot[water_money/1000];liu=SMG_IsDot[water_money%1000/100];
qi=SMG_NoDot[water_money%100/10];ba=SMG_NoDot[water_money%10];
}
}
/**************数码管显示函数 **************/
void SMG_display()
{
SMG_control();
SMG_Select(1,yi) ;Delay2ms();
SMG_Select(2,er) ;Delay2ms();
SMG_Select(3,san);Delay2ms();
SMG_Select(4,si) ;Delay2ms();
SMG_Select(5,wu) ;Delay2ms();
SMG_Select(6,liu);Delay2ms();
SMG_Select(7,qi) ;Delay2ms();
SMG_Select(8,ba) ;Delay2ms();
}
/******************按键扫描函数*******************/
void key_scan()
{
if(S7==0)//出水
{
Delay10ms();
if(S7==0)
{
if(flag==0)
{
flag=1;//出水状态
XBYTE[0XA000]=0X10;//继电器打开
water_amount=0;
TR0=1;
}
}
while(S7==0)SMG_display();//松手检测
}
if(S6==0)//停水
{
Delay10ms();
if(S6==0)
{
if(flag==1)
{
flag=0;//停水
XBYTE[0XA000]=0X00;//继电器断开
TR0=0;
}
}
while(S6==0)SMG_display();//松手检测
}
}
void main()
{
InitSystem();
InitTimer0();
while(1)
{
SMG_display();
key_scan();
iic_read(0x01);
ADC();
}
}
delay.c
#include <stc15f2k60s2.h>
#include <intrins.h>
void Delay2ms() //@11.0592MHz
{
unsigned char i, j;
_nop_();
_nop_();
i = 22;
j = 128;
do
{
while (--j);
} while (--i);
}
void Delay10ms() //@11.0592MHz
{
unsigned char i, j;
i = 108;
j = 145;
do
{
while (--j);
} while (--i);
}
delay.h
#ifndef _delay_h
#define _delay_h
#include <stc15f2k60s2.h>
void Delay2ms();
void Delay10ms();
#endif
icc.c
#include "stc15f2k60s2.h"
#include "intrins.h"
#define somenop {_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();}
#define SlaveAddrW 0xA0
#define SlaveAddrR 0xA1
//总线引脚定义
sbit SDA = P2^1; /* 数据线 */
sbit SCL = P2^0; /* 时钟线 */
unsigned char dat_rd1;//rd1数据采集值
unsigned char val;//电压
//总线启动条件
void IIC_Start(void)
{
SDA = 1;
SCL = 1;
somenop;
SDA = 0;
somenop;
SCL = 0;
}
//总线停止条件
void IIC_Stop(void)
{
SDA = 0;
SCL = 1;
somenop;
SDA = 1;
}
//应答位控制
void IIC_Ack(bit ackbit)
{
if(ackbit)
{
SDA = 0;
}
else
{
SDA = 1;
}
somenop;
SCL = 1;
somenop;
SCL = 0;
SDA = 1;
somenop;
}
//等待应答
bit IIC_WaitAck(void)
{
SDA = 1;
somenop;
SCL = 1;
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 iic_read(unsigned char channel)
{
IIC_Start(); //IIC总线起始信号
IIC_SendByte(0x90); //PCF8591的写设备地址
IIC_WaitAck(); //等待从机应答
IIC_SendByte(channel); //写入PCF8591的控制字节
IIC_WaitAck(); //等待从机应答
IIC_Stop(); //IIC总线停止信号
IIC_Start(); //IIC总线起始信号
IIC_SendByte(0x91); //PCF8591的读设备地址
IIC_WaitAck(); //等待从机应答
dat_rd1=IIC_RecByte(); //读取PCF8591通道的数据
IIC_Ack(0); //产生非应答信号
IIC_Stop(); //IIC总线停止信号
val=dat_rd1*0.0196; // 5/255=0.0196
return val; //返回读取的数据
}
icc.h
#ifndef _IIC_H
#define _IIC_H
//函数声明
void IIC_Start(void);
void IIC_Stop(void);
void IIC_Ack(bit ackbit);
void IIC_SendByte(unsigned char byt);
bit IIC_WaitAck(void);
unsigned char IIC_RecByte(void);
unsigned char iic_read(unsigned char channel);
extern unsigned char dat_rd1;
extern unsigned char val;
#endif
有问题的朋友可以戳我哟
自动售水机源码工程文件