前言:作者想要帮助一些童鞋和爱好者进行项目构建,但自知能力有限,不喜可论,创作不易,勿喷。
系统采用STC12C5A60S2芯片进行的单片机恒温箱,能够实现恒温加热,超温报警。上代码。
main.c
#include <STC12C5A60S2.H>
#include <ds1602.c>
uchar cp,cp1,cp2,cp3,mode=0,sec,min,hour,mode1=0;
uchar temp,ad0,temp_x;
unsigned char TL=0,TH=0,TD=0,TN=0,count;
#include <18b20.c>
uchar bit0=0,bit1=0,bit2=0,bit3=0,flag=0;
#include "key.c"
//uint T0_H,T0_L,T1_H,T1_L;
#include <display.c>
void Timer_isr(void)interrupt 1
{
TH0 =64535/256;
TL0 =64535%256;
cp++;
if(cp >= 250)
{
cp = 0;
cp1++;
key();
ReadTemp();
if(cp1 >= 240)//min 240=1min
{
cp1 = 0;
min++;
if(min >= 2)
{
min = 0;
if(bit0 == 1)bit0 = 0;
if(bit1 == 1)bit1 = 0;
if(bit2 == 1)bit2 = 0;
if(bit3 == 1)bit3 = 0;
}
}
}
}
void Timer_Init()
{
TMOD = 0x01;
TH0 =64535/256;
TL0 =64535%256;
TR0 = 1;
ET0 = 1;
EA =1;
}
void T_mode()
{
if(flag == 0)
{
// mode1 = 0;
cp1 = 0;
flag = 1;
bit0 = 1;
}
if(bit0 == 0){
if(flag == 1)
{
// mode1 = 1;
cp1 = 0;
flag = 2;
bit1 = 1;
}
if(bit1 == 0){
if(flag == 2)
{
// mode1 = 2;
cp1 = 0;
flag = 3;
bit2 = 1;
}
if(bit2 == 0){
if(flag == 3)
{
cp1 = 0;
flag = 4;
bit3 = 1;
}
if(bit3 == 0){
flag = 0;
mode = 0;
}
}
}
}
}
void temp_mode(uchar aa,bb,cc,dd)
{
if( bit0 == 1)
{
if(TN > aa) P20 = 0;
if(TN <= aa) P20 = 1;
}
if( bit1 == 1)
{
if(TN > bb) P20 = 0;
if(TN <= bb) P20 = 1;
}
if( bit2 == 1)
{
if(TN > cc) P20 = 0;
if(TN <= cc) P20 = 1;
}
if( bit3 == 1)
{
if(TN > dd) P20 = 0;
if(TN <= dd) P20 = 1;
}
}
void main()
{
Timer_Init();
init_1602();
LCD_clr1602();
delayus(20);
//
ReadTemp();
while(1)
{
if(mode == 0)P20= 0;
else T_mode();
if(mode == 1)temp_mode(100,90,80,70);
if(mode == 2)temp_mode(90,80,70,60);
if(mode == 3)temp_mode(80,70,60,50);
if(mode == 4)temp_mode(70,60,50,40);
display();
}
}
DS1602.c
#define uchar unsigned char
#define uint unsigned int
sbit RS = P2^5;//数据/命令
sbit RW = P2^6;//读/写
sbit E = P2^7;//使能
uchar i;
uchar str[] = {"Internet of Things00"};
uchar num[] = {"0123456789"};
void delayus(uint x) //延时函数
{
while(x--);
}
void write_com(uchar com)//写命令
{
RW = 0;
RS = 0;
E = 1;
P0 = com;
delayus(100);
E = 0;
}
void write_data(uchar da)//写入数据
{
RW = 0;
RS = 1;
E = 1;
P0 = da;
delayus(100);
E = 0;
}
void init_1602() //LCD1602 初始化
{
write_com(0x3c);//设定数据总线的个数4/8,显示一行/两行
write_com(0x0c);// //光标不显示
write_com(0x06);// //光标随字符右移
}
void LCD_clr1602() //LCD1602 清屏
{
write_com(0x01); // 对字符串清0
write_com(0x02); //对光标清0
}
void goto_xy(uchar y,uchar x) //定位显示位置
{
if(y == 1)
write_com(x + 0x80); //定位第一行
else
write_com(x + 0x80 + 0x40); //定位第二行
}
void display_num(unsigned char x) //显示数字
{
write_data(num[x / 10%10]);
write_data(num[x % 10]);
}
void display_num1(unsigned int x) //显示数字
{
write_data(num[x / 1000 % 10]);
write_data(num[x / 100 % 10]);
write_data(num[x / 10 % 10]);
write_data(num[x % 10]);
}
void display_string(uchar *p) //显示字符
{
while(*p)
{
write_data(*p);
p++;
}
}
void display_xnum2(float x) //显示数字
{
uint y,x1;
y = (int)x;
write_data(num[y / 10]);
write_data(num[y % 10]);
x1 = (int)((x -(float)y)*1000);
display_string(".");
write_data(num[x1 / 100 % 10]);
// write_data(num[x1 / 10 % 10]);
// write_data(num[x1 % 10]);
}
void display_xnum1(float x) //显示数字
{
uint y,x1;
y = (int)x;
write_data(num[y / 100%10]);
write_data(num[y / 10%10]);
write_data(num[y % 10]);
x1 = (int)((x -(float)y)*1000);
display_string(".");
write_data(num[x1 / 100 % 10]);
write_data(num[x1 / 10 % 10]);
}
18b20.c
/
/***********ds18b20子程序*************************/
sbit DQ = P2^4;
/***********ds18b20延迟子函数(晶振12MHz )*******/
void delay_18B20(unsigned int i)
{
while(i--);
}
/**********ds18b20初始化函数**********************/
void Init_DS18B20(void)
{
unsigned char x=0;
DQ = 1; //DQ复位
delay_18B20(8); //稍做延时
DQ = 0; //单片机将DQ拉低
delay_18B20(80); //精确延时 大于 480us
DQ = 1; //拉高总线
delay_18B20(14);
x=DQ; //稍做延时后 如果x=0则初始化成功 x=1则初始化失败
delay_18B20(20);
}
/***********ds18b20读一个字节**************/
unsigned char ReadOneChar(void)
{
uchar i=0;
uchar dat = 0;
for (i=8;i>0;i--)
{
DQ = 0; // 给脉冲信号
dat>>=1;
DQ = 1; // 给脉冲信号
if(DQ)
dat|=0x80;
delay_18B20(4);
}
return(dat);
}
/*************ds18b20写一个字节****************/
void WriteOneChar(uchar dat)
{
unsigned char i=0;
for (i=8; i>0; i--)
{
DQ = 0;
DQ = dat&0x01;
delay_18B20(5);
DQ = 1;
dat>>=1;
}
}
/**************读取ds18b20当前温度************/
void ReadTemp()
{
Init_DS18B20();
WriteOneChar(0xCC); // 跳过读序号列号的操作
WriteOneChar(0x44); // 启动温度转换
delay_18B20(100); // this message is wery important
Init_DS18B20();
WriteOneChar(0xCC); //跳过读序号列号的操作
WriteOneChar(0xBE); //读取温度寄存器等(共可读9个寄存器) 前两个就是温度
TL=ReadOneChar(); //先读的是温度值低位
TH=ReadOneChar(); //接着读的是温度值高位
TN=TH*16+TL/16; //实际温度值=(TH*256+TL)/16,即:TH*16+TL/16
//这样得出的是温度的整数部分,小数部分被丢弃了
TD=(TL%16)*100/16; //计算温度的小数部分,将余数乘以10再除以16取整,
//这样得到的是温度小数部分的第一位数字(保留1位小数)
}
key.c
void key()
{
if(P32 == 0)
{
while(P32 == 0);
mode = 1;
}
if(P33 == 0)
{
while(P33 == 0);
mode = 2;
}
if(P34 == 0)
{
while(P34 == 0);
mode = 3;
}
if(P35 == 0)
{
while(P35 == 0);
mode = 4;
}
}
display.c
void display()
{
goto_xy(1,0);
display_string("temp:");
display_num(TN);
display_string(".");
display_num(TD);
display_string(" ");
display_num(mode);
goto_xy(2,5);
display_num(bit0);
display_num(bit1);
display_num(bit2);
display_num(bit3);
}
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/156064.html