#include "reg52.h" //此文件中定义了单片机的一些特殊功能寄存器
#include"temp.h"
#include<math.h>
typedef unsigned int u16; //对数据类型进行声明定义
typedef unsigned char u8;
sbit LSA=P2^2;
sbit LSB=P2^3;
sbit LSC=P2^4;
sbit BZ=P1^5;
sbit WATER=P2^6;//清水
sbit CLEAN=P2^7;//清洁剂
sbit k1=P3^1;
sbit k2=P3^0;
sbit k3=P3^2;
sbit k4=P3^3; //定义按键端口
sbit PWM=P2^1;
u8 code smgduan[10]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};
u8 KeyValue;
#define GPIO_DIG P0
#define GPIO_KEY P1
#define KEY1 1
#define KEY2 2
#define KEY3 3
#define KEY4 4
u16 value,tempq;
char keynum=25,num=0;
u8 DisplayData[8],timer1;
/*******************************************************************************
* 函 数 名 : delay
* 函数功能 : 延时函数,i=1时,大约延时10us
*******************************************************************************/
void delay(u16 i)
{
while(i--);
}
void datapros(int temp) //温度部分
{
float tp;
if(temp< 0) //当温度值为负数
{
DisplayData[0] = 0x40; // -
//因为读取的温度是实际温度的补码,所以减1,再取反求出原码
temp=temp-1;
temp=~temp;
tp=temp;
temp=tp*0.0625*100+0.5;
//留两个小数点就*100,+0.5是四舍五入,因为C语言浮点数转换为整型的时候把小数点
//后面的数自动去掉,不管是否大于0.5,而+0.5之后大于0.5的就是进1了,小于0.5的就
//算加上0.5,还是在小数点后面。
}
else
{
DisplayData[0] = 0x00;
tp=temp;//因为数据处理有小数点所以将温度赋给一个浮点型变量
//如果温度是正的那么,那么正数的原码就是补码它本身
temp=tp*0.0625*100+0.5;
//留两个小数点就*100,+0.5是四舍五入,因为C语言浮点数转换为整型的时候把小数点
//后面的数自动去掉,不管是否大于0.5,而+0.5之后大于0.5的就是进1了,小于0.5的就
//算加上0.5,还是在小数点后面。
}
//DisplayData[7] =smgduan[temp/10000];
DisplayData[5] = smgduan[temp%10000/1000];
DisplayData[4] = smgduan[temp%1000/100]|0x80;
DisplayData[3] = smgduan[temp%100/10];
//DisplayData[2] = smgduan[temp%10];
tempq=temp/100;
}
void KeyDown(void)//
{
char a=0;
GPIO_KEY=0x0f;
if(GPIO_KEY!=0x0f)//读取按键是否按下
{
delay(1000);//延时10ms进行消抖
if(GPIO_KEY!=0x0f)//再次检测键盘是否按下
{
//测试列
GPIO_KEY=0X0F;
switch(GPIO_KEY)
{
case(0X07): KeyValue=1;{WATER=0;CLEAN=0;}break;
case(0X0b): KeyValue=2;{WATER=0;CLEAN=1;}break;/*S1,S2,S3*/
case(0X0d): KeyValue=0;{WATER=1;CLEAN=1;}break;
//case(0X0e): KeyValue=0;break;
}
}
}
}
//mode=0 单次 1:连续
u8 KeyScan(u8 mode)
{
static u8 keyen=1;
if(mode==1)
{
keyen=1;
}
if(keyen==1&&(k1==0||k2==0||k3==0||k4==0))
{
delay(1000); //消抖处理
keyen=0;
if(k1==0)return KEY1;
else if(k2==0)return KEY2;
else if(k3==0)return KEY3;
else if(k4==0)return KEY4;
}
else if(k1==1&&k2==1&&k3==1&&k4==1)
{
keyen=1;
}
return 0;
}
/*******************************************************************************
* 函 数 名 : DigDisplay
* 函数功能 : 数码管动态扫描函数,循环扫描8个数码管显示
*******************************************************************************/
void DigDisplay()
{
u8 i,j;
for(i=0;i<8;i++)
{
switch(i) //位选,选择点亮的数码管,
{
case(0):
LSA=0;LSB=0;LSC=0; break;//显示第0位
case(1):
LSA=1;LSB=0;LSC=0; break;//显示第1位
case(2):
LSA=0;LSB=1;LSC=0; break;//显示第2位
case(3):
LSA=1;LSB=1;LSC=0; break;//显示第3位
case(4):
LSA=0;LSB=0;LSC=1; break;//显示第4位
case(5):
LSA=1;LSB=0;LSC=1; break;//显示第5位
case(6):
LSA=0;LSB=1;LSC=1; break;//显示第6位
case(7):
LSA=1;LSB=1;LSC=1; break;//显示第7位
}
P0=DisplayData[i];//发送段码
delay(80); //间隔一段时间扫描
P0=P0&0x00;//消隐
}
}
void keypros()
{
u8 key=KeyScan(0);
switch(key)
{
case 1: keynum++;if(keynum>=60)keynum=60; break;
case 2: keynum--;if(keynum<=25)keynum=25; break;
case 3: keynum=25; break;
case 4: break;
}
DisplayData[1]=smgduan[keynum/10];
DisplayData[0]=smgduan[keynum%10];
}
void time1Config()
{
TMOD|= 0x10; //设置定时计数器工作方式1为定时器
TH1 = 0xFE;
TL1 = 0x0C;
ET1 = 1; //开启定时器1中断
EA = 1;
TR1 = 1; //开启定时器
}
/*******************************************************************************
* 函 数 名 : main
* 函数功能 : 主函数
* 输 入 : 无
* 输 出 : 无
*******************************************************************************/
void main()
{
float ek,ek1,ek2,uk,uk1;
ek=0;
ek1=0;
ek2=0;
uk=0;
uk1=0;
time1Config();
while(1)
{
ek=keynum-tempq;//测量值-设置值
/*if((-3<=ek)&&(ek<=3))
{
uk=10*ek;
}
else
{
uk=13*ek;
}
value=uk;//控制量转换??
uk1=uk;
ek2=ek1;
ek1=ek;*/
if(tempq>=keynum)//不需要加热
{
PWM=0;
}
else
{
value=10*ek;
if(timer1>1000) //PWM周期为1000*1ms
{
timer1=0;
}
if(timer1<value) //改变30这个值可以改变直流电机的速度
{
PWM=1;
}
else
{
PWM=0;
}
}
datapros(Ds18b20ReadTemp()); //数据处理函数
keypros();
DigDisplay();
KeyDown(); //按键判断函数
GPIO_DIG=smgduan[KeyValue];
}
}
void Time1(void) interrupt 3 //3 为定时器1的中断号 1 定时器0的中断号 0 外部中断1 2 外部中断2 4 串口中断
{
TH1 = 0xFE; //重新赋初值
TL1 = 0x0C;
timer1++;
}