/*--------------------------------------
快熱式熱水器程序
MCU AT89C51 XAL 12MHz
--------------------------------------*/
//#pragma SRC
#include
#include
#include
void delay(unsigned int); //延時函數
void display(void); //顯示函數
unsigned char keysCAN(void); //按鍵掃描處理函數
void heatCTRl(void); //加熱控制函數
void temptest(void); //測溫函數
sbit swkey=P1^0; //開關鍵
sbit upkey=P1^1; //加熱檔位“+”鍵
sbit downkey=P1^2; //加熱檔位“-”鍵
sbit buzz=P1^05; //蜂鳴器輸出端
sbit triac=P1^6; //可控硅觸發信號輸出端
sbit relay=P1^7; //繼電器控制信號輸出端
sbit LED1=P2^5; //加熱檔位指示燈1
sbit led2=P2^6; //加熱檔位指示燈2
sbit led3=P2^7; //加熱檔位指示燈3
signed char data ctemp; //當前測得水溫寄存器
unsigned char data dispram[2]={0x10,0x10}; //顯示區緩存
unsigned char data heatpower,px0count; //加熱檔位寄存器、外中斷0計數器
bit tempov,t0tst,testok; //超溫標志、測溫開始標志、測溫完成標志
/*----------------------------------------------
主函數 void main(void)
無參數,無返回值
循環調用顯示、鍵掃描、溫度檢測、加熱控制函數
----------------------------------------------*/
void main(void)
{
unsigned char i,j;
ctemp=15; //初始化水溫寄存器
heatpower=5; //初始化加熱檔位為5當
tempov=0; //清除超溫標志
swkey=0; //默認開關鍵被按下,進入待機狀態
TMOD=0x11; //設定T0和T1工作方式為16位定時器
TCON=0x05; //設置外中斷0和1為下降沿觸發
IP=0x01; //設置外中斷0優先
IE=0x80; //打開總中斷
while (1)
{
i=1;
do{
for (j=0;j<100;j++) //循環100次約0.5s
{
if (keyscan()) i=6; //如果有鍵按下,顯示當前檔位3s
display(); //調用顯示函數一次約4ms
heatctrl(); //調用加熱控制函數
}//end for (b=0;b<100;b++)
temptest(); //每0.5s進行一次測溫
} while (--i); //通過改變循環次數i的大小決定是否刷新顯示
j=abs(ctemp); //取溫度絕對值
dispram[1]=j%10; //取個位數送顯示
j/=10; //取十位數
dispram[0]=j?j:0x11; //送顯示(帶滅零)
}//end while (1)
}
/*--------------------------------------
延時函數 void delay(unsigned int dt)
參數:dt,無返回值
延時時間=dt*500機器周期
--------------------------------------*/
void delay(unsigned int dt)
{
register unsigned char bt; //定義寄存器變量
for (; dt; dt--)
for (bt=250; --bt; ); //此句編譯時以“DJNZ”實現,250*2=500機器周期
}
/*--------------------------------------
顯示函數 void display(void)
無參數,無返回值
兩位共陽數碼管掃描顯示
--------------------------------------*/
void display(void)
{
unsigned char code table[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,\
0x88,0x83,0xc6,0xa1,0x86,0x8e,0xbf,0xff};
unsigned char i,a;
a=0xfe; //位選賦初值
for (i=0; i<2; i++) //循環掃描兩位數碼管
{
P2|=0x1f; //清除位選
P0=table[dispram[i]]; //送顯示段碼
P2&=a; //選通一位
delay(4); //延時2ms
a=_crol_(a,1); //改變位選字
P0=0xff; //消影
}
}
/*----------------------------------------------------------
按鍵掃描處理函數 unsigned char keyscan(void)
無參數,返回值:無符號字符型,無鍵按下為0,有鍵按下為其它
影響全局變量:heatpower
----------------------------------------------------------*/
unsigned char keyscan(void)
{
unsigned char i,ch;
if (upkey==0) //“+”鍵
{
buzz=0; //打開蜂鳴器(發出按鍵音)
for (i=0;i<5;i++) display(); //延時消抖
buzz=1; //關閉蜂鳴器
if (heatpower<9) heatpower++; //檔位加一
dispram[0]=0;
dispram[1]=heatpower; //顯示當前檔位
while (upkey==0) display(); //等待鍵釋放
return (1); //返回有鍵按下
}
else if (downkey==0) //“-”鍵
{
buzz=0; //打開蜂鳴器(發出按鍵音)
for (i=0;i<5;i++) display(); //延時消抖
buzz=1; //關閉蜂鳴器
if (heatpower>0) heatpower--; //檔位減一
dispram[0]=0;
dispram[1]=heatpower; //顯示當前檔位
while (downkey==0) display(); //等待鍵釋放
return (2); //返回有鍵按下
}
else if (swkey==0) //開關鍵
{
buzz=0; //打開蜂鳴器(發出按鍵音)
for (i=0;i<30;i++) display(); //延時消抖
buzz=1; //關閉蜂鳴器
swkey=1; //置位開關鍵
while (swkey==0) display(); //等待鍵釋放
ch=IE; //暫存中斷控制字IE
IE=0x00; //禁止中斷
P0=0xff;
P1=0xff;
P2=0xff; //清除端口輸出
dispram[0]=0x10;
dispram[1]=0x10; //顯示“--”
display();
while (1)
{
while (swkey) display(); //等待開關鍵按下
buzz=0; //打開蜂鳴器(發出按鍵音)
for (i=0;i<10;i++) display();//延時消抖
buzz=1; //關閉蜂鳴器
if (swkey==0) break; //確認開關鍵被按下
}
while (swkey==0) display(); //等待鍵釋放
IE=ch; //還原中斷控制字IE
return (0); //返回無鍵按下
}
else return (0); //無任何鍵按下時由此返回
}
/*--------------------------------------
加熱控制函數 void heatctrl(void)
無參數,無返回值
判斷是否加熱、加熱功率及檔位指示燈處理
--------------------------------------*/
void heatctrl(void)
{
if (!tempov) //當沒有超溫標志時
{
relay=0; //接通繼電器
buzz=1; //關閉蜂鳴器
switch (heatpower) //判斷加熱檔位
{
case 0: {EX1=0;ET1=0;triac=1;led1=1;led2=1;led3=1;break;}//0檔不加熱,指示燈不亮
case 1:
case 2:
case 3:
case 4: {led1=0;led2=1;led3=1;EX1=1;break;} //1~4檔1號指示等亮
case 5:
case 6:
case 7:
case 8: {led1=0;led2=0;led3=1;EX1=1;break;} //5~8檔1號、2號指示燈亮
case 9: {EX1=0;ET1=0;led1=0;led2=0;led3=0;triac=0;break;} //9檔全功率,指示燈全亮
}
}
else //當有超溫標志時
{
relay=1; //斷開繼電器
EX1=0; ET1=0; triac=1; //關閉可控硅
buzz=0; //蜂鳴報警
}
}
/*--------------------------------------
測溫函數 void temptest(void)
無參數,無返回值,
影響全局變量:ctemp,tempov
測量并查表計算溫度,判斷是否超溫
--------------------------------------*/
void temptest(void)
{
signed char temp,tempmin,tempmax;
unsigned int t0rig;
unsigned int code temptab[]={0x6262,0x61eb,0x6171,0x60f7,0x6047,0x5ff7,0x5f6e,0x5eef,0x5e53,0x5dbe,0x5d4b,0x5ca5,0x5c17,\
0x5b6b,0x5ada,0x5a5c,0x599b,0x58ff,0x5869,0x57b0,0x570d,0x5663,0x55c6,0x550e,0x5444,0x5396,\
0x52dd,0x5240,0x5189,0x50b0,0x5005,0x4f20,0x4e69,0x4db1,0x4cef,0x4c42,0x4b64,0x4aaa,0x49e1,\
0x48fc,0x4847,0x476c,0x46b1,0x4604,0x4503,0x4449,0x4356,0x4299,0x41c0,0x40ce,0x3ff0,0x3f2b,\
0x3e33,0x3d86,0x3ca6,0x3bd2,0x3b26,0x3a39,0x3973,0x38a6,0x37ef,0x373f,0x3687,0x35c3,0x3507,\
0x3487,0x33bc,0x32ed,0x324f,0x319e,0x3106,0x3053,0x2fa6,0x2f2a,0x2e88,0x2e00,0x2d63,0x2cd6,\
0x2c65,0x2bae,0x2b28,0x2a97,0x2a07,0x298e,0x2914,0x287a,0x280d,0x278a,0x2703,0x2687,0x2626,\
0x25e5,0x256d,0x24ee,0x2489,0x2414,0x23bc,0x2356,0x22d9,0x2278,0x2203}; //溫度頻率表
px0count=2; //測頻中斷函數參數
t0tst=1; //置測頻程序開始標志
EX0=1; //打開測頻外中斷
testok=0; //清除測頻程序完成標志
while (!testok) display(); //等待測試完成
t0rig=(unsigned int)TH0<<8|TL0; //字節合成字
tempmin=0; //以下是二分查表法計算溫度值
tempmax=100; //tempmin和tempmax為溫度表的范圍
while (1)
{
temp=(tempmax+tempmin)/2; //假定當前溫度為最大值與最小值之中點值
if (t0rig==temptab[temp]) break; //若實際值等于假定值結束查找
else if (t0rig>temptab[temp]) tempmax=temp;//若實際值大于假定值,減小查找范圍的最大值
else tempmin=temp; //若實際值小于假定值,增大查找范圍的最小值
if (tempmax-tempmin<=1) //若查找范圍已縮小到1度之間,
{ //判斷實際值更接近哪個端點
if (temptab[tempmax]+temptab[tempmin]>2*t0rig) temp=tempmax;//接近最大值取最大值
else temp=tempmin; //接近最小值取最小值
break; //結束查找
}
}
ctemp=temp; //刷新當前溫度寄存器
if (temp>65) tempov=1; //如果溫度超過65度置位超溫標志
else if (temp<45) tempov=0; //當溫度回落到45度以下時清除超溫標志
}
/*------------------------------------------
測溫頻率測試函數 void tempFrequency(void)
使用外部X0中斷,寄存器組1
測出溫度——頻率轉換電路的頻率
------------------------------------------*/
void tempfrequency(void) interrupt 0 using 1
{
if (--px0count) return; //找齊起點或計數
if (t0tst) //如果是起點
{
t0tst=0; //清除測頻開始標志
px0count=100; //取100個方波為一次測頻
TH0=0;
TL0=0; //清除計時器T0
TR0=1; //開始計時
}
else //如果是終點
{
TR0=0; //停止計時
EX0=0; //停止測頻外中斷
testok=1; //置位測頻完成標志
}
}
/*--------------------------------------
加熱控制過〇檢測函數 void pass0(void)
使用外部X1中斷,寄存器組2
檢測過〇點,給定時器T1賦初值
--------------------------------------*/
void pass0(void) interrupt 2 using 2
{
unsigned char code powertab[]={0xd8,0xf0,0xe2,0x63,0xe5,0x25,0xe8,0x3e,0xeb,0x16,0xed,0xda,0xf0,0xb2,0xf3,0xcb,0xf7,0x8d,0xf7,0x8d};//10個功率檔位的可控硅導通角延時參數表
TH1=powertab[2*heatpower]-1;
TL1=powertab[2*heatpower+1]; //市電過零后,根據當前設置的檔位給定時器T1賦延時參數
ET1=1; //允許定時器T1中斷
TR1=1; //打開定時器T1
}
/*------------------------------------------
可控硅觸發信號控制函數 void triaCCtrl(void)
使用定時器T1中斷,寄存器組3
向可控硅送出觸發信號
------------------------------------------*/
void triacctrl(void) interrupt 3 using 3
{
register unsigned char i;
triac=0; //輸出可控硅導通信號
ET1=0; //關閉定時器T1中斷
TR1=0; //終止定時器運行
for (i=0;i<2;i++); //延時,保證導通信號有足夠的寬度
triac=1; //完成可控硅導通信號
}
上一篇:AT89C2051簡易正弦波\三角波\方波發生器
下一篇:51單片機超聲測距程序
推薦閱讀
史海拾趣
Delkin Devices深知品質是企業生存和發展的基石。因此,公司始終將品質控制放在重要位置,通過引進先進的生產設備和技術、建立完善的品質管理體系等方式,確保產品質量的穩定性和可靠性。同時,Delkin Devices還注重可持續發展,積極采取環保措施和節能減排技術,努力降低生產過程中的能耗和排放。這些努力不僅提升了公司的品牌形象和競爭力,也為社會和環境的可持續發展做出了積極貢獻。
CUI公司在發展過程中,始終注重市場拓展和品牌建設。公司通過與國內外知名企業的合作,不斷拓寬產品應用領域,提升品牌影響力。同時,公司還積極參加各類行業展會和交流活動,與同行和客戶建立緊密的合作關系,為公司的長期發展奠定了堅實的基礎。
人才是企業最寶貴的資源。HI Microwave高度重視人才培養和團隊建設,通過引進和培養高素質的技術人才和管理人才,不斷提升企業的核心競爭力。公司建立了完善的人才激勵機制和培訓體系,鼓勵員工不斷學習和創新。同時,公司還注重營造和諧、開放的企業文化氛圍,激發員工的積極性和創造力。這些措施為公司的持續發展提供了有力的人才保障和智力支持。
EBG RESISTORS LLC公司始終將品質管理放在首位。他們建立了嚴格的質量控制體系,確保每一款產品的性能和質量都符合客戶要求。同時,公司還鼓勵員工提出改進意見,不斷優化生產流程和產品性能。這種持續改進的精神使得EBG RESISTORS LLC公司的產品在市場上始終保持著領先地位。
前言 3G終端電源管理的主要策略之一,就是設計轉化效率高的線性調壓器(因其低壓降特性稱為LDO)。盡管開關型調制器的轉化效率較高,但由于線性調壓器在電壓輸出端產生的噪聲最小,而且LDO極小的紋波可以避免噪聲使手機發射器產生的RF載波儒變 ...… 查看全部問答∨ |
剛接觸Stellaris,關于USB的例程只有看到BULK的,而且是使用庫文件編寫好的,看了源程序,進行了修改,編譯出來usblib.a后 不知道該如何使用,希望有人能夠幫幫忙,或者提供一個基于Stellaris的USB例程,不要BULK那個庫里直接調用的 最好是基于AP ...… 查看全部問答∨ |
摘要:隨著無線通信技術的迅速發展, 新的技術不斷出現。短距離無線通信技術已成為無線通信技術的新熱點,作為IEEE802.15.4 標準的ZigBee技術是一種新興的近距離、低復雜度、低功耗、低數據速率、低成本的無線網絡技術, 主要用于近距離無線連接。而A ...… 查看全部問答∨ |
兩年嵌入式學習的心得體會——歡迎大家來交流! 不知不覺搞嵌入式也快兩年了。說到學習嵌入式,整理了一位資深嵌入式工程師的視頻報告,里面講到了嵌入式學習的要點和嵌入式學習需要重點掌握的知識點。希望能讓那些將要學習嵌入式和正 ...… 查看全部問答∨ |
哪里有vs2005智能設備的大屏幕的皮膚? C:\\Program Files\\Microsoft Visual Studio 8\\smartdevices\\Skins\\PocketPC_2003\\PocketPC_2003_Square\\2052\\PocketPC_2003_Square_Skin.xml 這些PocketPC_2003 Smartphone_2003都太小 ...… 查看全部問答∨ |
|
430的輸入邏輯高電平是0.8Vcc,0.8*3.3=2.64V,我用的器件的輸出邏輯高電平是4.5V,電平是匹配了,可這樣會不會燒壞430呢,430管腳最大允許電壓是多少呢?我查的信息不統一。麻煩你了各位了!謝謝!… 查看全部問答∨ |
|
原理圖附上,現在用2個PWM分別控制LM358的2個通道運放輸出0~10V,出現問題: PWM相同占空比:通道1輸出10V &nb ...… 查看全部問答∨ |