代碼電路參考百度多個(gè)作者修改而成,如有侵犯,請(qǐng)聯(lián)系本人,立即刪除。
本作品僅供學(xué)習(xí)參考,不喜勿噴,退出即可。
主要功能:
紅外遙控,開燈關(guān)燈,調(diào)風(fēng)扇的速度。
自動(dòng)調(diào)光,自動(dòng)溫度調(diào)速。
蜂鳴器報(bào)警風(fēng)速極限。液晶屏顯示溫度數(shù)值與光敏電阻電壓數(shù)值。
資料內(nèi)含代碼與電路
本次課題得名稱主要是由***提出,夏天天氣很熱宿舍風(fēng)扇轉(zhuǎn)得又不快,然后要按時(shí)熄燈。工作又沒做完,想要有一個(gè)涼快得夏天,還要自動(dòng)得調(diào)光系統(tǒng)方便學(xué)習(xí),并且保護(hù)眼睛。那這就是舒適得桌面環(huán)境了。所以就有這個(gè)課題。
電路分析: 主要功能: 紅外遙控,開燈關(guān)燈,調(diào)風(fēng)扇的速度。自動(dòng)調(diào)光,自動(dòng)溫度調(diào)速。 蜂鳴器報(bào)警風(fēng)速極限。液晶屏顯示溫度數(shù)值與光敏電阻電壓數(shù)值。 整體模塊: 
詳細(xì)分析: 
電源模塊:由12v轉(zhuǎn)5v,使用7805降壓芯片。 復(fù)位電路、晶振電路:這兩個(gè)電路加上STC89C52RC構(gòu)成控制電路,即51單片機(jī)最小系統(tǒng)。 顯示模塊:lcd 1602液晶顯示屏,其電阻RM是調(diào)背光亮度,顯示溫度,電壓,模式。 溫度模塊:使用DS18B20,對(duì)溫度進(jìn)行采集。 光敏電阻:對(duì)光線強(qiáng)弱控制。 A/D模塊:使用A/D C0832模數(shù)轉(zhuǎn)換芯片,對(duì)光敏測(cè)量出光敏電阻阻值。 電機(jī)驅(qū)動(dòng)模塊:使用L298N電路穩(wěn)壓。 紅外遙控:使用紅外傳感器,實(shí)現(xiàn)對(duì)電路共能得控制。 可以改進(jìn)的地方: 硬件布局方面: 飛線應(yīng)該減少,可以將兩個(gè)板子合成一個(gè)板子。 軟件:應(yīng)該實(shí)現(xiàn)程序優(yōu)化。
物品清單:
完成效果圖: 實(shí)物圖: 
Protuse實(shí)現(xiàn):
單片機(jī)源程序如下: - /*-------------------------------------------------------------------
- 程序名稱: 在1602液晶上顯示出DS18B20的溫度與光敏電阻電壓
- 自動(dòng)功能: | 手動(dòng)功能:
- 根據(jù)溫度的數(shù)值控制風(fēng)速 | 紅外控制風(fēng)速
- 根據(jù)光的亮暗控制光線的強(qiáng)弱 | 紅外控制燈的亮暗
- -------------------------------------------------------------------*/
- #include <reg52.h>
- #include <intrins.h>
- #define uint unsigned int
- #define uchar unsigned char
- #define P0 P0
- sbit ds=P2^2; //定義DS18B20通信端口
- sbit lcd_rs = P3^5; //定義LCD控制端口
- sbit lcd_rw = P3^6;
- sbit lcd_en = P3^4;
- sbit IN1=P1^0; //電機(jī)
- sbit M_pwm=P1^1;
- sbit fm=P2^4;
- sbit ir=P3^2; //紅外
- sbit led=P1^2; //臺(tái)燈
- sbit led1=P2^0; //風(fēng)扇指示燈
- sbit led2=P2^1; //臺(tái)燈指示燈
- sbit CS=P2^7; //AD芯片的定義口
- sbit CLK=P2^5;
- sbit DIO=P2^6;
- uint temp,temp1; //溫度值定義
- bit flag; //溫度中的標(biāo)志位
- uchar code mun_to_char[] = {"0123456789ABCDEF"}; //定義數(shù)字跟ASCII碼的關(guān)系
- uchar data lcd1602_line1[]={"MODE:0 LIGHT:0 "}; //LCD1602液晶第一行
- uchar data lcd1602_line2[]={"TEMP:00.0 U:0.0 "}; //LCD1602液晶第二行。注意:用空格補(bǔ)位
-
- uint AD_val; //電壓值
- uchar irtime; //用于計(jì)數(shù)時(shí)間
- uchar ircode[4]; //儲(chǔ)存數(shù)據(jù)碼
- uchar irdata[33]; //1引導(dǎo)碼 8位客戶1 8位客戶2 8位操作碼 8位操作反碼
- bit startflag,irok,irprosok; //設(shè)置中斷標(biāo)志位 接收成功標(biāo)志位 處理成功標(biāo)志
- uchar bitnum; //位數(shù)值
- uchar num,pwm1,n,num2;
- uint pwm2;
- /*------------------------------------------------------------------------------
- 延時(shí)函數(shù)
- ------------------------------------------------------------------------------*/
- void delayus(uint t) //微秒級(jí)的延時(shí)函數(shù)
- {
- while(t--);
- }
- void delayms(uint ms) //毫秒級(jí)的延時(shí)函數(shù)
- {
- uchar i;
- while(ms--)
- {
- for(i=0;i<120;i++);
- }
- }
- /*------------------------------------------------------------------------------
- AD轉(zhuǎn)換
- ------------------------------------------------------------------------------*/
- unsigned char AD(void)
- {
- unsigned char i,dat;
- CS=1; //一個(gè)轉(zhuǎn)換周期開始
- CLK=0; //第一個(gè)脈沖做準(zhǔn)備
- CS=0; //CS置0,片選有效
- DIO=1; //規(guī)定的起始信號(hào)
- CLK=1; //第一個(gè)脈沖
- CLK=0; //第一個(gè)脈沖下降沿,此前DIO必須是高電平
- DIO=1; //DIO置1,通道選擇信號(hào)
- CLK=1; //第二個(gè)脈沖,第2、3個(gè)脈沖下沉之前,DI必須跟別的輸入兩位數(shù)據(jù)用于選則通道
- CLK=0; //第二個(gè)脈沖下降沿
- DIO=0; //DI置0,選擇通道0
- CLK=1; //第三個(gè)脈沖
- CLK=0; //第三個(gè)脈沖下降沿
- DIO=1; //第三個(gè)脈沖下沉之后,輸入端DIO失去作用,應(yīng)置1
- CLK=1; //第四個(gè)脈沖
- for(i=0;i<8;i++)
- {
- CLK=1; //第四個(gè)脈沖
- CLK=0;
- dat<<=1; //將下面儲(chǔ)存的低位數(shù)據(jù)向右移
- dat|=(unsigned char)DIO; //將輸出數(shù)據(jù)DIO通過或運(yùn)算儲(chǔ)存在dat最低位
- }
-
- CS=1; //片選無效
- return dat; //將讀出的數(shù)據(jù)返回
- }
- /*------------------------------------------------------------------------------
- 蜂鳴器
- ------------------------------------------------------------------------------*/
- void bee()
- {
- fm=0;
- delayms(100);
- fm=1;
- delayms(100);
- }
- /*------------------------------------------------------------------------------
- 紅外遙控
- ------------------------------------------------------------------------------*/
- void timer0init(void)//定時(shí)器0初始化 256*(1/12m)*12=0.256ms
- {
- TMOD=0x02;//定時(shí)器0工作方式2,TH0是重裝值,TL0是初值
- TH0=0x00; //重載值
- TL0=0x00; //初始化值
- ET0=1; //開中斷
- TR0=1;
- }
- /////////////////////////////////////////////////////////////////////
- //定時(shí)器0中斷服務(wù)函數(shù)
- /////////////////////////////////////////////////////////////////////
- void tim0_isr (void) interrupt 1 using 1 //定時(shí)器0中斷服務(wù)函數(shù)
- {
- irtime++; //用于計(jì)數(shù)2個(gè)下降沿之間的時(shí)間
- num++;
- num2++;
- if(num>62)
- {
- num=0;
- }
- if(num<=pwm1)
- {
- M_pwm=1;
- }
- else
- {
- M_pwm=0;
- }
- }
- void int0init(void) //外部中斷0初始化
- {
- IT0 = 1; //指定外部中斷0下降沿觸發(fā),INT0 (P3.2)
- EX0 = 1; //使能外部中斷
- EA = 1; //開總中斷
- }
- void int0 () interrupt 0 //外部中斷0服務(wù)函數(shù)
- {
- if(startflag)
- {
- if(irtime>32&&irtime<63) //8-16ms
- {
- bitnum=0;
- }
- irdata[bitnum]=irtime;
- irtime=0;
- bitnum++;
- if(bitnum==33)
- {
- bitnum=0;
- irok=1;
- }
- }
- else
- {
- irtime=0;
- startflag=1;
- }
- }
- /*------------------------------------------------------------------------------
- 紅外碼值處理
- ------------------------------------------------------------------------------*/
- void irpros(void) // 紅外碼值處理
- {
- uchar mun,k,i,j;
- k=1;
- for(j=0;j<4;j++)
- {
- for(i=0;i<8;i++)
- {
- mun=mun>>1;
- if(irdata[k]>6)
- {
- mun=mun | 0x80;
- }
- k++;
- }
- ircode[j]=mun;
- }
- irprosok=1;
- }
- /*------------------------------------------------------------------------------
- PWM控制
- ------------------------------------------------------------------------------*/
-
- void temp_pwm()
- {
-
- if(n==1)
- {
- lcd1602_line1[6] = mun_to_char[1];
- if(pwm1<62)
- {
- IN1=1;
- pwm1++;
- delayms(100);
- }
- else
- {
- bee();
- }
-
- }
- if(n==3)
- {
- lcd1602_line1[6] =mun_to_char[2] ;
- if(pwm1>1)
- {
- IN1=1;
- pwm1--;
- delayms(100);
- }
- else
- {
- bee();
- }
- }
- if(n==5) //停止
- {
-
- led1=1;
- IN1=0;
- pwm1=0;
- }
- if(n==2)
- {
- pwm1=31;
- delayms(100);
- }
- }
- void led_pwm()
- {
- if(n==6)
- {
- lcd1602_line1[14] =mun_to_char[1] ;
- if(pwm2<800)
- {
- pwm2++;
- delayms(100);
- }
- }
- else
- {
- bee();
- }
- if(n==7)
- {
- lcd1602_line1[14] =mun_to_char[2] ;
- if(pwm2>1)
- {
- pwm2--;
- delayms(100);
- }
- }
- else
- {
- bee();
- }
- }
- /*------------------------------------------------------------------------------
- 紅外鍵值處理
- ------------------------------------------------------------------------------*/
- void ir_work(void) //紅外鍵值處理
- {
- switch(ircode[2]) //判斷操作碼(第三個(gè)數(shù)碼值)
- {
-
- case 0x19:bee();break; // 0
- case 0x45:n=1;temp_pwm();break; //加速 1
- case 0x47:n=3;temp_pwm();break; //減速 3
- case 0x46:n=2;temp_pwm();break; //復(fù)位 2
- case 0x1c:n=4;break; //自動(dòng)模式 ok
- case 0x44:n=5;break; //關(guān)閉點(diǎn)擊 4
- case 0x07:led=0;break; //關(guān)燈 8
- case 0x15:led=1;break; //開燈 7
- case 0x08:n=6;led_pwm();break; //調(diào)亮 <
- case 0x5a:n=7;led_pwm();break; //調(diào)亮 >
- case 0x16:n=8;break; //自動(dòng) *
- default:break;
- }
- irprosok=0; //處理完成標(biāo)志
- }
- /*------------------------------------------------------------------------------
- 單總線初始化函數(shù)(溫度)
- ------------------------------------------------------------------------------*/
- void ds_reset() //單總線初始化函數(shù)
- {
- ds=1;
- delayus(5);
- ds=0;
- delayus(80);
- ds=1;
- delayus(14);
- if(ds==0)
- flag=1;
- else
- flag=0;
- delayus(20);
- }
- /*------------------------------------------------------------------------------
- 讀時(shí)隙(即位讀。┖瘮(shù) (溫度)
- ------------------------------------------------------------------------------*/
- bit ds_read_bit() //讀時(shí)隙(即位讀。┖瘮(shù)
- {
- bit dat;
- ds=0;
- _nop_();
- _nop_();
- ds=1;
- _nop_();
- dat=ds;
- delayus(10);
- return dat;
- }
- /*------------------------------------------------------------------------------
- 讀一個(gè)字節(jié)函數(shù)
- ------------------------------------------------------------------------------*/
- uchar ds_read_byte() //讀一個(gè)字節(jié)函數(shù)
- {
- uchar i,j,k;
- for(i=0;i<8;i++)
- {
- j=ds_read_bit();
- k=(j<<7)|(k>>1);
- }
- return k;
- }
- /*------------------------------------------------------------------------------
- 寫一個(gè)字節(jié)函數(shù)
- ------------------------------------------------------------------------------*/
- void ds_write_byte(uchar dat) //寫一個(gè)字節(jié)函數(shù)
- {
- uchar i;
- for(i=0;i<8;i++)
- {
- ds=0;
- _nop_();
- ds=dat&0x01;
- delayus(6);
- ds=1;
- dat=dat>>1;
- }
- delayus(6);
- }
- /*------------------------------------------------------------------------------
- 讀取溫度函數(shù)
- ------------------------------------------------------------------------------*/
- uint read_temperature() //讀取溫度函數(shù)
- {
-
- uchar a,b;
- ds_reset();
- EA=0;
- ds_write_byte(0xcc);
- ds_write_byte(0xbe);
- a=ds_read_byte();
- b=ds_read_byte();
- temp=b;
- temp=temp<<8;
- temp=temp|a;
- temp=temp*0.0625*10+0.5;
- EA=1;
- return temp;
- }
- /*------------------------------------------------------------------------------
- 1602液晶顯示
- ------------------------------------------------------------------------------*/
- void lcd_delay(uchar x) //LCD1602 延時(shí)
- {
- uint i,j;
- for(i=x;i>0;i--)
- {
- for(j=120;j>0;j--);
- }
- }
- /*------------------------------------------------------------------------------
- LCD1602 命令字寫入
- ------------------------------------------------------------------------------*/
- void write_com(uchar com) //LCD1602 命令字寫入
- {
- lcd_rs = 0;
- lcd_rw = 0;
- lcd_en = 0;
- P0 = com;
- lcd_en = 1;
- lcd_delay(5);
- lcd_en = 0;
- }
- /*------------------------------------------------------------------------------
- LCD1602 初始化
- ------------------------------------------------------------------------------*/
- void lcd_init() //LCD1602 初始化
- {
- write_com(0x38);
- write_com(0x08);
- write_com(0x01);
- write_com(0x06);
- write_com(0x0c); //開顯示,不顯示光標(biāo)
- }
- /*------------------------------------------------------------------------------
- LCD1602 字符寫入
- ------------------------------------------------------------------------------*/
- void lcd_char_write(uchar x_pos,y_pos,lcd_dat) //LCD1602 字符寫入
- {
- x_pos &= 0x0f; // X位置范圍 0~15
- y_pos &= 0x01; // Y位置范圍 0~ 1
- if(y_pos==1) x_pos += 0x40;
- x_pos += 0x80;
- write_com(x_pos);
- lcd_delay(5);
- lcd_rs = 1;
- lcd_rw = 0;
- lcd_en = 0;
- P0 = lcd_dat;
- lcd_en = 1;
- lcd_en = 0;
- P0 = 0xff; //釋放數(shù)據(jù)端口
- }
- void main()
- {
- uchar i;
- float adnum;
- lcd_en=0; //關(guān)閉1602液晶使能,防止1602數(shù)據(jù)端影響單片機(jī)P0口輸出
- led=0;
- P0=0xff;
- int0init(); //外部中斷初始化
- timer0init(); //定時(shí)器初始化
- pwm2=400;
- num=0;
- pwm1=31;
- lcd_init(); //LCD1602 初始化
-
- while(1)
- {
- ds_reset(); //單總線初始化
- ds_write_byte(0xcc); //跳線ROM
- ds_write_byte(0x44); //啟動(dòng)溫度傳換
- AD_val=AD(); //讀取電壓的數(shù)值
- temp1=read_temperature(); //讀取當(dāng)前溫度值
- lcd1602_line2[5] = mun_to_char[temp1/100]; //把當(dāng)前溫度分解送到1602顯示
- lcd1602_line2[6] = mun_to_char[temp1%100/10];
- lcd1602_line2[8] = mun_to_char[temp1%10];
- lcd1602_line2[12] = mun_to_char[AD_val/51];
- lcd1602_line2[14] = mun_to_char[((AD_val%51)*100/51)/10];
- lcd1602_line2[15] = mun_to_char[((AD_val%51)*100/51)%10];
- for(i=0;i<16;i++) lcd_char_write(i,0,lcd1602_line1[i]);
- for(i=0;i<16;i++) lcd_char_write(i,1,lcd1602_line2[i]);
- //
- // if(temp1>260&&temp1<350) IN1=1;
- // else IN1=0;
- if(n==4)
- {
- lcd1602_line1[5] = mun_to_char[1];
- lcd1602_line1[6] =mun_to_char[0] ;
- led1=0;
- if(temp1>250&&temp1<280) pwm1=31;
- if(temp1>290&&temp1<310) pwm1=40;
- if(temp1>310&&temp1<350) pwm1=50;
- if(temp1>10&&temp1<200) pwm1=20;
- }
- if(n==5)
- {
- lcd1602_line1[5] = mun_to_char[2];
- lcd1602_line1[6] =mun_to_char[0] ;
- led1=1;
- IN1=0;
- pwm1=2;
- }
- adnum=(AD_val/51);
- if(n==8)
- {
- if(adnum>3&&adnum<5){led=1;led2=0;}
- if(adnum>0&&adnum<2){led=0;led2=1;}
- }
-
- if(irok==1) //如果紅外編碼接收好了,
- {
- irpros(); //進(jìn)行紅外碼值處理。
- irok=0;
- }
-
- if(irprosok==1) //如果紅外碼值處理好后,
- {
- ir_work(); //進(jìn)行工作處理。
- }
- }
- }
復(fù)制代碼
word格式的以上資料51hei提供下載:
|