久久久久久久999_99精品久久精品一区二区爱城_成人欧美一区二区三区在线播放_国产精品日本一区二区不卡视频_国产午夜视频_欧美精品在线观看免费
標題:
單片機智能窗戶程序與Proteus仿真設計 光敏電阻自動控制與時間控制
[打印本頁]
作者:
不負初心螞蟻
時間:
2022-12-10 16:33
標題:
單片機智能窗戶程序與Proteus仿真設計 光敏電阻自動控制與時間控制
整個系統以AT89C52單片機為核心器件,配合電阻電容晶振等器件,構成單片機的最小系統。其它個模塊圍繞著單片機最小系統展開。其中包括,顯示設備使用1602液晶,可以同時顯示年、月、日、時、分、控制模式、光照強度等基本信息;時鐘模塊采用DS1302芯片,初始化之后,就會開始運行計算時間,單片機只需進行時間信息的讀取即可;光照檢測電路采用光敏電阻和模數轉換芯片ADC0832,將模擬量數字化并顯示出來;窗簾使用步進電機進行代替模擬,同時配有一個LED燈用來指示窗簾當前的開關狀態;本設計還有5個按鍵作為操作輸入設備,可以對當前時間進行調整設置和設置窗簾開關時間和光控閾值等;最后是供電采用常用的USB 5V進行供電。智能窗簾控制系統具有以下幾個基本功能:
(1)手動控制:該功能是根據用戶的需求通過按鍵進行窗簾的開關,此功能可以使窗簾的開閉處于任何一種狀態;
(2)光照自動控制:系統可以根據用戶設定的光照強度值通過感光器采集光照自動開光窗簾;
(3)時間控制:此功能是根據用戶設定的時間一次性開關窗簾。
(4)可以通過按鍵是上面三種控制模式循環切換。
仿真原理圖如下(proteus仿真工程文件可到本帖附件中下載)
51hei.gif
(188.59 KB, 下載次數: 18)
下載附件
2022-12-12 03:33 上傳
單片機源程序如下:
#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^2; // 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; // 指示燈
uchar gMode=1; // 1是手動模式,2是時間自動模式,3是亮度自動模式
uchar OpenHour = 18; // 開啟窗簾的小時
uchar OpenMinute = 20; // 開啟窗簾的分鐘
uchar CloseHour = 10; // 關閉窗簾的小時
uchar CloseMinute = 30; // 關閉窗簾的分鐘
uchar gLight = 40; // 窗簾開關的閾值
uchar code Clock[]={0x10,0x90,0x80,0xc0}; // 步進電機順時針旋轉數組
uchar code AntiClock[]={0x80,0x90,0x10,0x30}; // 步進電機逆時針旋轉數組
uchar code Clock1[]={0x10,0x90,0x80,0xc0};
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
/*********************************************************/
// 按鍵掃描(設置當前時間)
/*********************************************************/
void KeyScanf1()
{
if(KeySet_P==0)
{
LcdGotoXY(0,13); // 顯示秒鐘的冒號
LcdWriteData(':');
LcdWriteCmd(0x0f); // 啟動光標閃爍
LcdGotoXY(0,3); // 定位光標到年份閃爍
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); // 延時等待,消除按鍵松開的抖動
}
}
/*********************************************************/
// 按鍵掃描(設置窗簾的動作)
/*********************************************************/
void KeyScanf2()
{
if(KeySet2_P==0)
{
LcdGotoXY(0,0); // 光標定位
LcdPrintStr(" OpenTime : "); // 顯示第1行內容
LcdGotoXY(1,0); // 光標定位
LcdPrintStr("CloseTime : "); // 顯示第2行內容
LcdGotoXY(0,10); // 光標定位
LcdPrintNum(OpenHour); // 顯示開啟窗簾的小時
LcdGotoXY(0,13); // 光標定位
LcdPrintNum(OpenMinute); // 顯示開啟窗簾的分鐘
LcdGotoXY(1,10); // 光標定位
LcdPrintNum(CloseHour); // 顯示關閉窗簾的小時
LcdGotoXY(1,13); // 光標定位
LcdPrintNum(CloseMinute); // 顯示關閉窗簾的分鐘
LcdWriteCmd(0x0f); // 啟動光標閃爍
LcdGotoXY(0,11); // 定位光標
DelayMs(10); // 延時等待,消除按鍵按下的抖動
while(!KeySet2_P); // 等待按鍵釋放
DelayMs(10); // 延時等待,消除按鍵松開的抖動
/* 調整開啟的小時 */
while(1)
{
if(KeyDown_P==0) // 如果減按鍵被下去
{
if(OpenHour>0) // 判斷小時是否大于0
OpenHour--; // 是的話就減去1
LcdGotoXY(0,10); // 光標定位
LcdPrintNum(OpenHour); // 刷新顯示改變后的小時
LcdGotoXY(0,11); // 定位光標
DelayMs(300); // 延時0.3秒左右
}
if(KeyUp_P==0) // 如果加按鍵被下去
{
if(OpenHour<23) // 判斷小時是否小于23
OpenHour++; // 是的話就加上1
LcdGotoXY(0,10); // 光標定位
LcdPrintNum(OpenHour); // 刷新顯示改變后的小時
LcdGotoXY(0,11); // 定位光標
DelayMs(300); // 延時0.3秒左右
}
if(KeySet2_P==0)
{
break;
}
}
LcdGotoXY(0,14); // 定位光標
DelayMs(10); // 延時等待,消除按鍵按下的抖動
while(!KeySet2_P); // 等待按鍵釋放
DelayMs(10); // 延時等待,消除按鍵松開的抖動
/* 調整開啟的分鐘 */
while(1)
{
if(KeyDown_P==0) // 如果減按鍵被下去
{
if(OpenMinute>0) // 判斷分鐘是否大于0
OpenMinute--; // 是的話就減去1
LcdGotoXY(0,13); // 光標定位
LcdPrintNum(OpenMinute); // 刷新顯示改變后的分鐘
LcdGotoXY(0,14); // 定位光標
DelayMs(300); // 延時0.3秒左右
}
if(KeyUp_P==0) // 如果加按鍵被下去
{
if(OpenMinute<59) // 判斷分鐘是否小于59
OpenMinute++; // 是的話就加上1
LcdGotoXY(0,13); // 光標定位
LcdPrintNum(OpenMinute); // 刷新顯示改變后的分鐘
LcdGotoXY(0,14); // 定位光標
DelayMs(300); // 延時0.3秒左右
}
if(KeySet2_P==0)
{
break;
}
}
LcdGotoXY(1,11); // 定位光標
DelayMs(10); // 延時等待,消除按鍵按下的抖動
while(!KeySet2_P); // 等待按鍵釋放
DelayMs(10); // 延時等待,消除按鍵松開的抖動
/* 調整關閉的小時 */
while(1)
{
if(KeyDown_P==0) // 如果減按鍵被下去
{
if(CloseHour>0) // 判斷小時是否大于0
CloseHour--; // 是的話就減去1
LcdGotoXY(1,10); // 光標定位
LcdPrintNum(CloseHour); // 刷新顯示改變后的小時
LcdGotoXY(1,11); // 定位光標
DelayMs(300); // 延時0.3秒左右
}
if(KeyUp_P==0) // 如果加按鍵被下去
{
if(CloseHour<23) // 判斷小時是否小于23
CloseHour++; // 是的話就加上1
LcdGotoXY(1,10); // 光標定位
LcdPrintNum(CloseHour); // 刷新顯示改變后的小時
LcdGotoXY(1,11); // 定位光標
DelayMs(300); // 延時0.3秒左右
}
if(KeySet2_P==0)
{
break;
}
}
LcdGotoXY(1,14); // 定位光標
DelayMs(10); // 延時等待,消除按鍵按下的抖動
while(!KeySet2_P); // 等待按鍵釋放
DelayMs(10); // 延時等待,消除按鍵松開的抖動
/* 調整關閉的分鐘 */
while(1)
{
if(KeyDown_P==0) // 如果減按鍵被下去
{
if(CloseMinute>0) // 判斷分鐘是否大于0
CloseMinute--; // 是的話就減去1
LcdGotoXY(1,13); // 光標定位
LcdPrintNum(CloseMinute); // 刷新顯示改變后的分鐘
LcdGotoXY(1,14); // 定位光標
DelayMs(300); // 延時0.3秒左右
}
if(KeyUp_P==0) // 如果加按鍵被下去
{
if(CloseMinute<59) // 判斷分鐘是否小于59
CloseMinute++; // 是的話就加上1
LcdGotoXY(1,13); // 光標定位
LcdPrintNum(CloseMinute); // 刷新顯示改變后的分鐘
LcdGotoXY(1,14); // 定位光標
DelayMs(300); // 延時0.3秒左右
}
if(KeySet2_P==0)
{
break;
}
}
DelayMs(10); // 延時等待,消除按鍵按下的抖動
while(!KeySet2_P); // 等待按鍵釋放
DelayMs(10); // 延時等待,消除按鍵松開的抖動
/* 光照強度的設置 */
LcdWriteCmd(0x0C); // 關閉光標閃爍
LcdGotoXY(0,0); // 光標定位
LcdPrintStr(" Light Set "); // 顯示第1行內容
LcdGotoXY(1,0); // 光標定位
LcdPrintStr(" "); // 顯示第2行內容
LcdGotoXY(1,7); // 光標定位
LcdPrintNum(gLight); // 顯示窗簾的光線控制強度閾值
while(1)
{
if(KeyDown_P==0) // 如果減按鍵被下去
{
if(gLight>0) // 判斷光線閾值是否大于0
gLight--; // 是的話就減去1
LcdGotoXY(1,7); // 光標定位
LcdPrintNum(gLight); // 刷新顯示改變后的光線閾值
DelayMs(300); // 延時0.3秒左右
}
if(KeyUp_P==0) // 如果加按鍵被下去
{
if(gLight<99) // 判斷光線閾值是否小于59
gLight++; // 是的話就加上1
LcdGotoXY(1,7); // 光標定位
LcdPrintNum(gLight); // 刷新顯示改變后的光線閾值
DelayMs(300); // 延時0.3秒左右
}
if(KeySet2_P==0)
{
break;
}
}
/* 退出前的設置 */
LcdShowInit(); // 液晶顯示內容初始化
DelayMs(10); // 延時等待,消除按鍵按下的抖動
while(!KeySet2_P); // 等待按鍵釋放
DelayMs(10); // 延時等待,消除按鍵松開的抖動
}
}
/*********************************************************/
// 按鍵掃描(模式切換)
/*********************************************************/
void KeyScanf3()
{
if(KeyMode_P==0)
{
gMode++; // 切換到下一模式
if(gMode==4) // 如果到盡頭了
gMode=1; // 回到第一種模式
LcdGotoXY(1,0); // 光標定位
LcdPrintMode(gMode); // 顯示模式
DelayMs(10); // 去除按鍵按下的抖動
while(!KeyMode_P); // 等待按鍵是否
DelayMs(10); // 去除按鍵松開的抖動
}
}
/*********************************************************/
// 開窗
/*********************************************************/
void Open()
{
uint i;
for(i=0;i<4;i++)
{
P2=Clock[i];
DelayMs(250);
}
Led_P=0;
}
/*********************************************************/
// 關窗
/*********************************************************/
void Close()
{
uint i;
for(i=0;i<4;i++)
{
P2=AntiClock[i];
DelayMs(250);
}
Led_P=1;
}
/*********************************************************/
// 主函數
/*********************************************************/
void main()
{
uchar light;
LcdInit(); // 執行液晶初始化
DS1302_Init(); // 時鐘芯片的初始化
LcdShowInit(); // 液晶顯示內容的初始化
if(DS1302_Read_Byte(0x81)>=128) // 判斷時鐘芯片是否正在運行
{
DS1302_Write_Time(); // 如果沒有,則初始化一個時間
}
while(1)
{
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(KeyDown_P==0) // 如果關窗簾鍵按下了
{
if(Led_P==0) // 如果窗簾當前是打開的
{
Close(); // 則關閉窗簾
}
}
if(KeyUp_P==0) // 如果開窗簾鍵按下了
{
if(Led_P==1) // 如果窗簾當前是關閉的
{
Open(); // 則打開窗簾
}
}
}
/*時間控制模式*/
if(gMode==2)
{
if((TimeBuff[4]==CloseHour)&&(TimeBuff[5]==CloseMinute)&&(TimeBuff[6]==0)) // 如果到了關窗簾的時間
{
if(Led_P==0) // 如果窗簾當前是打開的
{
Close(); // 則關閉窗簾
}
}
if((TimeBuff[4]==OpenHour)&&(TimeBuff[5]==OpenMinute)&&(TimeBuff[6]==0)) // 如果到了開窗簾的時間
{
if(Led_P==1) // 如果窗簾當前是關閉的
{
Open(); // 則打開窗簾
}
}
}
/*光線控制模式*/
if(gMode==3)
{
if(light<gLight) // 當前光線小于設置的閾值
{
if(Led_P==0) // 如果窗簾當前是打開的
{
Close(); // 則關閉窗簾
}
}
else // 當前光線大于或等于設置的閾值
{
if(Led_P==1) // 如果窗簾當前是關閉的
{
Open(); // 則打開窗簾
}
}
}
DelayMs(100); // 延時0.1秒
}
}
復制代碼
所有資料51hei附件下載:
仿真程序.7z
(89.02 KB, 下載次數: 57)
2022-12-12 03:37 上傳
點擊文件名下載附件
下載積分: 黑幣 -5
作者:
heicad
時間:
2022-12-12 03:42
好資料,51黑有你更精彩!!!
作者:
gemxie
時間:
2025-1-15 11:00
好資料,51黑有你更精彩!!!
作者:
allen98
時間:
2025-3-21 10:41
感謝up的資料,學習了
作者:
allen98
時間:
2025-3-21 10:41
感謝UP的資料,學習了哦
歡迎光臨 (http://m.zg4o1577.cn/bbs/)
Powered by Discuz! X3.1
主站蜘蛛池模板:
激情五月激情综合网
|
精品一区二区三区视频
|
欧美一级网站
|
婷婷91
|
久久免费国产
|
国产午夜精品一区二区三区视频
|
国产精品久久网
|
私库av在线
|
亚洲视频一区在线观看
|
亚洲av毛片
|
www.精品国产
|
麻豆中文字幕
|
亚洲欧美综合网
|
亚洲性天堂
|
国产欧美一区二区三区视频在线观看
|
日韩精品影院
|
日韩视频免费在线观看
|
四虎影院www
|
亚洲专区在线
|
免费观看av
|
中文字幕无人区二
|
国产三级在线观看视频
|
日日夜夜狠狠
|
黄色一级片免费看
|
亚洲免费播放
|
不用播放器的av
|
超碰91在线
|
中文字幕日韩视频
|
久久精品毛片
|
欧美在线综合
|
国产精品美女久久久久久久久
|
国产精品久久久久久无人区
|
成人片网址
|
久久国内精品
|
一级片国产
|
欧洲一级毛片
|
美日韩在线
|
久久久久久免费
|
国产精品久久一区
|
欧美一区二区免费
|
欧美精品一区二
|