`
#include
#include
#define uchar unsigned char
#define uint unsigned int
#define jump_ROM 0xcc
#define start 0x44
#define read_EEROM 0xbe
***it scl=P3^5; //24c02 SCL
***it sda=P3^6; //24c02 SDA
***it DQ=P2^3; //DS18B20数据口
***it E=P2^7; //1602使能引脚
***it RW=P2^6; //1602读写引脚
***it RS=P2^5; //1602数据/命令
***it beep=P3^7; //蜂鸣器报警
***it s1=P3^2; //功能选择按键
***it s2=P3^3; //温度加
***it s3=P3^4; //温度减
***it warm=P3^0; //升温继电器
***it 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
}
/***********************************************
*名称: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<
}
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
{ 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); } } `
0
已退回3积分
|