標題: 主函數while循環(huán)中,觸發(fā)一次或連續(xù)多次蜂鳴器該怎么寫..獻上我慘不忍睹的單片機代碼 [打印本頁]

作者: sdarling    時間: 2021-3-10 02:55
標題: 主函數while循環(huán)中,觸發(fā)一次或連續(xù)多次蜂鳴器該怎么寫..獻上我慘不忍睹的單片機代碼
     最近學習中感覺遇到了一個砍..類似于1602顯示這類實時驅動的程序按照模塊化編程感覺沒什么問題了,但是那些觸發(fā)類型的功能函數感覺很生疏...比如蜂鳴器的觸發(fā)類型的驅動,然后找開發(fā)板那些程序...又都是類似于用延遲函數等蜂鳴器響完成結束了再去執(zhí)行其他程序....我嘗試以定時器時基的方式在主函數的while中實現蜂鳴器控制,但是感覺寫的挺亂的樣子,應該說寫了一點點就不知道如何寫了...寫不出來了233     蜂鳴器需要在某些條件下響一聲或是連續(xù)的幾聲,但是不影響while函數中其他的功能,該如何寫
     附上亂寫一通后無從下手的代碼....有大佬能指導一下嗎..     是需要加上一個蜂鳴器總控開關的標志位嗎

單片機源程序如下:
  1. void buz_1()    //一聲
  2. {
  3.   static uchar time_500ms=0;
  4.   if(buz_timecnt)
  5.     {
  6.       buz_timecnt=0;  //定時器中10ms置1一次
  7.       time_500ms++;
  8.       if(time_500ms>50)
  9.         {
  10.           buz_state(buz_off);   //開蜂鳴器。。有緣蜂鳴器
  11.           time_500ms=0;
  12.            buz_one_finish=1;
  13.           }
  14.     else
  15.      {
  16.       buz_state(buz_on);    //關蜂鳴器
  17.       }
  18.   }
  19. }

  20. void buz_4()    //連續(xù)響四聲
  21. {
  22.   static uchar num=0;
  23.   if(num<4)   //
  24.   {
  25.       buz_1();
  26.      if(buz_one_finish==1)
  27.      {
  28.         buz_one_finish=0;
  29.         num++;   、、不知道如何寫了
  30.      }
  31.    }
  32. }
復制代碼





作者: mengzhixinheng    時間: 2021-3-10 08:06
只是做提示音的話用有源蜂鳴器很簡單的。
作者: mengzhixinheng    時間: 2021-3-10 08:44
char t,c;
void(char t1,char c1)
{
   t=t1;//單次=溢出*t1
   c=c1;//單次時次數為0
   beep=1;//開蜂鳴器
}
void time_INT()//定時器溢出值自定
{
   if(t--==0)
   {
       if(c==0)
         beep=0;//關  
       else
         beep=~beep;
   }
}
作者: mengzhixinheng    時間: 2021-3-10 08:49
注意定時器的開啟與關閉同步
作者: 心有浮生    時間: 2021-3-10 09:33
傳參不就好了,寫那么多函數干嘛
作者: wulin    時間: 2021-3-10 11:39
這很簡單,給你寫個示例,一看就明白。
  1. #include <reg51.H>

  2. sbit Buzzer=P3^7;
  3. sbit key=P3^0;

  4. unsigned char start;

  5. /****1ms延時子程序(12MHz)****/
  6. void delayms(unsigned int k)
  7. {
  8.         unsigned int i,j;
  9.         for(i=k;i>0;i--)
  10.                 for(j=120;j>0;j--);
  11. }
  12. //num最大值與主循環(huán)周期密切關聯
  13. //此例以主循環(huán)周期1ms計算,響鈴周期1s
  14. void buz_4()    //1~n次聲響
  15. {
  16.         static unsigned int num;
  17.         if(start>0)   //start=0~n
  18.         {
  19.                 num++;       
  20.                 if(num<=500)
  21.                         Buzzer=0;//響
  22.                 if(num>500)
  23.                         Buzzer=1;//停
  24.                 if(num>=1000)
  25.                 {
  26.                         num=0;
  27.                         start--;
  28.                 }
  29.         }
  30.         else //確保意外時能復位
  31.         {
  32.                 Buzzer=1;
  33.                 num=0;
  34.         }
  35. }

  36. void keyscan()       
  37. {
  38.         static unsigned char count=0;        //計數變量                       
  39.         static bit key_sign=0;                        //按鍵狀態(tài)標志
  40.         if(!key)                                                //按鍵按下
  41.         {                       
  42.                 if(++count>=10&&key_sign==0)//計數延時消抖
  43.                 {                       
  44.                         key_sign=1;                                //按鍵狀態(tài)標志置1,防止重復響應
  45.                         start=4;                                        //start最大賦值255
  46.                 }
  47.         }
  48.         else                                                         //松手
  49.         {
  50.                 count=0;                                        //計數變量清0
  51.                 key_sign=0;                                        //按鍵狀態(tài)標志清0
  52.         }
  53. }
  54. void main()
  55. {
  56.         while(1)
  57.         {
  58.                 keyscan();
  59.                 buz_4();
  60.                 delayms(1);//控制主循環(huán)周期,代替其它程序所占時間
  61.         }
  62. }
復制代碼

作者: daemondong    時間: 2021-3-10 12:16
標準程序寫法, 中斷函數設定標志位,主循環(huán)處理標志位。
蜂鳴器處理辦法,時鐘中斷處理各種鳴叫 switch case ,  主循環(huán)設置好鳴叫模式就好了。
作者: SPEAR    時間: 2021-3-10 13:46
寫在外部中斷里唄,注意優(yōu)先級
作者: sdarling    時間: 2021-3-11 01:53
mengzhixinheng 發(fā)表于 2021-3-10 08:44
char t,c;
void(char t1,char c1)
{

謝謝大佬簡單明了的代碼   筆記做起!
作者: sdarling    時間: 2021-3-11 02:07
wulin 發(fā)表于 2021-3-10 11:39
這很簡單,給你寫個示例,一看就明白。

...最開始思路確實是往這方向寫的.同時響控制具體的開啟時間....但是腦子腦子一抽總感覺不對勁,最后越寫越亂.腦子一下子繞不過來....  感謝大佬幫我的思路延續(xù).....讓我發(fā)現錯在哪里了
作者: sdarling    時間: 2021-3-11 02:51
總結參考了上邊兩個程序,我知道我程序里邊少了一個核心的東西了,標志位..第一個buz_1的函數功能基本也無問題,但是少了觸發(fā)函數的條件,也就是標志位,第二個函數buz_4,在標志位列出來之后,就已經是個沒用了的函數了,可以直接刪除省事,但是如果真要單獨寫個4聲的函數也是可以寫出來了
作者: mengzhixinheng    時間: 2021-3-11 18:29
sdarling 發(fā)表于 2021-3-11 01:53
謝謝大佬簡單明了的代碼   筆記做起!

只是這樣簡單的提示音,擔心蜂鳴器過多占用資源的話,肯定要用定時器。8位單片機定時器也是很珍貴的。沒必要單獨寫兩個函數對定時器做過多的修飾。寫個帶參的初始化函數,在需要提示音的地方放個初始化函數就行了,要多少聲就初始化多少聲,要響多長時間就多長時間。我上面的程序只是思路,有兩個錯誤,如果你發(fā)現了自己改了就是。沒有就說一下!
作者: wyqf    時間: 2021-3-11 22:24
使用有源蜂鳴器,根據定時器設置的時間標志位改變蜂鳴器io輸出狀態(tài)即可
作者: sdarling    時間: 2021-3-12 00:34
mengzhixinheng 發(fā)表于 2021-3-11 18:29
只是這樣簡單的提示音,擔心蜂鳴器過多占用資源的話,肯定要用定時器。8位單片機定時器也是很珍貴的。沒 ...

這樣可以嗎.不知道大佬覺得該如何改..我放開發(fā)板上,這個程序能是能用,但是不知道IO口什么情況,明明有能力驅動三極管控制正常發(fā)聲的,一上這個程序在響的時候就只有滋滋滋的聲音了...


  1. char t,c;
  2. void(char t1,char c1)   
  3. {
  4.    t=t1;//單次=溢出*t1
  5.    c=c1;//單次時次數為1
  6.    beep=1;//開蜂鳴器
  7. }
  8. void time_INT()//定時器溢出值自定
  9. {
  10. static char cnt=0;
  11.   if(C>0)
  12.     {
  13.         if(++cnt<t)
  14.        {
  15.            beep=1;//開
  16.         }
  17.         else if(cnt<xx) //多次響時,xxx為間隔時間,可調
  18.         {
  19.            beep=0;
  20.          }
  21.         else
  22.         {
  23.            cnt=0;
  24.            C--;
  25.          }       
  26.      }
  27.     else  beep=0; //關
  28. }
復制代碼

作者: sdarling    時間: 2021-3-12 00:53
mengzhixinheng 發(fā)表于 2021-3-11 18:29
只是這樣簡單的提示音,擔心蜂鳴器過多占用資源的話,肯定要用定時器。8位單片機定時器也是很珍貴的。沒 ...

大佬有更簡便的方法嗎,剛剛那個用是能用的,聲音不對是我其他地方弄錯了
作者: mengzhixinheng    時間: 2021-3-12 07:32
sdarling 發(fā)表于 2021-3-12 00:53
大佬有更簡便的方法嗎,剛剛那個用是能用的,聲音不對是我其他地方弄錯了

char t,c;//全局變量
//蜂鳴器初始化
//c1聲響次數
//t1設定單次聲音的長度
/*
例:蜂鳴器單次響2秒,定時器溢出10ms
t1=200,c1=0
例:蜂鳴器響4次,每次500ms,定時器溢出10
t1=50,c1=4
如果定時器一直開啟,溢出時間不能太長,
如果定時器與蜂鳴器同步開啟關閉,那就無所謂
但是浪費定時器
*/
void BeepInit(char t1,char c1)//此函數哪里需要就放哪里
{
t=t1;//單次=溢出*t1
c=c1*2;//單次時次數為0
beep=1;//開蜂鳴器
}
void time_INT()//定時器溢出值自定,不同單片機函數寫法自己修改
{
//這里你的定時器初值是否需要重載?
if(t--==0)
{
   if(c==0)
   beep=0;//關
   else
       {
   beep=~beep;
         c--;
        }
}
}
注意以上程序是要調用定時器的,你有準確調用定時器嗎?
作者: sdarling    時間: 2021-3-15 03:29
mengzhixinheng 發(fā)表于 2021-3-12 07:32
char t,c;//全局變量
//蜂鳴器初始化
//c1聲響次數

這次看懂了!   謝謝
作者: sdarling    時間: 2021-3-15 03:41
mengzhixinheng 發(fā)表于 2021-3-12 07:32
char t,c;//全局變量
//蜂鳴器初始化
//c1聲響次數

但是你其中的變量t不是也還是需要重裝的嗎,所以也還是需要多寫一個變量吧?
作者: mengzhixinheng    時間: 2021-3-15 18:20
sdarling 發(fā)表于 2021-3-15 03:41
但是你其中的變量t不是也還是需要重裝的嗎,所以也還是需要多寫一個變量吧?

t,c根據你的需要初始化賦值,這不叫重載。你需要怎么樣的效果就怎樣賦值,調用函數填入參數就行。。。
作者: yzwzfyz    時間: 2021-3-15 21:52
教你如何讓蜂鳴器叫N聲,而不影響其它程序。
1、弄清楚蜂鳴器的特性:假設是長鳴型的,且接在P1.1上,0、1可決定其鳴與不鳴。
不妨用一個標記位來決定P1.1的值,設為B_BELL,=0或1,送入P1.1就可決定鳴叫。(假設0=叫,1=停)
2、弄清楚什么是叫一聲:假設叫0.5秒停0.3秒為叫一聲。這就需要用兩個寄存器來計時,不妨一個叫R_BUZZ用作0.5秒計時,另一個叫R_STOP用作0.3秒計時。
3、弄一個寄存器決定叫幾聲,設為R_N。
4、即下來就是計時了,用定時器做個中斷,設中斷時間=10ms。在中斷子程序里做一個供蜂鳴器用的標記位,設為:B_BELLTIME,每次中斷時將B_BELLTIME置1。
5、寫關鍵的鳴叫程序了:
5.1,在主程序中查B_BELLTIME,=0說明還未中斷,什么也不做,結束;=1說明中斷了,進行如下處理:
5.2,清B_BELLTIME=0,防止本程序被再次執(zhí)行(10ms后將由中斷服務程序置1)。
5.3,查看R_N=?,=0則表示已經完成了N次鳴叫,什么也不做,結束;<>0,則表示還在鳴叫中,繼續(xù)下面步驟:
5.4,查看當前正在叫B_BELL=0,還是正在停B_BELL=1?分別處理如下:
5.4.1,當前正在叫B_BELL=0,將R_BUZZ-1,即計時10ms(初始化時,讓R_BUZZ=50,即0.5秒),減1后不為0,則結束,即一聲還未叫完,讓它繼續(xù)叫著,不必動它。
       如果=0,即已叫滿0.5秒了,應該停叫了。這時:復位R_BUZZ=50準備下次計時用,將B_BELL改為1,并送到P1.1,讓蜂鳴器停止。
5.4.2,當前正在停B_BELL=1,將R_STOP-1,即計時10ms(初始化時,讓R_STOP=30,即0.3秒),減1后不為0,則結束,即一聲中的停止期未完,讓它繼續(xù)停著,不必動它。
       如果=0,即已停止0.3秒了,應該叫了。這時:復位R_STOP=30準備下次計時用,將B_BELL改為0,并送到P1.1,讓蜂鳴器開始叫。
       5.4.1 與 5.4.2 是分支,兩者只做一個。與5.4.1不同的是,5.4.2還要增加做一件重要的事:將R_N-1。!
以上就大功告成了。

要讓蜂鳴器叫8次,就讓R_N=8,就行了。叫5聲呢,讓R_N=5。
如何讓蜂鳴器在鳴叫過程中突然停止呢?是不是將R_N改為0就可以了呢?你自己想想吧,就算給你的作業(yè)吧。如果做對了,就說明你徹底理解了。
作者: yzwzfyz    時間: 2021-3-15 21:54
其它程序也同樣處理,關鍵是構思處理方案。寫程序簡單,照著構思寫語句就可以了。
作者: sdarling    時間: 2021-3-18 03:39
yzwzfyz 發(fā)表于 2021-3-15 21:52
教你如何讓蜂鳴器叫N聲,而不影響其它程序。
1、弄清楚蜂鳴器的特性:假設是長鳴型的,且接在P1.1上,0、1 ...

主要還是看的資料少,按樓上老哥思路差不多已經自己弄了一個了,之前看的都是那些直接上延遲的操作,想找貼近實際項目的教程很難找
作者: tyrl800    時間: 2021-3-18 16:11
yzwzfyz 發(fā)表于 2021-3-15 21:52
教你如何讓蜂鳴器叫N聲,而不影響其它程序。
1、弄清楚蜂鳴器的特性:假設是長鳴型的,且接在P1.1上,0、1 ...

假如是無源蜂鳴器,怎么寫呢?
作者: design003    時間: 2021-3-19 09:17
弄好了之后 再發(fā)散一下   自己編寫一個  通用函數以后可以用一輩子
    RunTask(  *Task(),uint8 Delay,uint8 Period,uint8 RunTimes)         

*Task() 是任務函數   Period  掃描執(zhí)行的間隔    Delay初值=Period 然后在時基標志時--  到0時再賦值Period RunTimes是任務次數   任務執(zhí)行的條件RunTimes大于1




歡迎光臨 (http://www.torrancerestoration.com/bbs/) Powered by Discuz! X3.1