题目要求:
S16:定义为“加”按键,按下S16,电压参数增加0.5V;增加到5.00后,再次按下S16返回0.00V。
代码:
#include "STC15F2K60S2.H"
#include "iic.h"
#include "xmf_smg_ca.h"
#include "absacc.h"
unsigned int time = 0; //用于计时
float VRb2,comp ; //从8591读出的电压值和比较电压值
unsigned int X,Pare; //X是对VRb2乘100,Pare是对comp乘100,方便传入数码管
unsigned char miao = 0; //计时变量
unsigned char mode = 0; //界面切换,为零是初始界面,为一是参数界面,为二是时间记录界面
unsigned int L1_time = 0; //用来判断L1是否该亮,如果记录电压大于参考电压,那么将点亮L1
unsigned char flaut = 0; //用来记录无效按键的次数
void init0() //定时一毫秒
{
TMOD = 0XF0;
TH0 = 0XD4;
TL0 = 0XCD;
TR0 = 1;
ET0 = 1; //打开中断
EA = 1;
}
void serviceinit0() interrupt 1 //中断服务函数
{
time++;L1_time++;
if(time == 100)
{
time = 0;
miao++; //一秒后miao++
if(miao == 60)
{
miao = 0; //六十秒后计数自动清零
}
}
}
//***********************************************************
unsigned char read_pcf8591() //读出8591中的电阻值,方便后面转换成电压值
{
unsigned char temp;
IIC_Start();
IIC_SendByte(0x90);
IIC_WaitAck();
IIC_SendByte(0x03);
IIC_WaitAck();
IIC_Start();
IIC_SendByte(0x91);
IIC_WaitAck();
temp = IIC_RecByte();
IIC_Ack(0);
IIC_Stop();
return temp;
}
unsigned char read_24c02() //读出存入EE2中的电压值
{
unsigned char temp;
IIC_Start();
IIC_SendByte(0xa0);
IIC_WaitAck();
IIC_SendByte(0x00);
IIC_WaitAck();
IIC_Start();
IIC_SendByte(0xa1);
IIC_WaitAck();
temp = IIC_RecByte();
IIC_Ack(0);
IIC_Stop();
return temp;
}
void write_24c02(unsigned char date) //将电压值写入EE2中
{
IIC_Start();
IIC_SendByte(0xa0);
IIC_WaitAck();
IIC_SendByte(0x00);
IIC_WaitAck();
IIC_SendByte(date);
IIC_WaitAck();
IIC_Stop();
}
//****************************************************************
//************************************************************
void date_V() //显示电压
{
smgbit(SMG_ti_shi[0],0);
smgdelay(100);
smgbit(SMGDot_CA[X/100],5);
smgdelay(100);
smgbit(SMG_duanma[(X%100)/10],6);
smgdelay(100);
smgbit(SMG_duanma[X%10],7);
smgdelay(100);
smgall(0xff);
smgdelay(100);
}
void date_P() //显示参数,比较电压
{
smgbit(SMG_ti_shi[1],0);
smgdelay(100);
smgbit(SMGDot_CA[Pare/100],5);
smgdelay(100);
smgbit(SMG_duanma[(Pare%100)/10],6);
smgdelay(100);
smgbit(SMG_duanma[Pare%10],7);
smgdelay(100);
smgall(0xff);
}
void date_m() //记录时间
{
smgbit(SMG_ti_shi[2],0);
smgdelay(100);
smgbit(SMG_duanma[miao/10],6);
smgdelay(100);
smgbit(SMG_duanma[miao%10],7);
smgdelay(100);
smgall(0xff);
}
void jie_mian_qie_huan() //用于切换数码管界面
{
if(mode == 0)
{
date_V();//显示电压
}
if(mode == 1)
{
date_P();//显示参数,比较电压
}
if(mode == 2)
{
date_m();//记录时间
}
}
//************************************************************8
void keyscan()
{
P35 = 0;
P34 = 1;
if(P33 == 0)//检测S12,并且通过按S12来切换数码管的模式,以便下面三个按键的检测
{
smgdelay(100);
if(P33 == 0)
{
flaut = 0;
if(mode == 0)
{
mode = 1;
}
else if(mode == 1)
{
mode = 2;
}
else if(mode == 2)
{
mode = 0;
}
while(P33 == 0);
}
else
{
flaut++;
}
}
P35 = 0;
P34 = 1;
if(P32 == 0) //检测S13
{
smgdelay(100);
if(P32 == 0)
{
flaut = 0;
if(mode == 2)
{
miao = 0;
while(P32 == 0);
}
}
else
{
flaut++;
}
}
P35 =1;
P34 =0;
if(P33 == 0) //检测S16
{
smgdelay(100);
if(P33 == 0)
{
flaut = 0;
if(mode == 1)
{
comp = comp +0.5;
if(comp>5)
{
comp = 0.0;
}
}
while(P33 == 0)
{
write_24c02((unsigned char) comp*10);
smgdelay(5000);
jie_mian_qie_huan();
}
}
else
{
flaut++;
}
}
P35 =1;
P34 =0;
if(P32 == 0) //检测S17
{
smgdelay(100);
if(P32 == 0)
{
flaut = 0;
if(mode == 1)
{
comp = comp -0.5;
if(comp<0)
{
comp = 5.0;
}
}
while(P32 == 0)
{
jie_mian_qie_huan();
}
}
else
{
flaut++;
}
}
}
void led_contr() //控制灯光
{
if(X>Pare)
{
if(L1_time >=500)
{
XBYTE[0X8000] = 0XFE; //L1灯光控制
smgdelay(100);
L1_time = 5001;
}
}
else
{
L1_time = 0;
XBYTE[0X8000] = 0XFF;
}
if((miao%2) == 1)
{
XBYTE[0X8000] = 0XFD; //L2灯光控制
smgdelay(100);
}
else
{
XBYTE[0X8000] = 0XFF;
}
if(flaut >=3)
{
XBYTE[0X8000] = 0XFB; //L3灯光控制
smgdelay(100);
}
else
{
XBYTE[0X8000] = 0XFF;
}
}
void main()
{
close();
init0();
//*****************************将上次掉电后存的数据取出来
comp = read_24c02()/10.0;
if(!((comp>=0.0) && (comp<=5.0))) //如果数据不在参考电压的范围里面那么让参考电压为零
{
comp = 0.0;
}
//******************************
while(1)
{
VRb2 = read_pcf8591() * 5 /255.0; //将电阻值转换成电压值
X = VRb2*100; //方便显示在数码管上
Pare = comp*100.0;
led_contr();
keyscan();
jie_mian_qie_huan();
}
}
IIC.H
#ifndef _IIC_H
#define _IIC_H
void Delay_IIC(unsigned char time);
void IIC_Start(void);
void IIC_Stop(void);
void IIC_Ack(unsigned char ackbit);
bit IIC_WaitAck(void);
void IIC_SendByte(unsigned char byt);
unsigned char IIC_RecByte(void);
#endif
#include "STC15F2K60S2.H"
#include "intrins.h"
//总线引脚定义
sbit SDA = P2^1; /* 数据线 */
sbit SCL = P2^0; /* 时钟线 */
void Delay_IIC(unsigned char time)
{
do{_nop_();}
while(time--);
}
void IIC_Start(void)
{
SDA = 1;
SCL = 1;
Delay_IIC(5);
SDA = 0; //在SCL高电平期间,SDA由高变低
Delay_IIC(5);
SCL = 0;
}
void IIC_Stop(void)
{
SDA = 0;
SCL = 1;
Delay_IIC(5);
SDA = 1; //在SCL高电平期间,SDA由高变低
Delay_IIC(5);
}
void IIC_Ack(unsigned char ackbit)
{
if(ackbit)
SDA = 0; //产生应答信号
else
SDA = 1; //产生非应答信号
Delay_IIC(5);
SCL = 1;
Delay_IIC(5); //第9个时钟周期
SCL = 0;
SDA = 1; //释放SDA线
Delay_IIC(5);
}
bit IIC_WaitAck(void)
{
SDA = 1;
Delay_IIC(5);
SCL = 1;
Delay_IIC(5);
if(SDA) //在SCL高电平期间,SDA为高电平,从机非应答。
{
SCL = 0;
IIC_Stop();
return 0;
}
else //在SCL高电平期间,SDA为低电平,从机有应答。
{
SCL = 0;
return 1;
}
}
void IIC_SendByte(unsigned char byt)
{
unsigned char i;
for(i=0;i<8;i++) //循环发送8位数据
{
if(byt & 0x80) //数据位是高电平
{
SDA = 1;
}
else //数据位是低电平
{
SDA = 0;
}
Delay_IIC(5);
SCL = 1; //SCL高电平期间,SDA的数据要保持稳定
byt <<= 1; //发送的数据左移,准备发送下一位
Delay_IIC(5); //等待SDA的数据被读取
SCL = 0;
}
}
unsigned char IIC_RecByte(void)
{
unsigned char da;
unsigned char i;
for(i=0;i<8;i++)
{
SCL = 1;
Delay_IIC(5); //在SCL高电平期间,读取SDA的数据
da <<= 1;
if(SDA)
da |= 0x01;
SCL = 0;
Delay_IIC(5);
}
return da;
}
数码管底层代码
#ifndef _XMF_SMG_BA_H
#define _XMF_SMG_BA_H
unsigned char code SMGDot_CA[10] = {0x40,0x79,0x24,0x30,0x19,0x12,0x02,0x78,0x00,0x10};//数字0.到数字9.
unsigned char code SMG_duanma[18]=
{0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,
0x80,0x90,0x88,0x80,0xc6,0xc0,0x86,0x8e,
0xbf,0x7f};
unsigned char code SMG_ti_shi[3]={0xc1,0x8c,0xc8};//提示符U,P,N
void smgdelay(unsigned int n);
void close();
void smgbit(unsigned char dat,unsigned char pot);
void smgall(unsigned char all);
#endif
#include "absacc.h"
void smgdelay(unsigned int n)
{
while(n--);
}
void close() //初始化设备
{
XBYTE[0XA000] = 0X00;
XBYTE[0X8000] = 0Xff;
}
void smgbit(unsigned char dat,unsigned char pot) //数码管段码
{
XBYTE[0XE000] = 0xff;
XBYTE[0XC000] = 0X01<<pot;
XBYTE[0XE000] = dat;
}
void smgall(unsigned char all) //关闭所有数码管
{
XBYTE[0XC000] = 0XFF;
XBYTE[0XE000] = all;
}