在項目中原理圖如下:
如果不能保證I/O的輸出性能可以根據(jù)情況增加上拉或者下拉電阻。
切入正題:在程序里面這個蜂鳴器的驅動就是個高低電平驅動。高電平三極管導通、蜂鳴器發(fā)聲,低電平三極管關斷、蜂鳴器不發(fā)聲。這的確很簡單,程序上最開始我是這樣寫的:
當然,如果單片機沒有很好的I/O跳變函數(shù)也可以這樣修改:
這里稍作解釋:
1)
函數(shù)功能:蜂鳴器發(fā)聲驅動
傳入參數(shù):蜂鳴器發(fā)聲的次數(shù)
2)
傳入的次數(shù)cnt需要再函數(shù)內翻倍。這是因為傳入的參數(shù)是想讓蜂鳴器連續(xù)的發(fā)cnt聲。但是蜂鳴器除了發(fā)聲還有不發(fā)聲的時候。也就是說蜂鳴器每響一次都需要關閉一次,如果沒有關閉操作肯定就不會出現(xiàn)響幾聲而是連續(xù)的響一聲,這個也很容易推理。
3)
在while循環(huán)完之后需要加一個蜂鳴器關閉操作。
這里假如傳進的參數(shù)是2,目的是讓蜂鳴器響兩聲。根據(jù)程序的執(zhí)行步驟:
cnt2變成4。
第1次while(4) 蜂鳴器開 cnt自減到3
第2次while(3) 蜂鳴器關 cnt自減到2
第3次while(2) 蜂鳴器開 cnt自減到1
第4次while(1) 蜂鳴器關 cnt自減到0
第5次while(0) 跳出while
可以看出其實在while之后蜂鳴器狀態(tài)已經(jīng)是關閉的了,但是保險起見,確保函數(shù)調用完之后蜂鳴器是關閉的狀態(tài)。比如第一個函數(shù)I/O跳變的就更需要保障了,因為代碼上只能看出跳變,看不到跳變之后的狀態(tài)。
至此,一個簡單的蜂鳴器電路和驅動程序就都溫習完了,接下來上干貨:
在寫程序的時候很多時候講究程序的效率,比如這個蜂鳴器驅動,驅動過程中會降低效率,厲害的人很快能看出來,就是這個Delay延時的問題。但是上面也說了,不延時也是不行的。所以趨于效率我嘗試著換了一種方法驅動蜂鳴器。
代碼如下:
實現(xiàn)起來也很簡單,簡單說下原理:
1)首先是提供蜂鳴器驅動的I/O配置,
2)其次是定時器的配置
3)最后是定時器中斷函數(shù)實現(xiàn)
我選用的定時器是項目單片機中最簡單的一個定時器,配制成1ms中斷,能夠提供溢出中斷。其實這個定時器我常用做計系統(tǒng)運行時間Systick_ms。但是該項目對這個系統(tǒng)時間沒有用到,那就用這個定時器做文章把。
實現(xiàn)方法:
1、同樣函數(shù)在調用蜂鳴器驅動的時候接口是一樣的,傳入的參數(shù)還是蜂鳴器的響聲次數(shù)。
2、函數(shù)體變了,這里改成了兩個變量的賦值,第一個BELL_CNT同普通方法中的cnt2,這里不再贅述。第二個是FLAG_BELL是用來保存蜂鳴器是否需要驅動的狀態(tài)變量。所以既然是調用驅動函數(shù),那肯定這個變量要為真。
3、定時器中斷函數(shù)里面加上了一個靜態(tài)變量NOW,他的作用就是和Systic_ms產生一個50ms的時間片,干嘛用?肯定是給蜂鳴器開關之間的延時用咯。模擬軟件延時嘛。然后再來分析下這段代碼:
1)首先這個NOW和Systic_ms是無條件需要賦值保證50ms時間片的。對應的代碼為NOW=Systick_ms+50;
2)判斷蜂鳴器驅動狀態(tài)變量是不是真,如果不為真就關閉蜂鳴器,這個也是無條件的。
3)如果狀態(tài)變量為真:蜂鳴器先跳變Bell_Tog();當然如果沒有這個跳變函數(shù)也可以用上述的判斷cnt的方法,就不多寫了都是一樣的。同時次數(shù)自減BELL_CNT--;同時判斷是不是減到0了,減到0了說明響完了啊,那就把狀態(tài)變量賦值為假。再次進來不管蜂鳴器是開著的還是關著的都會執(zhí)行關閉操作,這個跟上面說的保險一樣。
4)最后,這兩個變量用的是全局變量,這里是以結構體的形式呈現(xiàn)的,因為很多情況這兩個函數(shù)不在一個C里面。如果硬要寫在一個C可以忽略本條。
-
三極管
+關注
關注
143文章
3622瀏覽量
122404 -
單片機
+關注
關注
6043文章
44621瀏覽量
638628 -
蜂鳴器
+關注
關注
12文章
893瀏覽量
46100
原文標題:單片機有源蜂鳴器驅動之效率編程
文章出處:【微信號:changxuemcu,微信公眾號:暢學單片機】歡迎添加關注!文章轉載請注明出處。
發(fā)布評論請先 登錄
相關推薦
ESP32可以直接寫入RX的高低電平,和直接讀取TX的高低電平嗎?
高低電平的問題
單片機蜂鳴器驅動模塊設計及程序詳解
inux驅動IO輸出高低電平
如何用LPC2114的一個引腳輸出高低電平控制蜂鳴器間歇鳴叫
傳感器是直接返回一個值嗎?還是只是高低電平
![傳感器是直接返回一<b class='flag-5'>個</b>值嗎?還是只是<b class='flag-5'>高低電平</b>](https://file.elecfans.com/web1/M00/AF/0A/o4YBAF3f8IiAOUg8AAEUtEFAmZI405.jpg)
評論