狠狠躁夜夜躁人人爽超碰97香蕉|色婷婷日日躁夜夜躁|亚洲一区欧美一区在线播|久久久久久性高|伊人久久大香线蕉亚洲

歡迎來到同城快修-附近家電維修、家電清洗、家電安裝服務平臺

24小時家電維修熱線:

400—1558638

當前位置:主頁 > 空調 > 維修資訊 >

蜂鳴器源代碼(蜂鳴器初始化代碼)

發布日期:2023-02-11 11:42:53 瀏覽:
蜂鳴器源代碼(蜂鳴器初始化代碼)

前沿拓展:


最近幾天總是下雨,搞的人心情也很差,昨天看到有粉絲留言說,導師讓他們組做一個關于超聲波控制液體水位的項目,但是無從下手,希望我幫幫他,可以有償。他是我的鐵粉,下面我就把我前段時間幫人家設計的一個超聲波水位自動控制系統 分享出來,希望可以幫到他們。

51單片機超聲波水位控制器設計

設計說明:

本設計中液晶顯示有4個字母,分別為

H------容器的最高水位設定值(不能高于實際高度) L------容器的最低水位設定值

D-----容器實際高度(可以設置)

C-----容器內液體的高度(在實際演示中,障礙物離探頭越近,液晶C顯示越大,因為障礙物好比液面,離探頭近了說明水位高了)

特別提醒:如果容器實際高度D你設置為1米,那么C液體的高度最高能測到98cm,因為探頭的盲區在2cm左右。如果D設為2米,那么最高能測到1.98m.

按鍵功能分別為:設置鍵 增加鍵 減小鍵 復位鍵

三個指示燈的分別功能為:紅色----超過設定的最高水位H 黃色-----低于設定的最低水位L

綠色----最高H和最低L中間

本文采用AT89C52單片機系統實現了水塔水位的自動控制,設計出一種低成本、高實用價值的水塔水位控制器。該系統具有水位檢測、水位高度LCD顯示、低水位高水位報警以及自動加水等功能。

本設計過程中主要采用了傳感技術、單片機技術、光報警技術以及弱電控制強電的技術。本設計傳感器使用了超聲波模塊,并且詳細闡述了超聲波測距測的原理,給出了系統構成框圖。此系統具有易控制、工作可靠、測量精度高的優點,可實時監控液位。并采用52單片機系統控制整個電路的信號處理以及采用光電耦合和繼電器來實現弱電控制強電來實現加水系統的自動控制。它能自動完成水位檢測、光報警、上水停水的全部工作循環,保證液面高度始終處于較理想的范圍內,它結構簡單,制造成本低,靈敏度高,節約能源顯著,是用于各種高層液體儲存的理想設備。

為了大家更好地理解,請如下看示意圖

制作出來的實物圖如下:

AD的設計圖如下:

超聲波水位控制器元件清單

1) 9*15萬用板 1

2) AT89C51單片機 1

3) 超聲波探頭 0

4) 40腳IC座 1

5) 4腳排針 0

6) 杜邦線4根 0

7) 繼電器*2 0

8) LCD1602液晶 1

9) 103電位器 0

10) 16腳IC座 0

11) 16腳排針 1

12) 蜂鳴器 0

13) 8550三極管*3 0

14) 1k電阻*8 0

15) 10k電阻 0

16) 10uf電容 0

17) 30pf電容*2 0

18) 12M晶振 1

19) 3mmLED(紅、綠各2個,黃1個) 0

20) 輕觸按鍵*4 1

21) 自鎖開關 1

22) DC電源插口 1

23) USB電源線(電池盒)

24) 直流水泵*2(根據客戶自選)

單片機程序源碼如下:

/***************************************************************

名稱:基于51單片機的超聲波水位監測報警系統

單片機型號:AT89C51

單片機設置:時鐘12T,晶體12MHZ

作者:從零開始學單片機

注:修改增加水泵控制和排水控制,即雙繼電器

***************************************************************/

#include <reg51.h>

#include <intrins.h> // 包含循環移位:_cror_

#include "main.h"

//----------------------------------------------------------------------

uchar code TabNumASCII[10] = {'0','1','2','3','4','5','6','7','8','9'};

bool g_flag = isNo; //用于標記超時(65.536ms)

bool g_flag05s = isNo; //用于標記0.52秒

uchar ucCount = 0; //用于計數0.52秒

uint uiH = 80; //設定的最高報警水位 H

uint uiL = 30; //設定的最低報警水位 L

uint uiD = 100; //檢測探頭到水庫底部的距離 D

bool g_flagSwitch = isNo; //控制閥門連續開啟間隔延時(保護)標志

bool g_flagBeepTimer = isNo; //定時提醒標志

//-----------------------------------------------------------------------

// 延時10us

void delay10us(void) //@12MHz

{

unsigned char i;

_nop_();

i = 2;

while (--i);

}

// 延時100us

void delay100us(void) //@12MHz

{

uchar i;

_nop_();

i = 47;

while (--i);

}

// 延時125us

void delay125us(void) //@12MHz

{

unsigned char i;

i = 60;

while (--i);

}

// 延時5ms

void delay5ms(void) //@12.000MHz

{

unsigned char i, j;

i = 10;

j = 183;

do

{

while (--j);

} while (--i);

}

// 延時500ms

void delay500ms(void) //@12MHz

{

unsigned char i, j, k;

_nop_();

i = 4;

j = 205;

k = 187;

do

{

do

{

while (--k);

} while (--j);

} while (--i);

}

//-----------------------------------------------------------------------

//初始化IO端口

void initIO(void)

{

P0 = 0xff;

P1 = 0xff;

P2 = 0xff;

P3 = 0xff;

}

// 初始化定時器0,定時器時鐘12T模式 模式1,16位 @12.000MHz

void initTimer0(void)

{

TMOD &= 0xF0; //設置定時器模式

TMOD |= 0x01; //設置定時器模式

TL0 = 0; //定時器初值清零

TH0 = 0; //定時器初值清零

//TR0 = 1; //開定時器0

ET0 = 1; //開定時器0中斷

EA = 1; //開總中斷

}

// 初始化定時器1,定時器時鐘12T模式 模式1,16位 @12.000MHz

void initTimer1(void) //50毫秒@12.000MHz

{

TMOD &= 0x0F; //設置定時器模式

TMOD |= 0x10; //設置定時器模式

TL1 = 0xB0; //設置定時初值

TH1 = 0x3C; //設置定時初值

TR1 = 1; //定時器1開始計時

ET1 = 1; //開定時器0中斷

}

//-----------------------------------------------------------------------

//定時器0中斷

void zd0(void) interrupt 1

{

g_flag = isYes; //中斷溢出標志,g_flag = isYes超過測距范圍

if(++ucCount >= 8)

{

ucCount = 0;

g_flag05s = isYes; //g_flag05s = isYes定時0.52秒到,用于測量周期延時

}

TL0 = 0; //設置定時初值

TH0 = 0; //設置定時初值

}

//定時器1中斷 定時50ms

void tm1_isr() interrupt 3 using 1

{

static uchar count = DATA_switchTime; //50ms的200倍 = 10S

static uchar uiCount = 1200; // = 1分鐘

static uint uiCount_BeepTimer = DATA_BeepTimer;

TL1 = 0xB0; //設置定時初值

TH1 = 0x3C; //設置定時初值

if (g_flagSwitch == isNo)

{

if (count-- == 0) //50ms * 200 -> 10s

{

count = DATA_switchTime;

g_flagSwitch = isYes;

// TR1 = 0;

}

}

if(g_flagBeepTimer == isNo)

{

if (uiCount-- == 0) //= 1分鐘

{

uiCount = 1200;

if(uiCount_BeepTimer-- == 0)

{

uiCount_BeepTimer = DATA_BeepTimer;

g_flagBeepTimer = isYes;

// TR1 = 0;

}

}

}

}

//-----------------------------------------------

//外部中斷1

void exint1() interrupt 2

{

EX1 = 0; //關閉當前中斷

TR0 = 0; //關閉時器0

}

//-----------------------------------------------------------------------

//讀LCD忙狀態并等待忙狀態結束

void LCD_waitNotBusy(void)

{

IO_LCD_Data = 0xFF;

io_LCD_RS = 0;

io_LCD_RW = 1;

io_LCD_E = 0;

_nop_();

_nop_();

io_LCD_E = 1;

while(IO_LCD_Data & 0x80); //檢測如果是忙信號,一直等到不忙

}

//給LCD寫指令

void LCDWriteCommand(uchar command,bool ifReadBusy) //ifReadBusy = 1 時先進行忙檢測

{

if (ifReadBusy == isReadBusy) LCD_waitNotBusy(); //根據需要檢測忙

IO_LCD_Data = command;

io_LCD_RS = 0;

io_LCD_RW = 0;

io_LCD_E = 0;

_nop_();

_nop_();

io_LCD_E = 1;

}

//給LCD寫數據

void LCDWriteData(uchar dat)

{

LCD_waitNotBusy(); //等到不忙

IO_LCD_Data = dat;

io_LCD_RS = 1;

io_LCD_RW = 0;

io_LCD_E = 0;

_nop_();

_nop_();

io_LCD_E = 1;

}

// 初始化LCD1602液晶顯示屏

void initLCD1602(void)

{

uchar i;

IO_LCD_Data = 0; // 數據端口清零

for(i = 0; i < 3; i++) // 設置三次顯示模式

{

LCDWriteCommand(0x38,isNotReadBusy); // 不檢測忙信號

delay5ms();

}

LCDWriteCommand(0x38,isReadBusy); // 設置顯示模式,檢測忙信號

LCDWriteCommand(0x08,isReadBusy); // 關閉顯示

LCDWriteCommand(0x01,isReadBusy); // 顯示清屏

LCDWriteCommand(0x06,isReadBusy); // 顯示光標移動設置

LCDWriteCommand(0x0F,isReadBusy); // 顯示開及光標設置

}

//按指定位置顯示一個字符

void putOneCharToLCD1602(uchar line, uchar position, uchar ucData)

{

line &= DATA_LineMax;

position &= DATA_PositionMax;

if (line == DATA_LineTow) position |= 0x40; //當要顯示第二行時地址碼+0x40;

position |= 0x80; //設置兩行顯示格式 D7 = 1;

LCDWriteCommand(position, isReadBusy); //發送命令 設置字符地址

LCDWriteData(ucData); //寫入字符的數據

}

//按指定位置顯示一串字符

void putLineCharsToLCD1602(uchar line, uchar position, uchar count, uchar code *ucData)

{

uchar i;

for(i = 0; i < count; i++) //連續顯示單個字符

{

putOneCharToLCD1602(line, position + i, ucData[i]);

}

}

//按指定位置連續顯示三個字符(三位數字)

void putThreeCharToLCD1602(uchar line, uchar position, uint uiNumber)

{

uiNumber %= 1000;

putOneCharToLCD1602(line, position, TabNumASCII[uiNumber / 100]);

putOneCharToLCD1602(line, ++position, TabNumASCII[uiNumber % 100 / 10]);

putOneCharToLCD1602(line, ++position, TabNumASCII[uiNumber % 100 % 10]);

}

// 按鍵檢測子程序,有鍵按下返回鍵端口數據,無鍵返回0

uchar GetKey(void)

{

uchar KeyTemp = (IO_KEY | DATA_KEY_ORL); //獲取按鍵端口數據

if( KeyTemp != DATA_KEY_Null ) // 如果不為空

{

uchar CountTemp = 0;

do

{

delay125us();

if(KeyTemp != (IO_KEY | DATA_KEY_ORL)) return 0; //在延時期間檢測鍵,如果不穩定保持則退出

} while(++CountTemp > Data_Key20msCountMax); // 延時20ms去抖動

while((IO_KEY | DATA_KEY_ORL) != DATA_KEY_Null); //等鍵釋放

return KeyTemp; // 有鍵按下返回鍵端口數據

}

return 0; // 無有效鍵返回0

}

//加一

uchar INC_Number(uchar Number, uchar Min, uchar Max)

{

if(Number >= Max) return Min; else return (++ Number);

}

//減一

uchar DEC_Number(uchar Number, uchar Min, uchar Max)

{

if(Number <= Min) return Max; else return (-- Number);

}

// 檢測到有按鍵后 這里執行按鍵任務

void execute_key_task(uchar ucKeyValue)

{

uchar state = 0; //定義調整數據的狀態變量

uchar keyValue = 0; //定義鍵值得臨時變量

if(ucKeyValue != DATA_KEY_Set) return; //不是設置鍵退出

//是設置鍵繼續-----------------------------------------------------

putLineCharsToLCD1602(lineTow, 8, 8, "C:000cm "); //清零顯示當前距離CURRENT

putThreeCharToLCD1602(lineOne, 8 + 2, uiD); //光標調整到調整總距離(檢測探頭到水庫底部的距離“D:000cm”)

while(1)

{

keyValue = GetKey();

if(keyValue == 0) continue;

switch(keyValue)

{

case DATA_KEY_Set:

{

// 如果按的是設置鍵,順序設置總距離D——高水位H——低水位L——退出

switch(state)

{

case 0: // 如果是設置總距離狀態,改變為設置高水位狀態,并顯示高水位,實現移動光標到高水位后面

{

state = 1;

putThreeCharToLCD1602(lineOne, 0 + 2, uiH);

}

break;

case 1:

{

uchar tempMax = uiD - DATA_uiD_Min;

if(tempMax < 2 + 2) tempMax = 2 + 2;

if(uiH > tempMax)

{

uiH = tempMax;

putThreeCharToLCD1602(lineOne, 0 + 2, uiH);

}

else if(uiH < 2 + 2)

{

uiH = 2 + 2;

putThreeCharToLCD1602(lineOne, 0 + 2, uiH);

}

state = 2;

putThreeCharToLCD1602(lineTow, 0 + 2, uiL);

}

break;

case 2:

{

if(uiL > uiH - 2)

{

uiL = uiH - 2;

putThreeCharToLCD1602(lineTow, 0 + 2, uiL);

}

return;

}

break;

}

}

break;

// 如果按的是增加鍵,改變相應數據并顯示

case DATA_KEY_INC:

{

switch(state)

{

case 0:

{

uiD = INC_Number(uiD, DATA_uiD_Min, DATA_uiD_Max);

putThreeCharToLCD1602(lineOne, 8 + 2, uiD);

}

break;

case 1:

{

uchar tempMax = uiD - DATA_uiD_Min;

if(tempMax < 2 + 2) tempMax = 2 + 2;

uiH = INC_Number(uiH, 2, tempMax);

putThreeCharToLCD1602(lineOne, 0 + 2, uiH);

}

break;

case 2:

{

uiL = INC_Number(uiL, 0, uiH - 2);

putThreeCharToLCD1602(lineTow, 0 + 2, uiL);

}

break;

}

}

break;

// 如果按的是減少鍵,改變相應數據并顯示

case DATA_KEY_DEC:

{

switch(state)

{

case 0:

{

uiD = DEC_Number(uiD, DATA_uiD_Min, DATA_uiD_Max);

putThreeCharToLCD1602(lineOne, 8 + 2, uiD);

}

break;

case 1:

{

uchar tempMax = uiD - DATA_uiD_Min;

if(tempMax < 2 + 2) tempMax = 2 + 2;

uiH = DEC_Number(uiH, 2, tempMax);

putThreeCharToLCD1602(lineOne, 0 + 2, uiH);

}

break;

case 2:

{

uiL = DEC_Number(uiL, 0, uiH - 2);

putThreeCharToLCD1602(lineTow, 0 + 2, uiL);

}

break;

}

}

break;

}

}

}

// 蜂鳴器

void buzzerCall(void)

{

uchar i;

for(i = 0; i < 90; i++)

{

io_Buzzer = 0;

delay100us();

io_Buzzer = 1;

delay100us();

delay100us();

}

delay100us();

delay100us();

}

//計算水位

bool CalculatedWaterLevel(void)

{

uchar i = 8 + 2; //當前水位的數字在LCD屏顯示的起點位置

uint uiTime; //聲波傳播時間

ulong ulDis; //實時測量到距離

uiTime = TH0 << 8 | TL0;

ulDis = (uiTime * 3.40) / 200; //計算當前測量的距離,單位cm

TH0 = 0;

TL0 = 0;

if((ulDis > uiD) || (g_flag == isYes )) // ulDis > uiD 超出測量范圍;g_flag == isYes超時;

{

g_flag = isNo;

TR0 = 0;

putLineCharsToLCD1602(lineTow, i, 3, "Err"); // 顯示Err

//閥門動作:

// if(g_flagSwitch == isYes)

// {

// io_Control_Inlet = isio_Control_Inlet_OFF;

// io_Control_Outlet = isio_Control_Outlet_ON;

// g_flagSwitch = isNo;

// }

//指示燈:

ioLed_Red = ! ioLed_Red; // 三個燈同時快速閃亮

ioLed_Green = ! ioLed_Green;

ioLed_Yellow = ! ioLed_Yellow;

// 蜂鳴器叫:

if(buzzerCallFlag == isCall)

{

buzzerCall(); // 蜂鳴器叫

}

return isNo; // 返回錯誤信息

}

else

{

ulDis = uiD - ulDis; // 當前水位C = 總距離 - 當前檢測到的距離

if(ulDis > uiH) // 如果水位超高

{

//閥門動作:

io_Control_Inlet = isio_Control_Inlet_OFF;

io_Control_Outlet = isio_Control_Outlet_ON;

g_flagSwitch = isNo;

//指示燈:

ioLed_Red = ! ioLed_Red; // 紅燈閃

ioLed_Green = isLedOFF;

ioLed_Yellow = isLedOFF;

// 蜂鳴器叫:

if(ulDis - uiH > (uiD - uiH) / DATA_alarmCoefficient) //當“當前水位”超出最高水位“ ((“總高度減高水位)除以2的值”)時報警

{

buzzerCall(); // 蜂鳴器叫

}

}

else if(ulDis < uiL) // 如果水位超低

{

//閥門動作:

if(g_flagSwitch == isYes)

{

io_Control_Outlet = isio_Control_Outlet_OFF;

io_Control_Inlet = isio_Control_Inlet_ON;

g_flagSwitch = isNo;

}

//指示燈:

ioLed_Red = isLedOFF;

ioLed_Green = isLedOFF;

ioLed_Yellow = ! ioLed_Yellow; //黃燈閃

// 蜂鳴器叫:

if( uiL - ulDis > uiL / DATA_alarmCoefficient)//uiL / 2 當“當前水位”低于“低水位” “低水位除以2的值”時報警

{

buzzerCall(); // 蜂鳴器叫

}

}

else // 水位在正常范圍

{

ioLed_Red = isLedOFF;

ioLed_Green = ! ioLed_Green;

ioLed_Yellow = isLedOFF;

}

putThreeCharToLCD1602(lineTow, i, ulDis);

return isYes;

}

return isYes;

}

void main(void)

{

initIO(); //初始化IO端口

delay500ms(); //啟動延時,給器件進入正常工作狀態留夠時間

initLCD1602(); //LCD初始化

putLineCharsToLCD1602(lineOne, 8, 8, "D:000cm "); //顯示distance (總)距離(檢測探頭到水庫底部的距離)D

putThreeCharToLCD1602(lineOne, 8 + 2, uiD); //顯示三位數值

putLineCharsToLCD1602(lineOne, 0, 8, "H:000cm "); //顯示設定的最高報警水位H

putThreeCharToLCD1602(lineOne, 0 + 2, uiH); //顯示三位數值

putLineCharsToLCD1602(lineTow, 0, 8, "L:000cm "); //顯示設定的最低報警水位L

putThreeCharToLCD1602(lineTow, 0 + 2, uiL); //顯示三位數值

putLineCharsToLCD1602(lineTow, 8, 8, "C:000cm "); //顯示當前CURRENT水位C

initTimer0(); //初始化定時器0

initTimer1();

//閥門動作:初始先排水

io_Control_Inlet = isio_Control_Inlet_OFF;

io_Control_Outlet = isio_Control_Outlet_ON;

g_flagSwitch = isNo;

while(1)

{

io_US_TX = 1; //啟動超聲波模塊信號

delay10us();

io_US_TX = 0;

while(io_US_RX == 0); //等待計時開始

TR0 = 1; //開啟定時器0,計時開始

IT1 = 1; //設置外中斷INT1輸入信號模式(1:Falling only僅下降沿有效 0:Low level低電平有效)

EX1 = 1; //使能外中斷INT1

while(EX1 == 1 && g_flag == isNo)//等待中斷或超時退出

{

uchar ucKeyValue = GetKey(); //在等待中檢測按鍵

if(ucKeyValue) execute_key_task(ucKeyValue); //如果有鍵按下則執行按鍵任務

}

if(CalculatedWaterLevel() == isNo) continue; //計算水位,如果超出范圍返回isNo并重新循環

TR0 = 0; //暫時關閉定時器0

//清零定時器和計數變量以及標志

TL0 = 0;

TH0 = 0;

g_flag = isNo;

ucCount = 0;

g_flag05s = isNo;

TR0 = 1; //打開定時器0

鑒于篇幅限制,只能寫部分代碼

最后,如果有什么意見或者建議歡迎您留言給我,讓我們共同學習一起進步,

如果需要 完整代碼或設計文件,請在下方留言或者私信我,看到后會第一時間回復。

謝謝!

感謝你的閱讀,希望您有所收獲,喜歡請點贊評論加關注!

拓展知識:

主站蜘蛛池模板: 国产午夜高潮熟女精品av软件 | 99国产精品永久免费视频| 国产精品成人久久久久久久| 91精品一区二区| 人人添人人澡人人澡人人人人| 亚洲精品综合一区二区三| 夜夜爽久久揉揉一区| 中文字幕在线免费看线人| 欧美后入一区二区三区| 亚洲成a人v影院色老汉影院| 青草青草久热精品视频国产4| 亚洲日本欧美熟女一区二区三区.| 亚洲 欧美 日本 国产 高清| 巨爆乳中文字幕爆乳区| 秋霞午夜成人久久电影网| 一区二区三区视频直播| 亚洲一区二区三区四区视频| 狠狠色丁香婷婷久久综合| 懂色一区二区三区免费观看| 久久精品成人免费国产片小草| 久久av色欲av久久蜜桃网| 一性一交一口添一摸视频| 天堂中文在线资源| 一区二区三区四区电影网| 东京热精品视频一区二区三区| 色拍拍在线精品视频| 久久久成人一区二区免费影院| 十八禁在线观看国产一区| 一区二区亚洲精品国产片| 97久久久综合亚洲久久88| 国产精品久久久久久久9999| 国产精品国产三级国产专区53| 国产裸体美女视频全黄扒开| 久久免精品一区二区| 亚洲精品一区二区国产精华液| 不卡的一区二区三区av| 久久视频这里有精品33| 欧美不卡一区二区三区| 亚洲高清国产拍精品26u| 丰满人妻一区二区午夜福利久久 | 国产成人精品午夜二三区波多野 |