51单片机光照和温度控制步进电机正反转,有手动和自动控制模式。
仿真原理图如下(proteus仿真工程文件可到本帖附件中下载)
单片机源程序如下:
- #include <reg52.h>
- #include <intrins.h>
- #define uchar unsigned char // 以后unsigned char就可以用uchar代替
- #define uint unsigned int // 以后unsigned int 就可以用uint 代替
- sbit ADC_CS = P1^6; // ADC0832的CS引脚
- sbit ADC_CLK = P1^7; // ADC0832的CLK引脚
- sbit ADC_DAT = P3^0; // ADC0832的DI/DO引脚
- sbit SCK_P = P1^0; // 时钟芯片DS1302的SCK管脚
- sbit SDA_P = P1^1; // 时钟芯片DS1302的SDA管脚
- sbit RST_P = P1^2; // 时钟芯片DS1302的RST管脚
- sbit LcdRs_P = P1^3; // 1602液晶的RS管脚
- sbit LcdRw_P = P1^4; // 1602液晶的RW管脚
- sbit LcdEn_P = P1^5; // 1602液晶的EN管脚
- sbit KeyMode_P = P3^3; // 模式切换
- sbit KeySet_P = P3^4; // 设置时间按键
- sbit KeySet2_P = P3^5; // 设置时间模式的开关时间和光照控制强度
- sbit KeyDown_P = P3^6; // 减按键
- sbit KeyUp_P = P3^7; // 加按键
- sbit Led_P = P2^0; // 指示灯
- sbit ds=P3^1;
- bit closeflag,openflag;
- uchar gMode=1; // 1是手动模式,2是时间自动模式,3是亮度自动模式
- uchar gLight = 40; // 窗帘开关的阈值
- uchar wDu=35;
- uint wd=13,t;
- uchar xsflag;
- uchar code Clock[]={0x80,0x40,0x20,0x10}; // 步进电机顺时针旋转数组
- uchar code AntiClock[]={0x10,0x20,0x40,0x80}; // 步进电机逆时针旋转数组
- uchar TimeBuff[7]={17,9,1,6,18,30,40}; // 时间数组,默认2017年9月1日,星期五,18:30:40
- // TimeBuff[0] 代表年份,范围00-99
- // TimeBuff[1] 代表月份,范围1-12
- // TimeBuff[2] 代表日期,范围1-31
- // TimeBuff[3] 代表星期,范围1-7
- // TimeBuff[4] 代表小时,范围00-23
- // TimeBuff[5] 代表分钟,范围00-59
- // TimeBuff[6] 代表秒钟,范围00-59
- /*********************************************************/
- // 毫秒级的延时函数,time是要延时的毫秒数
- /*********************************************************/
- void DelayMs(uint time)
- {
- uint i,j;
- for(i=0;i<time;i++)
- for(j=0;j<112;j++);
- }
- void delay(uint z) //延时函数
- {
- uint x,y;
- for(x=z;x>0;x--)
- for(y=110;y>0;y--);
- }
- /*********************************************************/
- // 1602液晶写命令函数,cmd就是要写入的命令
- /*********************************************************/
- void LcdWriteCmd(uchar cmd)
- {
- LcdRs_P = 0;
- LcdRw_P = 0;
- LcdEn_P = 0;
- P0=cmd;
- DelayMs(2);
- LcdEn_P = 1;
- DelayMs(2);
- LcdEn_P = 0;
- }
- /*********************************************************/
- // 1602液晶写数据函数,dat就是要写入的数据
- /*********************************************************/
- void LcdWriteData(uchar dat)
- {
- LcdRs_P = 1;
- LcdRw_P = 0;
- LcdEn_P = 0;
- P0=dat;
- DelayMs(2);
- LcdEn_P = 1;
- DelayMs(2);
- LcdEn_P = 0;
- }
- /*********************************************************/
- // 1602液晶初始化函数
- /*********************************************************/
- void LcdInit()
- {
- LcdWriteCmd(0x38); // 16*2显示,5*7点阵,8位数据口
- LcdWriteCmd(0x0C); // 开显示,不显示光标
- LcdWriteCmd(0x06); // 地址加1,当写入数据后光标右移
- LcdWriteCmd(0x01); // 清屏
- }
- /*********************************************************/
- // 液晶光标定位函数
- /*********************************************************/
- void LcdGotoXY(uchar line,uchar column)
- {
- // 第一行
- if(line==0)
- LcdWriteCmd(0x80+column);
- // 第二行
- if(line==1)
- LcdWriteCmd(0x80+0x40+column);
- }
- /*********************************************************/
- // 液晶输出字符串函数
- /*********************************************************/
- void LcdPrintStr(uchar *str)
- {
- while(*str!='\0')
- LcdWriteData(*str++);
- }
- /*********************************************************/
- // 液晶输出数字(0-99)
- /*********************************************************/
- void LcdPrintNum(uchar num)
- {
- LcdWriteData(num/10+48); // 十位
- LcdWriteData(num%10+48); // 个位
- }
- /*********************************************************/
- // 显示模式
- /*********************************************************/
- void LcdPrintMode(uchar num)
- {
- switch(num)
- {
- case 1: LcdPrintStr("Manual"); break;
- /* case 2: LcdPrintStr("Timing"); break;*/
- case 2: LcdPrintStr("Liging"); break;
- case 3: LcdPrintStr(" Wendu"); break;
- default: break;
- }
- }
- /*********************************************************/
- // 液晶显示内容的初始化
- /*********************************************************/
- void LcdShowInit()
- {
- LcdGotoXY(0,0);
- LcdPrintStr("20du - : ");
- LcdGotoXY(1,0);
- LcdPrintStr(" gz: ");
- LcdGotoXY(1,0);
- LcdPrintMode(gMode);
- }
- /*********************************************************/
- // 刷新时间显示
- /*********************************************************/
- void FlashTime()
- {
- LcdGotoXY(0,0); // 年份
- LcdPrintNum(wd);
- LcdGotoXY(0,5); // 月份
- LcdPrintNum(TimeBuff[1]);
- LcdGotoXY(0,8); // 日期
- LcdPrintNum(TimeBuff[2]);
- LcdGotoXY(0,11); // 小时
- LcdPrintNum(TimeBuff[4]);
- LcdGotoXY(0,14); // 分钟
- LcdPrintNum(TimeBuff[5]);
- LcdGotoXY(0,13); // 秒钟
- if(TimeBuff[6]%2==0) // 秒钟是偶数显示冒号
- LcdWriteData(':');
- else // 秒钟是奇数显示空格
- LcdWriteData(' ');
- }
- /*********************************************************/
- // 初始化DS1302
- /*********************************************************/
- void DS1302_Init(void)
- {
- RST_P=0; // RST脚置低
- SCK_P=0; // SCK脚置低
- SDA_P=0; // SDA脚置低
- }
- /*********************************************************/
- // 从DS1302读出一字节数据
- /*********************************************************/
- uchar DS1302_Read_Byte(uchar addr)
- {
- uchar i;
- uchar temp;
-
- RST_P=1;
-
- /* 写入目标地址:addr*/
- for(i=0;i<8;i++)
- {
- if(addr&0x01)
- SDA_P=1;
- else
- SDA_P=0;
- _nop_();
-
- addr=addr>> 1;
- }
-
- /* 读出该地址的数据 */
- for(i=0;i<8;i++)
- {
- temp=temp>>1;
-
- if(SDA_P)
- temp|= 0x80;
- else
- temp&=0x7F;
-
- SCK_P=1;
- _nop_();
- SCK_P=0;
- _nop_();
- }
-
- RST_P=0;
-
- return temp;
- }
- /*********************************************************/
- // 向DS1302写入一字节数据
- /*********************************************************/
- void DS1302_Write_Byte(uchar addr, uchar dat)
- {
- uchar i;
-
- RST_P = 1;
-
- /* 写入目标地址:addr*/
- for(i=0;i<8;i++)
- {
- if(addr&0x01)
- SDA_P=1;
- else
- SDA_P=0;
- SCK_P=1;
- _nop_();
- SCK_P=0;
- _nop_();
-
- addr=addr>>1;
- }
-
- /* 写入数据:dat*/
- for(i=0;i<8;i++)
- {
- if(dat&0x01)
- SDA_P=1;
- else
- SDA_P=0;
-
- SCK_P=1;
- _nop_();
- SCK_P=0;
- _nop_();
-
- dat=dat>>1;
- }
-
- RST_P=0;
- }
- /*********************************************************/
- // 向DS1302写入时间数据
- /*********************************************************/
- void DS1302_Write_Time()
- {
- uchar i;
- uchar temp1;
- uchar temp2;
-
- for(i=0;i<7;i++) // 十进制转BCD码
- {
- temp1=(TimeBuff[i]/10)<<4;
- temp2=TimeBuff[i]%10;
- TimeBuff[i]=temp1+temp2;
- }
-
- DS1302_Write_Byte(0x8E,0x00); // 关闭写保护
- DS1302_Write_Byte(0x80,0x80); // 暂停时钟
- DS1302_Write_Byte(0x8C,TimeBuff[0]); // 年
- DS1302_Write_Byte(0x88,TimeBuff[1]); // 月
- DS1302_Write_Byte(0x86,TimeBuff[2]); // 日
- DS1302_Write_Byte(0x8A,TimeBuff[3]); // 星期
- DS1302_Write_Byte(0x84,TimeBuff[4]); // 时
- DS1302_Write_Byte(0x82,TimeBuff[5]); // 分
- DS1302_Write_Byte(0x80,TimeBuff[6]); // 秒
- DS1302_Write_Byte(0x80,TimeBuff[6]&0x7F); // 运行时钟
- DS1302_Write_Byte(0x8E,0x80); // 打开写保护
- }
- /*********************************************************/
- // 从DS1302读出时间数据
- /*********************************************************/
- void DS1302_Read_Time()
- {
- uchar i;
- TimeBuff[0]=DS1302_Read_Byte(0x8D); // 年
- TimeBuff[1]=DS1302_Read_Byte(0x89); // 月
- TimeBuff[2]=DS1302_Read_Byte(0x87); // 日
- TimeBuff[3]=DS1302_Read_Byte(0x8B); // 星期
- TimeBuff[4]=DS1302_Read_Byte(0x85); // 时
- TimeBuff[5]=DS1302_Read_Byte(0x83); // 分
- TimeBuff[6]=(DS1302_Read_Byte(0x81))&0x7F; // 秒
- for(i=0;i<7;i++) // BCD转十进制
- {
- TimeBuff[i]=(TimeBuff[i]/16)*10+TimeBuff[i]%16;
- }
- }
- /*********************************************************/
- // ADC0832的时钟脉冲
- /*********************************************************/
- void WavePlus()
- {
- _nop_();
- ADC_CLK = 1;
- _nop_();
- ADC_CLK = 0;
- }
- /*********************************************************/
- // 获取指定通道的A/D转换结果
- /*********************************************************/
- uchar Get_ADC0832()
- {
- uchar i;
- uchar dat1=0;
- uchar dat2=0;
-
- ADC_CLK = 0; // 电平初始化
- ADC_DAT = 1;
- _nop_();
- ADC_CS = 0;
- WavePlus(); // 起始信号
- ADC_DAT = 1;
- WavePlus(); // 通道选择的第一位
- ADC_DAT = 0;
- WavePlus(); // 通道选择的第二位
- ADC_DAT = 1;
-
- for(i=0;i<8;i++) // 第一次读取
- {
- dat1<<=1;
- WavePlus();
- if(ADC_DAT)
- dat1=dat1|0x01;
- else
- dat1=dat1|0x00;
- }
-
- for(i=0;i<8;i++) // 第二次读取
- {
- dat2>>= 1;
- if(ADC_DAT)
- dat2=dat2|0x80;
- else
- dat2=dat2|0x00;
- WavePlus();
- }
-
- _nop_(); // 结束此次传输
- ADC_CS = 1;
- if(dat1==dat2) // 返回采集结果
- return dat1;
- else
- return 0;
- }
- /*********************************************************/
- // 按键扫描(设置当前时间)
- /*********************************************************/
- void KeyScanf1()
- {
- if(KeySet_P==0)
- {
- LcdGotoXY(0,13); // 显示秒钟的冒号
- LcdWriteData(':');
- LcdWriteCmd(0x0f); // 启动光标闪烁
- LcdGotoXY(0,6); // 定位光标到年份闪烁
- DelayMs(10); // 延时等待,消除按键按下的抖动
- while(!KeySet_P); // 等待按键释放
- DelayMs(10); // 延时等待,消除按键松开的抖动
-
- // /* 调整年份 */
- // while(1)
- // {
- // if(KeyDown_P==0) // 如果减按键被下去
- // {
- // if(TimeBuff[0]>0) // 判断年份是否大于0
- // TimeBuff[0]--; // 是的话就减去1
- // LcdGotoXY(0,2); // 光标定位到年份的位置
- // LcdPrintNum(TimeBuff[0]); // 刷新显示改变后的年份
- // LcdGotoXY(0,3); // 定位光标到年份闪烁
- // DelayMs(300); // 延时0.3秒左右
- // }
- //
- // if(KeyUp_P==0) // 如果加按键被下去
- // {
- // if(TimeBuff[0]<99) // 判断年份是否小于99
- // TimeBuff[0]++; // 是的话就加上1
- // LcdGotoXY(0,2); // 光标定位到年份的位置
- // LcdPrintNum(TimeBuff[0]); // 刷新显示改变后的年份
- // LcdGotoXY(0,3); // 定位光标到年份闪烁
- // DelayMs(300); // 延时0.3秒左右
- // }
- //
- // if(KeySet_P==0)
- // {
- // break;
- // }
- // }
-
- LcdGotoXY(0,6); // 定位光标到月份闪烁
- DelayMs(10); // 延时等待,消除按键按下的抖动
- while(!KeySet_P); // 等待按键释放
- DelayMs(10); // 延时等待,消除按键松开的抖动
-
- /* 调整月份 */
- while(1)
- {
- if(KeyDown_P==0) // 如果减按键被下去
- {
- if(TimeBuff[1]>1) // 判断月份是否大于1
- TimeBuff[1]--; // 是的话就减去1
- LcdGotoXY(0,5); // 光标定位到月份的位置
- LcdPrintNum(TimeBuff[1]); // 刷新显示改变后的月份
- LcdGotoXY(0,6); // 定位光标到月份闪烁
- DelayMs(300); // 延时0.3秒左右
- }
-
- if(KeyUp_P==0) // 如果加按键被下去
- {
- if(TimeBuff[1]<12) // 判断月份是否小于12
- TimeBuff[1]++; // 是的话就加上1
- LcdGotoXY(0,5); // 光标定位到月份的位置
- LcdPrintNum(TimeBuff[1]); // 刷新显示改变后的月份
- LcdGotoXY(0,6); // 定位光标到月份闪烁
- DelayMs(300); // 延时0.3秒左右
- }
-
- if(KeySet_P==0)
- {
- break;
- }
- }
-
- LcdGotoXY(0,9); // 定位光标到日期闪烁
- DelayMs(10); // 延时等待,消除按键按下的抖动
- while(!KeySet_P); // 等待按键释放
- DelayMs(10); // 延时等待,消除按键松开的抖动
-
- /* 调整日期 */
- while(1)
- {
- if(KeyDown_P==0) // 如果减按键被下去
- {
- if(TimeBuff[2]>1) // 判断日期是否大于1
- TimeBuff[2]--; // 是的话就减去1
- LcdGotoXY(0,8); // 光标定位到日期的位置
- LcdPrintNum(TimeBuff[2]); // 刷新显示改变后的日期
- LcdGotoXY(0,9); // 定位光标到日期闪烁
- DelayMs(300); // 延时0.3秒左右
- }
-
- if(KeyUp_P==0) // 如果加按键被下去
- {
- if(TimeBuff[2]<31) // 判断日期是否小于31
- TimeBuff[2]++; // 是的话就加上1
- LcdGotoXY(0,8); // 光标定位到日期的位置
- LcdPrintNum(TimeBuff[2]); // 刷新显示改变后的日期
- LcdGotoXY(0,9); // 定位光标到日期闪烁
- DelayMs(300); // 延时0.3秒左右
- }
-
- if(KeySet_P==0)
- {
- break;
- }
- }
-
- LcdGotoXY(0,12); // 定位光标到小时闪烁
- DelayMs(10); // 延时等待,消除按键按下的抖动
- while(!KeySet_P); // 等待按键释放
- DelayMs(10); // 延时等待,消除按键松开的抖动
-
-
- /* 调整小时 */
- while(1)
- {
- if(KeyDown_P==0) // 如果减按键被下去
- {
- if(TimeBuff[4]>0) // 判断小时是否大于0
- TimeBuff[4]--; // 是的话就减去1
- LcdGotoXY(0,11); // 光标定位到小时的位置
- LcdPrintNum(TimeBuff[4]); // 刷新显示改变后的小时
- LcdGotoXY(0,12); // 定位光标到小时闪烁
- DelayMs(300); // 延时0.3秒左右
- }
-
- if(KeyUp_P==0) // 如果加按键被下去
- {
- if(TimeBuff[4]<23) // 判断小时是否小于23
- TimeBuff[4]++; // 是的话就加上1
- LcdGotoXY(0,11); // 光标定位到小时的位置
- LcdPrintNum(TimeBuff[4]); // 刷新显示改变后的小时
- LcdGotoXY(0,12); // 定位光标到小时闪烁
- DelayMs(300); // 延时0.3秒左右
- }
-
- if(KeySet_P==0)
- {
- break;
- }
- }
-
- LcdGotoXY(0,15); // 定位光标到分钟闪烁
- DelayMs(10); // 延时等待,消除按键按下的抖动
- while(!KeySet_P); // 等待按键释放
- DelayMs(10); // 延时等待,消除按键松开的抖动
-
- /* 调整分钟 */
- while(1)
- {
- if(KeyDown_P==0) // 如果减按键被下去
- {
- if(TimeBuff[5]>0) // 判断分钟是否大于0
- TimeBuff[5]--; // 是的话就减去1
- LcdGotoXY(0,14); // 光标定位到分钟的位置
- LcdPrintNum(TimeBuff[5]); // 刷新显示改变后的分钟
- LcdGotoXY(0,15); // 定位光标到分钟闪烁
- DelayMs(300); // 延时0.3秒左右
- }
-
- if(KeyUp_P==0) // 如果加按键被下去
- {
- if(TimeBuff[5]<59) // 判断分钟是否小于59
- TimeBuff[5]++; // 是的话就加上1
- LcdGotoXY(0,14); // 光标定位到分钟的位置
- LcdPrintNum(TimeBuff[5]); // 刷新显示改变后的分钟
- LcdGotoXY(0,15); // 定位光标到分钟闪烁
- DelayMs(300); // 延时0.3秒左右
- }
-
- if(KeySet_P==0)
- {
- break;
- }
- }
-
- /* 退出前的设置 */
- LcdWriteCmd(0x0C); // 关闭光标闪烁
- DS1302_Write_Time(); // 把新设置的时间值存入DS1302芯片
- DelayMs(10); // 延时等待,消除按键按下的抖动
- while(!KeySet_P); // 等待按键释放
- DelayMs(10); // 延时等待,消除按键松开的抖动
- }
- }
- uint temp,mm;uchar i;float f_temp;
- /*******************************************************
- 温度函数
- *******************************************************/
- void dsreset(void) //下边是温度获取子程衼E
- {
- uint i;
- ds=0;
- i=103;
- while(i>0)i--;
- ds=1;
- i=4;
- while(i>0)i--;
- }
- bit tempreadbit(void) //读一位
- {
- uint i;
- bit dat;
- ds=0;i++;
- ds=1;i++;i++;
- dat=ds;
- i=8;while(i>0)i--;
- return(dat);
- }
- uchar tempread(void) //获取温度
- {
- uchar i,j,dat;
- dat=0;
- for(i=1;i<=8;i++)
- {
- j=tempreadbit();
- dat=(j<<7)|(dat>>1);
- }
- return(dat);
- }
- void tempwritebyte(uchar dat) //写一个字节
- {
- uint i;
- uchar j;
- bit testb;
- for(j=1;j<=8;j++)
- {
- testb=dat&0x01;
- dat=dat>>1;
- if(testb)
- {
- ds=0;
- i++;i++;
- ds=1;
- i=8;while(i>0)i--;
- }
- else
- {
- ds=0;
- i=8;while(i>0)i--;
- ds=1;
- i++;i++;
- }
- }
- }
- void tempchange(void) //温度转换
- {
- dsreset();
- delay(1);
- tempwritebyte(0xcc);
- tempwritebyte(0x44);
- }
- uint get_temp() //获取温度
- {
- uchar a,b;
- dsreset();
- delay(1);
- tempwritebyte(0xcc);
- tempwritebyte(0xbe);
- a=tempread();
- b=tempread();
- temp=b;
- temp<<=8;
- temp=temp|a;
- f_temp=temp*0.0625;
- temp=f_temp*10+0.5;
- f_temp=f_temp+0.05;
- return temp;
- }
- /***********************************/
- /*********************************************************/
- // 按键扫描(设置窗帘的动作)
- /*********************************************************/
- void KeyScanf2()
- {
- if(KeySet2_P==0)
- {
- xsflag++;
- if(xsflag>=2)
- xsflag=0;
- while(!KeySet2_P);
- }
- if(xsflag==1)
- {
- // /* 光照强度的设置 */
- LcdWriteCmd(0x0C); // 关闭光眮E了?
- LcdGotoXY(0,0); // 光眮Eㄎ?
- LcdPrintStr(" Light Set "); // 显示第1行内容
- LcdGotoXY(1,0); // 光眮Eㄎ?
- LcdPrintStr(" "); // 显示第2行内容
- LcdGotoXY(1,7); // 光眮Eㄎ?
- LcdPrintNum(gLight); // 显示窗帘的光线控制强度阈值
-
- while(1)
- {
- if(KeySet2_P==0)
- {
- xsflag++;
- if(xsflag>=3)
- xsflag=0;
- while(!KeySet2_P);
- }
- if(xsflag==1)
- {
- if(KeyDown_P==0) // 如果减按紒E幌氯?
- {
- if(gLight>0) // 判断光线阈值是否大于0
- gLight--; // 是的话就减去1
- LcdGotoXY(1,7); // 光眮Eㄎ?
- LcdPrintNum(gLight); // 刷新显示改变后的光线阈值
- DelayMs(300); // 延时0.3脕E笥?
- }
-
- if(KeyUp_P==0) // 如果加按紒E幌氯?
- {
- if(gLight<99) // 判断光线阈值是否小于59
- gLight++; // 是的话就加上1
- LcdGotoXY(1,7); // 光眮Eㄎ?
- LcdPrintNum(gLight); // 刷新显示改变后的光线阈值
- DelayMs(300); // 延时0.3脕E笥?
- }
- }
- if(xsflag==2)
- {
- // 设置温度
- LcdWriteCmd(0x0C); // 关闭光眮E了?
- LcdGotoXY(0,0); // 光眮Eㄎ?
- LcdPrintStr(" Wendu Set "); // 显示第1行内容
- LcdGotoXY(1,0); // 光眮Eㄎ?
- LcdPrintStr(" "); // 显示第2行内容
- LcdGotoXY(1,7); // 光眮Eㄎ?
- LcdPrintNum(wDu); // 显示窗帘的光线控制强度阈值
- while(!KeySet2_P);
- while(1)
- {
- LcdGotoXY(1,7); // 光眮Eㄎ?
- LcdPrintNum(wDu); // 显示窗帘的光线控制强度阈值
- if(KeyDown_P==0) // 如果减按紒E幌氯?
- {
- if(wDu>0) // 判断光线阈值是否大于0
- wDu--; // 是的话就减去1
- DelayMs(300); // 延时0.3脕E笥?
- }
-
- if(KeyUp_P==0) // 如果加按紒E幌氯?
- {
- if(wDu<99) // 判断光线阈值是否小于59
- wDu++; // 是的话就加上1
- DelayMs(300); // 延时0.3脕E笥?
- }
- if(KeySet2_P==0)
- {
- break;
- }
- }
- }
- if(xsflag==0)
- {
- break;
- }
- }
- // /* 退出前的设置 */
- LcdShowInit(); // 液晶显示内容初始化
- DelayMs(10); // 延时等待,消除按紒E聪碌亩抖?
- while(!KeySet2_P); // 等待按紒E头?
- DelayMs(10);
- }
- }
- /*********************************************************/
- // 按键扫描(模式切换)
- /*********************************************************/
- void KeyScanf3()
- {
- if(KeyMode_P==0)
- {
- DelayMs(10);
- if(KeyMode_P==0)
- {
- gMode++; // 切换到下一模式
- if(gMode==4) // 如果到尽头了
- gMode=1; // 回到第一种模式
- LcdGotoXY(1,0); // 光标定位
- LcdPrintMode(gMode); // 显示模式
-
- while(!KeyMode_P); // 等待按键是否
- }
- }
- }
- /*********************************************************/
- // 开窗
- /*********************************************************/
- void Open()
- {
- uint i,j;
- for(j=0;j<255;j++) // 控制步进电机正转
- {
- for(i=0;i<4;i++)
- {
- P2=Clock[i];
- DelayMs(3);
- }
- }
- Led_P=0;
- }
- /*********************************************************/
- // 关窗
- /*********************************************************/
- void Close()
- {
- uint i,j;
- for(j=0;j<255;j++) // 控制步进电机反转
- {
- for(i=0;i<4;i++)
- {
- P2=AntiClock[i];
- DelayMs(3);
- }
- }
- Led_P=1;
- }
- /*********************************************************/
- // 主函数
- /*********************************************************/
- void main()
- {
- uchar light;
-
- LcdInit(); // 执行液晶初始化
- DS1302_Init(); // 时钟芯片的初始化
- LcdShowInit(); // 液晶显示内容的初始化
- if(DS1302_Read_Byte(0x81)>=128) // 判断时钟芯片是否正在运行
- {
- DS1302_Write_Time(); // 如果没有,则初始化一个时间
- }
- while(1)
- {
- tempchange();
- t=get_temp();
- if(t>=0&&t<=1250) //温度合法范围,不在这个范围就是没有获取到合适的值
- {
- wd=t/10;
- }
- DS1302_Read_Time(); // 获取当前时钟芯片的时间,存在数组time_buf中
- FlashTime(); // 刷新时间显示
- light=Get_ADC0832(); // 读取光照强度
- light=light/2.5; // 缩小光照检测结果(在0-99)
- if(light>99) // 如果大于99
- light=99; // 则依然保持99
- LcdGotoXY(1,14); // 光标定位
- LcdPrintNum(light); // 显示光照强度
-
- KeyScanf1(); // 按键扫描(时间的设置)
- KeyScanf2(); // 按键扫描(阈值的设置)
- KeyScanf3(); // 按键扫描(模式切换)
-
- /*手动控制模式*/
- if(gMode==1)
- {
- if(closeflag==1)
- {
- if(Led_P==0) // 如果窗帘当前是打开的
- {
- closeflag=0;
- Close(); // 则光标窗帘
- }else
- closeflag=0;
- }
- if(KeyDown_P==0) // 如果关窗帘键按下了
- {
- if(Led_P==0) // 如果窗帘当前是打开的
- {
- Close(); // 则光标窗帘
- }
- }
- if(openflag==1)
- {
- if(Led_P==1) // 如果窗帘当前是关闭的
- {
- openflag=0;
- Open(); // 则打开窗帘
- }else{
- openflag=0;
- }
-
- }
- if(KeyUp_P==0) // 如果开窗帘键按下了
- {
- if(Led_P==1) // 如果窗帘当前是关闭的
- {
- Open(); // 则打开窗帘
- }
- }
- }
-
-
- /*光线控制模式*/
- if(gMode==2)
- {
- if(light<gLight) // 当前光线小于设置的阈值
- {
- if(Led_P==0) // 如果窗帘当前是打开的
- {
- Close(); // 则光标窗帘
- }
- }
- else // 当前光线大于或等于设置的阈值
- {
- if(Led_P==1) // 如果窗帘当前是关闭的
- {
- Open(); // 则打开窗帘
- }
- }
- }
-
- if(gMode==3)
- {
- if(wd<wDu) // 当前温度小于设置的阈值
- {
- if(Led_P==0) // 如果窗帘当前是打开的
- {
- Close(); // 则关闭窗帘
- }
- }
- else // 当前温度大于或等于设置的阈值
- {
- if(Led_P==1) // 如果窗帘当前是关闭的
- {
- Open(); // 则打开窗帘
- }
- }
- }
-
- DelayMs(100); // 延时0.1秒
- }
- }
复制代码
所有资料51hei提供下载:
04、单片机程序(先解压后查看).rar
(311 KB, 下载次数: 204)
|