前几天做好了板子 最近几天一直在写程序
经过几天的奋斗(并不)  总算写完了!
俗话说: 电路简单 程序就麻烦 我算是体会到了 555
以后再也不图省事了 软件可比硬件让人头大多啦!
这个温度计所有的显示部分都是一个IO来控制 用的型号是STC15W104  扩展用的2片 74HC595
当时看中它的程序空间大 结果其实也没那么大,嘎嘎 结果EEPROM只有1K了
1.jpg

2.jpg

3.jpg

好了 进入正题 我先自吹自擂一下 (啊?! 谁扔的臭鸡蛋!)
从左到右 三个按钮 1 2 3
按钮1:短按 查看最大最小温湿度 每按一次切换显示1个  这些数据全部存储在内部的FlashRom中 会自动更新
长按 清除内部FlashRom存储的数据 并用当前的测量值全部填充
按钮2:显示模式轮换,三个模式:温湿度自动轮换 仅温度 仅湿度
其中温湿度自动轮换时间可调  显示的数值是每次切换温湿度的时候测量的
仅温度 仅湿度 这两个的数据是 每半秒更新一次(不可调 但是可以在编译前调好,我设置的是半秒)
这2个模式貌似每次更新的时候 LED会闪一下 没办法 设计缺陷555 谁叫他1个IO干完全部的显示呢?
按钮3:切换自动轮换的时间 ,我设置了3个挡位 2.5s 5s 10s ,同时这个还会自动存储在FlashROM里,只需要设定时间一次~~

P.S 最后加点感想: 这次又学到了很多东西,还专门写了2个C文件模块,模块化编程好啊~ 赞美C语言!
昨天晚上写这个程序,写的头很大,来来回回删了又写写了又删 ,起码删了300行,可谓是绞尽脑汁,我那10毫升的大脑都要变成浆糊啦!
今晚折腾出来了 我甚开心,赶紧拍下照片发帖留念了,MCU的世界真是美妙....我永远喜欢单片机!

单片机源程序如下:
#include "stc15f2k60s2.h"
  • #include "dht11.h"
  • #include "iaprom.h"
  • #define u8 unsigned char
  • #define u16 unsigned int
  • u8 code SMGtable[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x40};//最后这个是负号
  • void IOinit();
  • void LEDsDisplay(u8 Number,u8 position);
  • void Timer0Init();
  • void hc595activate();
  • void hc595send (u8 sbyte);
  • void Delay10ms();
  • void AllDisplay(u8 Integer,u8 Decimal);
  • void keyscan();
  • void CheckMaxMin();
  • void NormalMode();
  • void TemponlyMode();
  • void HumionlyMode();
  • void ModeInit();
  • void ModeSelect();                   //选择3种模式
  • void ViewMaxMin();         //查看最大最小温湿度
  • sbit LCHCK=P3^2;                   //595的时钟
  • sbit SFTCK=P3^3;
  • sbit sb1=P3^4;                        //MaxMin按钮1          检查max min,4 组数据切换,长按清空flash存储区
  • sbit sb2=P3^5;                        //mode按钮sb2   切换模式 湿度温度自动切换 长温度 长湿度
  • sbit sb3=P3^0;                        //切换时间sb3        自动切换时间调整   2.5S  5S 10S 三档 50 100 200
  • extern bit TempPoOrNe;         //温度正负位
  • bit TempHumiSelect=1; //1=Temp 0=Humi
  • int Temp,Humi;
  • u8 Time50ms=0;                 //50ms标志位
  • u8 SetTimes=50;                 //设定的时间 分别是 50(默认) 100 200
  • u8 SetMode=0x00;        //模式标志位 分别为 0x00 0x11 0x22   自动切换 长温度 长湿度
  • u8 ConditionLeds=0x0f;          //后4位控制4个LED灯泡的亮灭 0x01 MAX ,0x02 Min ,0x04 Temp ,0x08 Humi
  • void main()
  • {
  •         IOinit();
  •         Delay1000ms();//延时1s 等待传感器就位
  •         Timer0Init();          //定时器0初始化
  •         EA=1;ET0=1;                  //开中断,开定时器0中断
  •         GetTempAndHumi();  // 先读取一次温湿度
  •         ModeInit();       //从ROM中读取mode 进行初始化
  •         while(1)
  •         {
  •                 ModeSelect();                //选择模式 每个模式也负责读取温度
  •                 CheckMaxMin();
  •                 keyscan();
  •         }      
  • }
  • void keyscan()
  • {
  •         if(sb1==0||sb2==0||sb3==0)
  •         {
  •                 Delay10ms();
  •                 if(sb1==0)
  •                 {
  •                         Timer0Init();
  •                         Time50ms=0;
  •                         while(!sb1);
  •                         Delay10ms();
  •                         if(Time50ms>20)          //>1000ms
  •                         {
  •                                 IapEraseSector(0x0000);
  •                                 IapProgramWord(0x0000,Temp);
  •                                 IapProgramWord(0x0002,Humi);
  •                                 IapProgramWord(0x0004,Temp);
  •                                 IapProgramWord(0x0006,Humi);
  •                         }
  •                         else
  •                         {
  •                                 ViewMaxMin();        //短按操作
  •                         }
  •                         Timer0Init();                 //复位中断
  •                         Time50ms=0;
  •                 }
  •                 if(sb2==0)                                         //切换模式
  •                 {
  •                         if(SetMode==0x00) SetMode=0x11;
  •                         else if(SetMode==0x11) SetMode=0x22;
  •                         else if(SetMode==0x22) SetMode=0x00;
  •                         else SetMode=0x00;
  •                         while(!sb2);
  •                         Delay10ms();
  •                         IapEraseSector(0x0200);                    //擦除扇区
  •                         IapProgramByte(0x0200,SetMode);        //写入更改后的模式
  •                         Time50ms=0;
  •                 }
  •                 if(sb3==0&&SetMode==0x00)                                 //调整自动切换时间 2.5s 5s 10s
  •                 {
  •                         while(!sb3);
  •                         Delay10ms();
  •                         if(SetTimes==50) SetTimes=100;
  •                         else if(SetTimes==100) SetTimes=200;
  •                         else if(SetTimes==200) SetTimes=50;
  •                         else SetTimes=50;
  •                 }
  •         }
  • }
  • void CheckMaxMin()         //将读取到的温度湿度和存储的最大最小值对比,如果有更大/更小的,就写入
  • {
  •         int MaxTemp,MaxHumi,MinTemp,MinHumi;
  •         Temp=TempInteger*10+TempDecimal;                //把温度转化带正负的Int 如24.4 -> 244
  •         if(TempPoOrNe!=1) Temp=Temp*-1;                        //判断温度正负
  •         Humi=HumiInteger*10+HumiDecimal;                //湿度转化 ,其实可以用无符号 因为湿度是不可能是负数.但是我偷懒了
  •         MaxTemp=IapReadWord(0x0000);                        //从Rom中读取一些参数        做个留存保护
  •         MaxHumi=IapReadWord(0x0002);
  •         MinTemp=IapReadWord(0x0004);
  •         MinHumi=IapReadWord(0x0006);
  •         if(Temp>MaxTemp||Temp<MinTemp||Humi>MaxHumi||Humi<MinHumi) //如果需要更新
  •         {
  •                 IapEraseSector(0x0000);
  •                 if(Temp>MaxTemp) IapProgramWord(0x0000,Temp); else IapProgramWord(0x0000,MaxTemp);
  •                 if(Temp<MinTemp) IapProgramWord(0x0004,Temp); else IapProgramWord(0x0004,MinTemp);
  •                 if(Humi>MaxHumi) IapProgramWord(0x0002,Humi); else IapProgramWord(0x0002,MaxHumi);
  •                 if(Humi<MinHumi) IapProgramWord(0x0006,Humi); else IapProgramWord(0x0006,MinHumi);
  •         }
  •                
  • }
  • void ModeInit()
  • {
  •          SetMode=IapReadByte(0x0200);
  • }
  • void ViewMaxMin()                        //查看最大最小
  • {
  •          int cache;
  •          u8 cache1,cache2;
  •          Time50ms=0;
  •          while(sb1)                        //有按下就会继续往下执行 否则return
  •          {
  •                  ConditionLeds=0x05;                                           //最大温度灯亮
  •                 cache=IapReadWord(0x0000);
  •                 if(cache<0)
  •                 {
  •                 TempPoOrNe=0;
  •                 cache=cache*-1;
  •                 }
  •                 else TempPoOrNe=1;
  •                 cache1=cache/10;cache2=cache%10;
  •                 AllDisplay(cache1,cache2);//这是最大温度
  •                 if(Time50ms>100)
  •                 {
  •                         Time50ms=0;
  •                         GetTempAndHumi();
  •                         TempHumiSelect=1;
  •                         return;     //五秒不再按按钮就会自动退出
  •                 }
  •          }
  •          Delay10ms(); //按键消抖
  •          while(!sb1); //等你松手
  •          Delay10ms(); //按键消抖
  •          Time50ms=0;
  •          while(sb1)        //等你继续按下
  •          {
  •                 ConditionLeds=0x09;                           //最大湿度灯亮
  •                 cache=IapReadWord(0x0002);
  •                 cache1=cache/10;cache2=cache%10;
  •                 AllDisplay(cache1,cache2);//这是最大温度
  •                 if(Time50ms>100)
  •                 {
  •                         Time50ms=0;
  •                         GetTempAndHumi();
  •                         TempHumiSelect=1;
  •                         return;     //五秒不再按按钮就会自动退出
  •                 }
  •          }
  •          Delay10ms(); //按键消抖
  •          while(!sb1); //等你松手
  •          Delay10ms(); //按键消抖
  •          Time50ms=0;
  •          while(sb1)        //等你继续按下
  •          {
  •                 ConditionLeds=0x06;                                          //最小温度
  •                 cache=IapReadWord(0x0004);
  •                 if(cache<0)
  •                 {
  •                 TempPoOrNe=0;
  •                 cache=cache*-1;
  •                 }
  •                 else TempPoOrNe=1;
  •                 cache1=cache/10;cache2=cache%10;
  •                 AllDisplay(cache1,cache2);//这是最小温度
  •                 if(Time50ms>100)
  •                 {
  •                         Time50ms=0;
  •                         GetTempAndHumi();
  •                         TempHumiSelect=1;
  •                         return;     //五秒不再按按钮就会自动退出
  •                 }
  •          }
  •          Delay10ms(); //按键消抖
  •          while(!sb1); //等你松手
  •          Delay10ms(); //按键消抖
  •          Time50ms=0;
  •          while(sb1)        //等你继续按下
  •          {
  •                 ConditionLeds=0x0a;
  •                 cache=IapReadWord(0x0006);
  •                 cache1=cache/10;cache2=cache%10;
  •                 AllDisplay(cache1,cache2);//这是最小湿度
  •                 if(Time50ms>100)
  •                 {
  •                         Time50ms=0;
  •                         GetTempAndHumi();
  •                         TempHumiSelect=1;
  •                         return;     //五秒不再按按钮就会自动退出
  •                 }
  •          }
  •          Delay10ms(); //按键消抖
  •          while(!sb1); //等你松手
  •          GetTempAndHumi();
  •          Delay10ms(); //按键消抖
  •          TempHumiSelect=1;
  •          Time50ms=0;
  • }
  • void NormalMode()                        //常规模式
  • {
  •         if(TempHumiSelect)
  •         {
  •                 ConditionLeds=0x04;                //亮温度灯
  •                 AllDisplay(TempInteger,TempDecimal);      
  •         }
  •         else
  •         {
  •                 ConditionLeds=0x08;          //亮湿度灯
  •                 AllDisplay(HumiInteger,HumiDecimal);
  •         }
  •         if(Time50ms>SetTimes)
  •         {
  •                 Time50ms=0;
  •                 TempHumiSelect=~TempHumiSelect;
  •                 GetTempAndHumi();//每次切换时读取一次温湿度
  •         }
  • }
  • void TemponlyMode()                   //仅温度
  • {
  •         ConditionLeds=0x04;                //亮温度灯
  •         AllDisplay(TempInteger,TempDecimal);
  •         if(Time50ms>10)                   //500ms
  •         {
  •                 Time50ms=0;
  •                 GetTempAndHumi();//每次切换时读取一次温湿度
  •         }
  • }
  • void HumionlyMode()                        //仅湿度
  • {
  •         ConditionLeds=0x08;          //亮湿度灯
  •         AllDisplay(HumiInteger,HumiDecimal);
  •         if(Time50ms>10)                 //500ms
  •         {
  •                 Time50ms=0;
  •                 GetTempAndHumi();//每次切换时读取一次温湿度
  •         }
  • }
  • void ModeSelect()
  • {
  •         if(SetMode==0x00) NormalMode();
  •         else if(SetMode==0x11) TemponlyMode();
  •         else if(SetMode==0x22) HumionlyMode();
  •         else NormalMode();
  • }
  • void IOinit(void)
  • {
  • //P3 0  1  2  3  4  5  x  x
  • //         阻 默 默 默 阻 阻 x  x
  • //M1 1  0  0  0  1  1  x  x
  • //M0 0  0  0  0  0  0  x  x
  • P3M1=0x31;
  • P3M0=0x00;      
  • }
  • void LEDsDisplay(u8 Number,u8 position)         //在单个数码管和所有led灯珠显示内容 ,会自动在第三位上加上小数点
  • {
  •         u8 i=0,j=0xf0;
  •         i=(clrbit(j,position+3))+ConditionLeds;         //        计算需要输出的位选+led指示灯亮灭情况
  •         hc595send(i);           //发送位选和状态显示灯状态位
  •         if(position==3) hc595send(SMGtable[Number]|0x80);           //第三位加个小数点
  •         else hc595send(SMGtable[Number]);
  •         hc595activate();                       
  • }
  • void AllDisplay(u8 Integer,u8 Decimal)                 //扫描显示所有4个数码管和led灯珠        //也进行显示正负
  • {
  •         if(TempPoOrNe!=1)
  •         {
  •         LEDsDisplay(10,1);         //显示负号位 ,否则不显示
  •         }
  •         if(Integer/10%10!=0)          //判断十位是否需要消隐
  •         {
  •         LEDsDisplay(Integer/10%10,2);         //十位
  •         }
  •         LEDsDisplay(Integer/1%10,3);         //个位
  •         LEDsDisplay(Decimal/1%10,4);         //小数点后1位
  • }
  • void Timer0Init()                //        50ms @12Mhz 计时器0初始化
  • {
  •         AUXR &= 0x7F;                //12T
  •         TMOD &= 0xF0;      
  •         TL0 = 0xB0;               
  •         TH0 = 0x3C;               
  •         TF0 = 0;               
  •         TR0 = 1;
  • }
  • void Timer0 () interrupt 1          //计时器0中断
  • {
  •         Time50ms++;
  • }
  • void hc595send (u8 sbyte)        //移位输出8位数据至移位寄存器中          高位先进入移位寄存器
  • {
  •         u8 i=0;
  •         for(i=0;i<8;i++)
  •         {
  •                 SFTCK=0;
  •                 dat11=getbit(sbyte,7-i);
  •                 SFTCK=1;
  •         }
  • }
  • void hc595activate()                //让595输出寄存器输出移位寄存器保存的结果
  • {
  •         LCHCK=0;
  •         LCHCK=1;
  •         LCHCK=0;      
  • }
  • void Delay10ms()                //@12.000MHz  软延时10ms
  • {
  •         unsigned char i, j;
  •         i = 117;
  •         j = 184;
  •         do
  •         {
  •                 while (--j);
  •         } while (--i);
  • }
  • 复制代码