久久久久久久999_99精品久久精品一区二区爱城_成人欧美一区二区三区在线播放_国产精品日本一区二区不卡视频_国产午夜视频_欧美精品在线观看免费
標題:
單片機控制風扇程序
[打印本頁]
作者:
楊小楊
時間:
2018-5-14 15:38
標題:
單片機控制風扇程序
單片機源程序如下:
//宏定義
#define uchar unsigned char
#define uint unsigned int
//包含頭文件
#include <reg52.h>
#include <18b20.h>
#include <stdlib.h>
#include <intrins.h>
#include <eeprom52.h>
#define Imax 14000 //此處為晶振為11.0592時的取值,
#define Imin 8000 //如用其它頻率的晶振時,
#define Inum1 1450 //要改變相應的取值。
#define Inum2 700
#define Inum3 3000
sbit K1=P1^1;
sbit K2=P1^2;
sbit K3=P1^3; //按鍵定義
sbit PWM=P3^6; //PWM輸出
sbit BUZZ=P1^4; //蜂鳴器控制腳
sbit RSD=P2^0; //熱釋電引腳
unsigned char Im[4]={0x00,0x00,0x00,0x00};
uchar displaydata[4]; //顯示暫存數組
//全局變量
char f,dang,count,count1,a_a; //檔位
unsigned long m,Tc;
unsigned char IrOK; //定義紅外工作變量
void jisuan(); //聲明計算函數
uchar mode;
char sec_b=0;
bit flag_b=0;
uint TH,TL; //上下限變量
uchar baif,suiji;
unsigned char code duan[17]={
0x5F,0x44,0x9D,0xD5,0xC6,0xD3,0xDB,0x47,0xDF,0xD7, 0xCF,0xDA,0x98,0xDC,0x9B,0x8B}; //接線從高到低:g c dp d e b f a
//0、1、2、3、4、5、6、7、8、9、A、b、c、d、E、F的顯示碼 //
unsigned char code wei[8]={ //數碼管的位選
0xef,0xdf,0xbf,0x7f,0xfe,0xfd,0xfb,0xf7};
uchar code zhuanhuan[4]={10,5,3,0};//轉換數組
void write_eeprom() //內部eeprom寫函數
{
SectorErase(0x2000); //清空
SectorErase(0x2c00);
SectorErase(0x2e00);
byte_write(0x2c00,TH/256);
byte_write(0x2c01,TH%256);
byte_write(0x2c02,TL/256);
byte_write(0x2c03,TL%256); //將上下限數據保存到eeprom
byte_write(0x2c04,dang);
byte_write(0x2c05,mode);
byte_write(0x2060,0x01);
}
/******************把數據從單片機內部eeprom中讀出來*****************/
void read_eeprom()
{
mode = byte_read(0x2c05);
dang = byte_read(0x2c04);
TH = byte_read(0x2c00)*256+byte_read(0x2c01);
TL = byte_read(0x2c02)*256+byte_read(0x2c03);
a_a = byte_read(0x2060);
}
/**************開機自檢eeprom初始化*****************/
void init_eeprom()
{
a_a = byte_read(0x2060);
if(a_a != 1) //新的單片機初始單片機內問eeprom
{
a_a = 1;
write_eeprom(); //保存數據
}
}
void delay(uint z) //延時函數
{
uint z1,z2;
for(z1=0;z1<z;z1++)
for(z2=0;z2<110;z2++);
}
void display() //顯示函數
{
uchar i;
if(mode==0) //無極變速
{
displaydata[0]=0x00;
displaydata[1]=duan[disdata[1]];
displaydata[2]=duan[disdata[2]]|0x20;
displaydata[3]=duan[disdata[3]];
}
else if(mode==1) //上限
{
displaydata[0]=0xce; //H 11001110
displaydata[1]=duan[TH%1000/100];
displaydata[2]=duan[TH%100/10]|0x20;
displaydata[3]=duan[TH%10];
}
else if(mode==2) //下限
{
displaydata[0]=0x1a; //L 00111000
displaydata[1]=duan[TL%1000/100];
displaydata[2]=duan[TL%100/10]|0x20;
displaydata[3]=duan[TL%10];
}
else if(mode==3) //檔位0到3檔
{
displaydata[0]=duan[dang];
displaydata[1]=0x80; //01000000
displaydata[2]=duan[disdata[1]];
displaydata[3]=duan[disdata[2]];
}
else if(mode==4)
{
displaydata[0]=0xda; //b自然風
displaydata[1]=duan[disdata[1]];
displaydata[2]=duan[disdata[2]]|0x20;
displaydata[3]=duan[disdata[3]];
}
for(i=0;i<4;i++) //循環4次顯示4位數碼管
{
P2=wei[i]; //選中位
P0=displaydata[i]; //送入顯示碼
delay(3); //延時
P2=0xff; //關閉位
P0=0x00; //復位顯示碼
}
}
void key() //按鍵函數
{
if(K1==0||(Im[2]==0x47&&IrOK==1)) //按鍵1按下或者遙控器上的按鍵按下
{
delay(5); //延時去抖
if(K1==0||(Im[2]==0x47&&IrOK==1)) //再次判斷按鍵按下
{
BUZZ=0;
delay(20);
BUZZ=1; //按鍵音
mode++; //模式加
if(mode>4) //模式加到大于4
mode=0; //模式清零
// Im[2]=0;
IrOK=0; //變量清零
write_eeprom(); //寫入eeprom數據
while(!K1); //按鍵釋放
}
}
if(K2==0||(Im[2]==0x40&&IrOK==1))
{
delay(5);
if(K2==0||(Im[2]==0x40&&IrOK==1))
{
BUZZ=0;
delay(20);
BUZZ=1;
if(mode==1) //模式等于1時
{
TH++; //上限加
if(TH>999) //上限加到大于99.9度
TH=TL+1; //上限等于下限加一
}
else if(mode==2) //模式等于2時
{
TL++; //下限加
if(TL>=TH) //下限加到大于等于上限
TL=TH-1; //下限等于上限減一
}
else if(mode==3) //模式等于3時
{
dang++; //檔位加一
if(dang>3) //檔位大于3時
dang=0; //檔位清零
}
Im[2]=0;
IrOK=0; //紅外變量清零
write_eeprom(); //寫入eeprom數據
while(!K2); //按鍵釋放
}
}
if(K3==0||(Im[2]==0x19&&IrOK==1))
{
delay(5);
if(K3==0||(Im[2]==0x19&&IrOK==1))
{
BUZZ=0;
delay(20);
BUZZ=1;
if(mode==1)
{
TH--;
if(TH<=TL)
TH=TL+1;
}
else if(mode==2)
{
TL--;
if(TL>=TH)
TL=TH-1;
}
else if(mode==3)
{
dang--;
if(dang<0)
dang=3;
}
Im[2]=0;
IrOK=0;
write_eeprom();
while(!K3);
}
}
}
void jisuan() //計算函數
{
if((mode==0||mode==1||mode==2)&&RSD==1) //模式0、1、2并且熱釋電有信號時
{
if(tvalue<=TL) //溫度小于下限時
PWM=1; //關閉輸出,占空比0%
else if(tvalue>=TH) //溫度大于等于上限
PWM=0; //打開輸出,占空比100%
else //其他狀態時
{
baif=(((tvalue-TL)*50)/(TH-TL)); //占空比控制變量計算得到
//計算方法:當前溫度減去下限值乘以5再除以上限減下限
if(count1>baif) //根據變量判斷占空比大小
PWM=1; //關閉風扇
else
PWM=0; //打開風扇
}
}
else if(mode==3) //模式3時
{
if(count1>(zhuanhuan[dang]*5)) //根據檔位計算出占空比
PWM=0;
else
PWM=1;
}
else if((mode==4&&flag_b==0)&&RSD==1) //模式4時,熱釋電有信號
{
suiji=rand(); //讀隨機函數
suiji=suiji%23; //隨機數計算
if(10>suiji) //判斷隨機數是否小于10
PWM=0; //輸出開
else //隨機數大于等于10
PWM=1; //輸出關
flag_b=1; //變量置1
}
if(RSD==0&&mode!=3) //熱釋電沒有信號時
PWM=1; //關閉輸出
}
void main() //主函數
{
uint count; //定義變量
EA=1; //打開中斷總開關
EX1=1; //打開外部中斷1
IT1=1; //下降沿有效
TMOD=0x11; //定時器工作方式
TR0=0; //關閉T0
TH0=0;
TL0=0; //初值0
ET1=1; //T1允許中斷
TR1=1; //T1打開中斷
TH1=0xfc;
TL1=0x18; //T1初值1ms
mode=0; //初始模式0
TH=300;
TL=200; //上下限初始值
init_eeprom(); //初始化eeprom
read_eeprom(); //讀取eeprom數據
while(1) //進入循環
{
jisuan(); //計算函數
count++; //變量加
if(count>200) //加到大于200
{
count=0; //清零
TR1=0; //關閉定時器T1
read_wendu(); //讀取溫度
TR1=1; //打開定時器T1
}
jisuan(); //計算函數
display(); //顯示函數
key(); //按鍵函數
jisuan(); //計算函數
}
}
void timer1() interrupt 3 //定時器T1工作函數
{
TH1=0xfc;
TL1=0x18; //重新賦初值
count1++; //加
if(count1>50)
{
count1=0;
if(mode==4&&flag_b==1) //模式等于4時,變量為1
{
sec_b++; //變量加
if(sec_b>=8) //加到8時
{
sec_b=0; //清零
flag_b=0; //清零
}
}
}
}
void intersvr1(void) interrupt 2 //紅外工作函數
{
TR0=1;
Tc=TH0*256+TL0;//提取中斷時間間隔時長
TH0=0;
TL0=0; //定時中斷重新置零
if((Tc>Imin)&&(Tc<Imax))
{
m=0;
f=1;
return;
} //找到啟始碼
if(f==1)
{
if(Tc>Inum1&&Tc<Inum3)
{
Im[m/8]=Im[m/8]>>1|0x80; m++;
}
if(Tc>Inum2&&Tc<Inum1)
{
Im[m/8]=Im[m/8]>>1; m++; //取碼
}
if(m==32)
{
m=0;
f=0;
if(Im[2]==~Im[3])
{
IrOK=1;
TR0=0;
}
else
{
IrOK=0; //取碼完成后判斷讀碼是否正確
}
}
//準備讀下一碼
}
}
Ds18b20
sbit DQ=P1^0;//ds18b20與單片機連接口
uchar data disdata[5];
uint tvalue;//溫度值
uchar tflag;//溫度正負標志
/******************************ds1820程序***************************************/
void delay_18B20(uchar k)//延時1微秒
{
while(k--);
}
void ds1820rst()/*ds1820復位*/
{
DQ = 1; //DQ復位
delay_18B20(4); //延時
DQ = 0; //DQ拉低
delay_18B20(100); //精確延時大于480us
DQ = 1; //拉高
delay_18B20(40);
}
uchar ds1820rd()/*讀數據*/
{
unsigned char i=0;
unsigned char dat = 0;
for (i=8;i>0;i--)
{ DQ = 0; //給脈沖信號
dat>>=1;
DQ = 1; //給脈沖信號
if(DQ)
dat|=0x80;
delay_18B20(10);//延時106us
}
return(dat);
}
void ds1820wr(uchar wdata)/*寫數據*/
{
unsigned char i=0;
for (i=8; i>0; i--)
{
DQ = 0;
DQ = wdata&0x01;
delay_18B20(10);//延時106us
DQ = 1;
wdata>>=1;
}
}
uint read_wendu()/*讀取溫度值并轉換*/
{
uchar a,b;
ds1820rst();
ds1820wr(0xcc);//*跳過讀序列號*/
ds1820wr(0x44);//*啟動溫度轉換*/
ds1820rst();
ds1820wr(0xcc);//*跳過讀序列號*/
ds1820wr(0xbe);//*讀取溫度*/
a=ds1820rd();
b=ds1820rd();
tvalue=b;
tvalue<<=8;
tvalue=tvalue|a;
if(tvalue<0x0fff)
tflag=0;
else
{
tvalue=~tvalue+1;
tflag=1;
}
tvalue=tvalue*(0.625);//溫度值擴大10倍,精確到1位小數
disdata[1]=tvalue%1000/100;//十位數
disdata[2]=tvalue%100/10;//個位數
disdata[3]=tvalue%10;//小數位
return(tvalue);
}
eeprom
#ifndef _EEPROM52_H_
#define _EEPROM52_H_
/********STC89C51扇區分布*******
第一扇區:1000H--11FF
第二扇區:1200H--13FF
第三扇區:1400H--15FF
第四扇區:1600H--17FF
第五扇區:1800H--19FF
第六扇區:1A00H--1BFF
第七扇區:1C00H--1DFF
第八扇區:1E00H--1FFF
*****************/
/********STC89C52扇區分布*******
第一扇區:2000H--21FF
第二扇區:2200H--23FF
第三扇區:2400H--25FF
第四扇區:2600H--27FF
第五扇區:2800H--29FF
第六扇區:2A00H--2BFF
第七扇區:2C00H--2DFF
第八扇區:2E00H--2FFF
*****************/
#define RdCommand 0x01 //定義ISP的操作命令
#define PrgCommand 0x02
#define EraseCommand 0x03
#define Error 1
#define Ok 0
#define WaitTime 0x01 //定義CPU的等待時間
sfr ISP_DATA=0xe2; //寄存器申明
sfr ISP_ADDRH=0xe3;
sfr ISP_ADDRL=0xe4;
sfr ISP_CMD=0xe5;
sfr ISP_TRIG=0xe6;
sfr ISP_CONTR=0xe7;
/* ================ 打開 ISP,IAP 功能 ================= */
void ISP_IAP_enable(void)
{
EA = 0; /* 關中斷 */
ISP_CONTR = ISP_CONTR & 0x18; /* 0001,1000 */
ISP_CONTR = ISP_CONTR | WaitTime; /* 寫入硬件延時 */
ISP_CONTR = ISP_CONTR | 0x80; /* ISPEN=1 */
}
/* =============== 關閉 ISP,IAP 功能 ================== */
void ISP_IAP_disable(void)
{
ISP_CONTR = ISP_CONTR & 0x7f; /* ISPEN = 0 */
ISP_TRIG = 0x00;
EA = 1; /* 開中斷 */
}
/* ================ 公用的觸發代碼 ==================== */
void ISPgoon(void)
{
ISP_IAP_enable(); /* 打開 ISP,IAP 功能 */
ISP_TRIG = 0x46; /* 觸發ISP_IAP命令字節1 */
ISP_TRIG = 0xb9; /* 觸發ISP_IAP命令字節2 */
_nop_();
}
/* ==================== 字節讀 ======================== */
unsigned char byte_read(unsigned int byte_addr)
{
EA = 0;
ISP_ADDRH = (unsigned char)(byte_addr >> 8);/* 地址賦值 */
ISP_ADDRL = (unsigned char)(byte_addr & 0x00ff);
ISP_CMD = ISP_CMD & 0xf8; /* 清除低3位 */
ISP_CMD = ISP_CMD | RdCommand; /* 寫入讀命令 */
ISPgoon(); /* 觸發執行 */
ISP_IAP_disable(); /* 關閉ISP,IAP功能 */
EA = 1;
return (ISP_DATA); /* 返回讀到的數據 */
}
/* ================== 扇區擦除 ======================== */
void SectorErase(unsigned int sector_addr)
{
unsigned int iSectorAddr;
iSectorAddr = (sector_addr & 0xfe00); /* 取扇區地址 */
ISP_ADDRH = (unsigned char)(iSectorAddr >> 8);
ISP_ADDRL = 0x00;
ISP_CMD = ISP_CMD & 0xf8; /* 清空低3位 */
ISP_CMD = ISP_CMD | EraseCommand; /* 擦除命令3 */
ISPgoon(); /* 觸發執行 */
ISP_IAP_disable(); /* 關閉ISP,IAP功能 */
}
/* ==================== 字節寫 ======================== */
void byte_write(unsigned int byte_addr, unsigned char original_data)
{
EA = 0;
// SectorErase(byte_addr);
ISP_ADDRH = (unsigned char)(byte_addr >> 8); /* 取地址 */
ISP_ADDRL = (unsigned char)(byte_addr & 0x00ff);
ISP_CMD = ISP_CMD & 0xf8; /* 清低3位 */
ISP_CMD = ISP_CMD | PrgCommand; /* 寫命令2 */
ISP_DATA = original_data; /* 寫入數據準備 */
ISPgoon(); /* 觸發執行 */
ISP_IAP_disable(); /* 關閉IAP功能 */
EA =1;
}
#endif
復制代碼
chengxu.doc
2018-5-14 15:38 上傳
點擊文件名下載附件
下載積分: 黑幣 -5
68 KB, 下載次數: 15, 下載積分: 黑幣 -5
歡迎光臨 (http://www.zg4o1577.cn/bbs/)
Powered by Discuz! X3.1
主站蜘蛛池模板:
国产一区精品
|
国产成人小视频
|
中文字幕一区二区在线观看
|
国产免费视频
|
夜夜撸av
|
九九热视频这里只有精品
|
日日骚网
|
www.一区二区三区.com
|
欧美日韩中文在线
|
亚洲精品一区二区网址
|
精品国产乱码久久久久久蜜臀
|
日本亚洲欧美
|
天天射影院
|
亚洲一区二区三区免费观看
|
91欧美
|
亚洲一区中文字幕在线观看
|
欧美aa在线
|
午夜无码国产理论在线
|
黄色大片免费看
|
久久久国产视频
|
亚州精品天堂中文字幕
|
在线看片国产精品
|
亚洲精品国产一区
|
视频在线一区二区
|
精品久久久久香蕉网
|
久久er精品
|
欧美日韩专区
|
天天草视频
|
中文字幕一区二区三区四区
|
国产区一区二区三区
|
免费亚洲一区二区
|
中日av
|
在线免费观看色
|
欧美在线a
|
中文字幕亚洲视频
|
成人精品免费视频
|
99精品国产一区二区青青牛奶
|
caoporn免费在线视频
|
免费在线观看一区二区三区
|
天天碰夜夜操
|
国产乱码精品一区二区三区忘忧草
|