#include<reg52.h>
#include<intrins.h>
#define uchar unsigned char
#define uint unsigned int
#define jump_ROM 0xcc
#define start 0x44
#define read_EEROM 0xbe
sbit scl=P3^5; //24c02 SCL
sbit sda=P3^6; //24c02 SDA
sbit DQ=P2^3; //DS18B20数据口
sbit E=P2^7; //1602使能引脚
sbit RW=P2^6; //1602读写引脚
sbit RS=P2^5; //1602数据/命令
sbit beep=P3^7; //蜂鸣器报警
sbit s1=P3^2; //功能选择按键
sbit s2=P3^3; //温度加
sbit s3=P3^4; //温度减
sbit w
ARM=P3^0; //升温继电器
sbit cool=P3^1; //降温继电器
uchar TMPH,TMPL,Count1,Count2,T,xie,s1num,s2num,s3num,BusyC;
uint temp,speed;
uchar code table1[] = {"SET
tiNG T:22'C"};
uchar code table2[] = {"SP:L T:---.-'C"};
uchar code distab[] = {0x00,0x01,0x01,0x02,0x03,0x03,0x04,0x04, 0x05,0x06,0x06,0x07,0x08,0x08,0x09,0x09};
uchar data display[]= {0x00,0x00,0x00,0x00,0x00};
uchar code F_Rotation[]={0x20,0x60,0x40,0xc0,0x80,0x90,0x10,0x30};//正转表格
uchar x24c02_read(uchar address);
void x24c02_write(uchar address,uchar info);
void keyscan(void);
//软件延时
/***********************************************
* 名称 : flash()
* 功能 : 延时大概为2US
* 输入 : 无
* 输出 : 无
***********************************************/
void flash(void)
{
_nop_();
_nop_();
}
/***********************************************
*名称:delay_16us(uint A)单位us
*功能:当使用11.0592MHz晶振时候调用大概要耗时24
us,每次计数耗时约为16us
*输入:要延时的时间(A x 16)
*输出:无
***********************************************/
void delay_16us(uint N)
{
int i;
for(i=0;i<N;i++);
}
/***********************************************
*名称:delay_1ms(uint A)单位us
*功能:当使用11.0592MHz晶振时候每次计数延时约1ms
*输入:要延时的时间a ms
*输出:无
***********************************************/
void delay_1ms(uint a)
{
int i,j;
for(i=a;i>0;i--)
for(j=110;j>0;j--);
}
//定时器延时
/***********************************************
* 名称 : Time1_Init()
* 功能 : 定时器的初始化,11.0592MZ晶振,10ms
* 输入 : 无
* 输出 : 无
***********************************************/
void Time1_Init()
{
TMOD = 0x10;
IE = 0x88;
TH0 = 0xb8;
TL0 = 0x00;
}
/***********************************************
* 名称 : Time1_Int()
* 功能 : 定时器中断,中断中实现 Count 加一
* 输入 : 无
* 输出 : 无
***********************************************/
void Time1_Int() interrupt 3
{
TH0 = 0xb8;
TL0 = 0x00;
Count2++;
if(Count2==50)
{
Count2=0;
xie=1; //20ms写一次
}
}
//DS18B20测温显示
/***********************************************
*名称:Reset()
*功能:复位DS18B20
*输入:无
*输出:无
***********************************************/
uchar Reset(void)
{
uchar receive_data;
DQ=0; //把DQ拉低
delay_16us(29); //持续480us
DQ=1; //使DQ回高
delay_16us(3); //等存在脉冲
receive_data=DQ; //得存在脉冲
delay_16us(25);
return(receive_data);//返回时隙信号
}
/***********************************************
*名称:read_bit 读一位
*功能:从DS18B20读一个位值
*输入:无
*输出:一位的位值
***********************************************/
uchar read_bit(void)
{
uchar i;
DQ=0; //读开始
DQ=1;
for(i=0;i<3;i++); //延时约15us
return(DQ);
}
/***********************************************
*名称:write_bit() 写一位
*功能:向DS18B20写一个位值
*输入:bitval(要对DS18B20写入的位值)
*输出:无
***********************************************/
void write_bit(uchar bitval)
{
DQ=0; //拉低DQ开始写时隙
if(bitval==1) //若写1就拉高DQ,否则反之
DQ=1;
delay_16us(5); //延时采样
DQ=1;
}
/***********************************************
*名称:read_byte() 读一字节
*功能:从DS18B20读一个字节的值
*输入:无
*输出:读到的一个字节的值
***********************************************/
uchar read_byte(void)
{
uchar i,j,receive_data8;
j=1;
receive_data8=0;
for(i=0;i<8;i++)
{
if(read_bit())
{ receive_data8=receive_data8+(j<<i);
}
delay_16us(6);
}
return(receive_data8);
}
/***********************************************
*名称:write_byte() 写一字节
*功能:向DS18B20写一个字节的值
*输入:val(要对DS18B20写入的命令值)
*输出:无
***********************************************/
void write_byte(uint val)
{
uchar i,temp;
for(i=0;i<8;i++)
{
temp=val>>i; //分8次实现写操作
temp=temp&0x01; //只保留末位,实现bit输入
write_bit(temp);
delay_16us(5);
}
}
/***********************************************
*名称:tmp()
*功能:获得十进制温度值
*输入:无
*输出:display[]
***********************************************/
void tmp(void)
{
uchar n;
n=0;
Reset();
write_byte(jump_ROM);
write_byte(start);
Reset();
write_byte(jump_ROM);
write_byte(read_EEROM);
TMPL = read_byte();
TMPH = read_byte();
if(TMPH>127)
{
TMPH=(255-TMPH);
TMPL=(255-TMPL+1);
n=1;
}
display[4]=TMPL&0x0f;
display[0]=distab[display[4]];
display[4]=((TMPL&0xf0)>>4)|((TMPH&0x0f)<<4);
display[3]=(display[4]/100);
display[2]=(display[4]%100)/10;
display[1]=(display[4]%100)%10;
if(n)
display[3]=0x2d;
}
//1602液晶显示
/***********************************************
*名称:enable_1602()
*功能:1602的命令输入
*输入:命令值
*输出:无
***********************************************/
void enable_1602(uchar a)
{
P0=a;
RS=0;
RW=0;
E=0;
delay_1ms(20);
E=1;
delay_1ms(20);
}
/***********************************************
*名称:write_1602()
*功能:1602的数据写入
*输入:写入的数据
*输出:无
***********************************************/
void write_1602(uchar a)
{
P0=a;
RS=1;
RW=0;
E=0;
delay_1ms(20);
E=1;
delay_1ms(20);
}
/***********************************************
*名称:L1602_init()
*功能:初始化1602
*输入:无
*输出:无
***********************************************/
void L1602_init(void)
{
uchar num,i;
enable_1602(0x01); //清屏
enable_1602(0x38); //初始化5x7的显示
enable_1602(0x0c); //开或关光标设置
enable_1602(0x06); //地址指针加1
enable_1602(0x80);
for(num=0;num<14;num++)
{
write_1602(table1[num]);
delay_1ms(5);
}
enable_1602(0xc0);
for(num=0;num<7;num++)
{
write_1602(table2[num]);
delay_1ms(5);
}
for(i=3;i>0;i--)
{
write_1602(0x30+display
);
delay_1ms(5);
}
write_1602(table2[10]);
delay_1ms(5);
write_1602(0x30+display[0]);
delay_1ms(5);
for(num=12;num<14;num++)
{
write_1602(table2[num]);
delay_1ms(5);
}
}
/***********************************************
*名称:L1602_char(uchar hang,uchar lie,uchar sign)
*功能:改变液晶中某位的值,如果要让第一行,第五个
字符显示"b" ,调用该函数如:L1602_char(1,5,'b')
*输入:行,列,要输入1602的数据
*输出:无
***********************************************/
void L1602_char(uchar hang,uchar lie,uchar sign)
{
uchar a;
if(hang==1) a=0x80;
if(hang==2) a=0xc0;
a=a+lie-1; //设置数据指针
enable_1602(a);
write_1602(sign);
}
/***********************************************
*名称:L1602_string(uchar hang,uchar lie,uchar *p)
*功能:改变液晶中某位的值
*输入:行,列,要输入1602的数据
*输出:无
***********************************************/
void L1602_string(uchar hang,uchar lie,uchar date)
{
uchar a;
uchar shi,ge;
shi=date/10;
ge=date%10;
if(hang==1) a=0x80;
if(hang==2) a=0xc0;
a=a+lie-1;
enable_1602(a);
write_1602(0x30+shi);
write_1602(0x30+ge);
}
/***********************************************
*名称:write_display()
*功能:显示当前温度
*输入:无
*输出:无
***********************************************/
void write_display(void)
{
enable_1602(0xc0+7);
write_1602(0x30+display[3]);
write_1602(0x30+display[2]);
write_1602(0x30+display[1]);
enable_1602(0xc0+7+4);
write_1602(0x30+display[0]);
}
//24C02数据储存
/***********************************************
* 名称 : x24c02_init()
* 功能 : 24c02初始化子程序
* 输入 : 无
* 输出 : 无
***********************************************/
void x24c02_init(void)
{
scl=1;flash();sda=1;flash();
}
/***********************************************
* 名称 : start_24c02()
* 功能 : 启动I2C总线
* 输入 : 无
* 输出 : 无
***********************************************/
void start_24c02(void)
{
sda=1;flash();scl=1;flash();sda=0;flash();scl=0;flash();
}
/***********************************************
* 名称 : stop_24c02()
* 功能 : 停止I2C总线
* 输入 : 无
* 输出 : 无
***********************************************/
void stop_24c02()
{
sda=0;flash();scl=1;flash();sda=1;flash();
}
/***********************************************
* 名称 : write_24c02()
* 功能 : 写一个字节
* 输入 : 写入的值
* 输出 : 无
***********************************************/
void write_24c02(uchar j)
{
uchar i,k;
k=j;
for(i=0;i<8;i++)
{
k=k<<1;scl=0;flash();sda=CY;flash();
scl=1;flash();
}
scl=0;flash();sda=1;flash();
}
/***********************************************
* 名称 : read_24c02()
* 功能 : 读一个字节
* 输入 : 无
* 输出 : 读出的值
***********************************************/
uchar read_24c02(void)
{
uchar i,j,k=0;scl=0;flash();sda=1;
for(i=0;i<8;i++)
{
flash();scl=1;flash();if(sda==1) j=1;
else j=0;
k=(k<<1)|j;scl=0;
}
flash();return(k);
}
/***********************************************
* 名称 : I2C_clock()
* 功能 : I2C总线时钟
* 输入 : 无
* 输出 : 无
***********************************************/
void I2C_clock(void)
{
uchar i=0;scl=1;flash();
while((sda==1)&&(i<255))
{ i++;}
scl=0;flash();
}
/***********************************************
* 名称 : x24c02_read()
* 功能 : 从24c02中读出值
* 输入 : address(要在这个地址读取值)
* 输出 : 从24c02中读出的值
***********************************************/
uchar x24c02_read(uchar address)
{
uchar i;start_24c02();
write_24c02(0xa0);I2C_clock();
write_24c02(address);I2C_clock();
start_24c02();
write_24c02(0xa1);I2C_clock();
i=read_24c02();stop_24c02();
delay_16us(10);return(i);
}
/***********************************************
* 名称 : x24c02_write()
* 功能 : 想24c02中写入数据
* 输入 : address(地址) , info(值)
* 输出 : 无
***********************************************/
void x24c02_write(uchar address,uchar info)
{
EA=0;start_24c02();
write_24c02(0xa0);
I2C_clock();write_24c02(address);
I2C_clock();write_24c02(info);
I2C_clock();stop_24c02();
EA=1;delay_16us(50);
}
//报警
/***********************************************
*名称:alert(uchar sign)
*功能:报警电路
*输入:设置的温度值
*输出:调整后的温度值
***********************************************/
void alert(uchar sign)
{
uchar i,j;
while((sign==27)|(sign==17))
{
for(j=0;j<3;j++)
{
for(i=0;i<200;i++)//喇叭发声的时间循环
{
delay_16us(80); //参数决定发声的频率,估算值 beep=!beep;
}
beep=1; //喇叭停止工作,间歇的时间,可更改
delay_1ms(1000);
}
if(sign==27) sign=26;
else sign=18;
}
}
//键扫描
/***********************************************
*名称:keyscan()
*功能:给空调工作定温(按键)
*输入:无
*输出:无
***********************************************/
void keyscan(void)
{
uchar hang,lie;
enable_1602(0x80+10);
if(s1==0)
{
delay_1ms(5);if(s1==0)s1num++;while(!s1);while(s1num!=0)
{
if(s1==0)
{ delay_1ms(5);if(s1==0)s1num++;while(!s1);
}
switch(s1num)
{
case 1:enable_1602(0x80+10);
enable_1602(0x0f);hang=1;lie=11;break;
case 2:enable_1602(0xc0+3 );
enable_1602(0x0f);hang=2;lie=4;break;
case 3:enable_1602(0x0c);s1num=0;break;
}
if((s1num==1)&&(s2==0))
{
delay_1ms(5);if(s2==0)
while(!s2);
T++;
alert(T);
if(T==27) T=26;
L1602_string(hang,lie,T);
enable_1602(0x80+10);
}
if((s1num==1)&&(s3==0))
{
delay_1ms(5);
if(s3==0)
while(!s3);
T--;
alert(T);
if(T==17) T=18; L1602_string(hang,lie,T);
enable_1602(0x80+10);
}
if((s1num==2)&&(s2==0))
{
delay_1ms(5);
if(s2==0)
if(s2num==3);
else s2num++;
while(!s2);
switch(s2num)
{
case 1:enable_1602(0x0f);speed=2000;L1602_char(2,4,'L');enable_1602(0xc0+3);break;
case 2:enable_1602(0x0f);speed=1500;L1602_char(2,4,'M');enable_1602(0xc0+3);break;
case 3:enable_1602(0x0f);speed=1000;L1602_char(2,4,'H');enable_1602(0xc0+3);break;
}
}
if((s1num==2)&&(s3==0))
{
delay_1ms(5);
if(s3==0)
if(s2num==0);
else s2num--;
while(!s3);
switch(s2num)
{
case 0:enable_1602(0x0f);speed=2000;L1602_char(2,4,'L');enable_1602(0xc0+3);break;
case 1:enable_1602(0x0f);speed=1500;L1602_char(2,4,'M');enable_1602(0xc0+3);break;
case 2:enable_1602(0x0f);speed=1000;L1602_char(2,4,'H');enable_1602(0xc0+3);break;
}
}
}
}
}
//电机执行程序
/***********************************************
*名称:dianji(uchar x)
*功能:电机转动,改变频率控制风速
*输入:设定的频率
*输出:无
***********************************************/
void dianji(uchar x)
{
uchar a;
for(a=0;a<8;a++) //4相
{
P1=F_Rotation[a]; //输出对应的相 可以自行换成反转表格
delay_16us(x); //改变这个参数可以调整电机转速
}
}
//控制执行程序
/***********************************************
*名称:comp_dec()
*功能:比较设定温度与实际温度差,决定制冷还是制热
*输入:设定的温度
*输出:无
***********************************************/
void comp_dec(uchar sheding)
{
int shice,shiceL,shiceH;
shice=display[4]*100+display[3]*10+display[2]*1;
shiceL=shice-1;
shiceH=shice+1;
if((display[4]==0x2d)|(shiceL>sheding))
{
dianji(speed);
warm=1;
}
else
warm=0;
if(shiceH<sheding)
{
dianji(speed);
cool=1;
}
else
cool=0;
}
void main()
{
uchar i;
x24c02_init(); Time1_Init(); for(i=0;i<4;i++)
{
display = x24c02_read(i); }
L1602_init();
T=22;
while(1)
{
TR1=1;
keyscan(); tmp();
write_display(); if(xie==1)
{
xie=0;
for(i=0;i<4;i++)
{
x24c02_write(i,display);
}
}
comp_dec(T); }
}
一周热门 更多>