找回密碼
 立即注冊(cè)

QQ登錄

只需一步,快速開始

搜索
查看: 1707|回復(fù): 5
收起左側(cè)

單片機(jī)秒表程序中如何添加蜂鳴器功能?

[復(fù)制鏈接]
ID:1053789 發(fā)表于 2022-11-30 02:14 | 顯示全部樓層 |閱讀模式
這是一個(gè)秒表系統(tǒng)設(shè)計(jì)
可以選擇正計(jì)時(shí)/倒計(jì)時(shí)?梢宰约和ㄟ^按鍵設(shè)置倒計(jì)時(shí)的時(shí)間,當(dāng)自己設(shè)定的倒計(jì)時(shí)使蜂鳴器響。
倒計(jì)時(shí)我已經(jīng)完成了,但現(xiàn)在當(dāng)?shù)褂?jì)時(shí)時(shí)間到后使用蜂鳴器響我不知道如何添加,求指導(dǎo)。蜂鳴IO口為P1^0。如何在我現(xiàn)有的程序上修改程序呢,我試了很多次,都不行。我添加蜂鳴器對(duì)嗎?
秒表2222.png
單片機(jī)源程序如下:
  1. #include<reg52.h> // 包含 52 單片機(jī)寄存器定義的頭文件
  2. unsigned char Tab1[ ]={0x3f,0x06,0x5b,0x4f ,0x66,0x6d,0x7d,0x07,0x7f ,0x6f }; // 段碼表
  3. unsigned char Tab2[ ]={0xbf,0x86,0xdb,0xcf,0xe6,0xed,0xfd,0x87,0xff,0xef}; // 個(gè)位段碼表
  4. unsigned int x;
  5. unsigned char k;
  6. sbit int0=P3^2;          //開始/暫停//
  7. sbit int1=P3^3;
  8. sbit SUB60=P1^1; //正計(jì)時(shí)/倒計(jì)時(shí)//
  9. sbit S60=P1^2; //控制60s//
  10. sbit K5=P1^3;//加1s//
  11. sbit K6=P1^4;//減1s//
  12. sbit K7=P1^5; //賦值60s//
  13. sbit K8=P1^6; //清零//
  14. sbit baojing=P1^0;// 蜂鳴器//
  15. /*************************** 延時(shí) 1ms 基準(zhǔn) ******************************************/
  16. void delay1ms(unsigned int i)
  17. {
  18. unsigned char j;
  19. while(i--)
  20. {
  21. for(j=0;j<125;j++) //1ms 基準(zhǔn)延時(shí)程序 12MHZ 晶振
  22. {
  23. }
  24. }
  25. }
  26. /********************************************************************************
  27. ****************** 數(shù)碼管顯示程序 ***********************************************/
  28. void Display(unsigned int x)
  29. {
  30. P2=0xfe; //P2.0 引腳輸出低電平, DS6 點(diǎn)亮
  31. P0=Tab1[x/1000]; // 顯示百位
  32. delay1ms(6);
  33. P2=0xfd; //P2.1 引腳輸出低電平, DS6 點(diǎn)亮
  34. P0=Tab1[x%1000/100]; // 顯示十位
  35. delay1ms(6);
  36. P2=0xfb; //P2.2 引腳輸出低電平, DS6 點(diǎn)亮
  37. P0=Tab2[x%100/10]; // 顯示個(gè)位
  38. delay1ms(6);
  39. P2=0xf7; //P2.3 引腳輸出低電平, DS7 點(diǎn)亮
  40. P0=Tab1[x%10]; // 顯示 0.1 位
  41. delay1ms(6);
  42. P2=0xff;
  43. }

  44. /*******************************************
  45. 函數(shù)功能:主函數(shù)
  46. ******************************************/
  47. void main(void)
  48. {
  49. x=0;
  50. TMOD=0x01; // TMOD=0000 0001B, 使用計(jì)數(shù)器 T0 的工作方式 1
  51. EA=1; // 開起總中斷
  52. ET0=1; // 允許定時(shí)器 T0 的中斷
  53. EX0=1; // 允許外中斷 INT0
  54. IT0=1; //INT0 為下負(fù)脈沖觸發(fā)方式
  55. TH0=(65536-50000)/256; // 計(jì)數(shù)器 T0 高 8 位賦初值
  56. TL0=(65536-50000)%256; // 計(jì)數(shù)器 T0 低 8 位賦初值
  57. TF0=0; // 溢出標(biāo)志位清零
  58. while(1)
  59. {
  60. /************************************************************
  61. ****************K5 P1.3 按一次加 1 開關(guān) S1***************************/
  62. if(K5==0)
  63. {
  64. delay1ms(20);
  65. if(K5==0)
  66. {
  67. x=x+10;
  68. }
  69. while(!K5); // 摁鍵關(guān)斷 摁一次觸發(fā)一次
  70. }
  71. /***********************************************************
  72. ************K6 P1.4 按一次減 1 開關(guān) S2**************************/
  73. if(K6==0)
  74. {
  75. delay1ms(20);
  76. if(K6==0)
  77. {
  78. if(x==0)
  79. {
  80. x=10; // 在 00.0 的時(shí)候停止
  81. }
  82. x=x-10;
  83. }
  84. while(!K6); // 摁鍵關(guān)斷 摁一次觸發(fā)一次
  85. }
  86. /*********************************************************************
  87. ******************K7 P1.5 初始值 賦值為 60.0 秒開關(guān) S5********************/
  88. if(K7==0)
  89. {
  90. delay1ms(20);
  91. if(K7==0)
  92. {
  93. x=600; // 賦初值 60.0 秒
  94. }
  95. while(!K7); // 摁鍵關(guān)斷 摁一次觸發(fā)一次
  96. }
  97. /*********************************************************************
  98. ******************S60 控制 60S 停止開關(guān) P1.2****************************/
  99. if(x==600)
  100. {
  101. if(S60==0) // 如果 P1.2 口是低電平,秒表變化范圍 00.0~60.0
  102. {
  103. TR0=0;
  104. }
  105. }
  106. /********************************************************************
  107. ******************K8 P1.6 清零 clear0 摁鍵開關(guān) S3************************/
  108. if(K8==0)
  109. {
  110. delay1ms(20); // 延時(shí)消震
  111. if(K8==0)
  112. {
  113. x=0; // 數(shù)據(jù)清 0 數(shù)碼管顯示 000.0
  114. TR0=0; // 溢出標(biāo)志位清 0
  115. }
  116. }
  117. /************ 數(shù)碼管顯示 ***************************************/
  118. Display(x);
  119. }
  120. }
  121. /**********INT0 中斷函數(shù) 用于開始或暫停開關(guān) S4******************
  122. **************************************************************/
  123. void begin_stop() interrupt 0
  124. {
  125. if(int0==0)
  126. {
  127. delay1ms(30); // 延時(shí)消震
  128. if(int0==0)
  129. {
  130. TR0=~TR0; // 按鍵摁一次 讀秒開始或暫停
  131. if(x==0&&SUB60==0)
  132. {
  133. TR0=0;
  134. }
  135. }
  136. }
  137. }
  138. /*********************************************************
  139. ******T0 計(jì)數(shù)器中斷 控制每隔加 0.1 秒 ***********************/
  140. void add_one0() interrupt 1
  141. {
  142. k++;
  143. if(k==2)
  144. {
  145. k=0;
  146. TF0=0;
  147. if(SUB60==1) // 當(dāng) P1.1 口是高電平時(shí)秒表加 0.1s
  148. // 當(dāng) P1.1 口是低電平時(shí)秒表減 0.1s
  149. {
  150. x=x+1; // 秒表加 0.1s
  151. }
  152. else
  153. {
  154. x=x-1; // 秒表減 0.1s
  155. }
  156. if(x==0)
  157. {
  158. TR0=0;
  159. }
  160. if(x==9999)
  161. {
  162. TR0=0;
  163. }
  164. }
  165. TH0=(65536-50000)/256; // 計(jì)數(shù)器 T0 高 8 位賦初值
  166. TL0=(65536-50000)%256; // 計(jì)數(shù)器 T0 低 8 位賦初值
  167. }
復(fù)制代碼

回復(fù)

使用道具 舉報(bào)

ID:77589 發(fā)表于 2022-11-30 09:34 | 顯示全部樓層
如果你使用的是有源蜂鳴器,直接輸出高低電平就可以控制了。
如果你使用的是無源蜂鳴器,必須輸出頻率在20Hz~20000Hz之間的方波去驅(qū)動(dòng)了,具體頻率根據(jù)個(gè)人喜好去選擇,但頻率過低或過高人耳都是聽不見的。
回復(fù)

使用道具 舉報(bào)

ID:332444 發(fā)表于 2022-11-30 09:52 | 顯示全部樓層
入門時(shí)可以使用嵌套循環(huán),入門后中高級(jí)應(yīng)用就不能再一直使用嵌套循環(huán)。
回復(fù)

使用道具 舉報(bào)

ID:1053789 發(fā)表于 2022-11-30 14:48 | 顯示全部樓層
Longan.Wang 發(fā)表于 2022-11-30 09:34
如果你使用的是有源蜂鳴器,直接輸出高低電平就可以控制了。
如果你使用的是無源蜂鳴器,必須輸出頻率在20 ...

我使用的是有緣蜂鳴器。
但是如何更改我的程序,使倒計(jì)時(shí)時(shí)間到后,蜂鳴器響呢
我把148行到160行的代碼改成如下代碼,還是不可以

  1. if(SUB60==1) // 當(dāng) P1.1 口是高電平時(shí)秒表加 0.1s
  2. // 當(dāng) P1.1 口是低電平時(shí)秒表減 0.1s
  3. {
  4. if(x<600) x=x+1; // 秒表加 0.1s
  5. }
  6. else
  7. {
  8. if(x)
  9. {
  10.     x=x-1; // 秒表減 0.1s
  11.    if(0==x)  baojing=1;
  12. }
  13. }
  14. if(x==0)
  15. {
  16. TR0=0;
  17. }
復(fù)制代碼
回復(fù)

使用道具 舉報(bào)

ID:161164 發(fā)表于 2022-11-30 17:34 | 顯示全部樓層
仿了一下你的代碼,主循環(huán)耗時(shí)25ms
把下面的Beep()函數(shù)放到主循環(huán)
當(dāng)要響蜂鳴器時(shí)把BeepEn置1
蜂鳴器會(huì)以1Hz頻率來響,10秒后自動(dòng)停
2022-11-30_172854.png
回復(fù)

使用道具 舉報(bào)

ID:1053789 發(fā)表于 2022-11-30 18:49 | 顯示全部樓層
lkc8210 發(fā)表于 2022-11-30 17:34
仿了一下你的代碼,主循環(huán)耗時(shí)25ms
把下面的Beep()函數(shù)放到主循環(huán)
當(dāng)要響蜂鳴器時(shí)把BeepEn置1

為什么我這么添加還是報(bào)錯(cuò)呢,不是添加到主循環(huán)while中嗎
  1. #include<reg52.h> // 包含 52 單片機(jī)寄存器定義的頭文件
  2. unsigned char Tab1[ ]={0x3f,0x06,0x5b,0x4f ,0x66,0x6d,0x7d,0x07,0x7f ,0x6f }; // 段碼表
  3. unsigned char Tab2[ ]={0xbf,0x86,0xdb,0xcf,0xe6,0xed,0xfd,0x87,0xff,0xef}; // 個(gè)位段碼表
  4. unsigned int x;
  5. unsigned char k;
  6. sbit int0=P3^2;          //開始/暫停//
  7. sbit int1=P3^3;
  8. sbit SUB60=P1^1; //正計(jì)時(shí)/倒計(jì)時(shí)//
  9. sbit S60=P1^2; //控制60s//
  10. sbit K5=P1^3;//加1s//
  11. sbit K6=P1^4;//減1s//
  12. sbit K7=P1^5; //賦值60s//
  13. sbit K8=P1^6; //清零//
  14. sbit baojing=P1^0;// 蜂鳴器//
  15. /*************************** 延時(shí) 1ms 基準(zhǔn) ******************************************/
  16. void delay1ms(unsigned int i)
  17. {
  18. unsigned char j;
  19. while(i--)
  20. {
  21. for(j=0;j<125;j++) //1ms 基準(zhǔn)延時(shí)程序 12MHZ 晶振
  22. {
  23. }
  24. }
  25. }
  26. /********************************************************************************
  27. ****************** 數(shù)碼管顯示程序 ***********************************************/
  28. void Display(unsigned int x)
  29. {
  30. P2=0xfe; //P2.0 引腳輸出低電平, DS6 點(diǎn)亮
  31. P0=Tab1[x/1000]; // 顯示百位
  32. delay1ms(6);
  33. P2=0xfd; //P2.1 引腳輸出低電平, DS6 點(diǎn)亮
  34. P0=Tab1[x%1000/100]; // 顯示十位
  35. delay1ms(6);
  36. P2=0xfb; //P2.2 引腳輸出低電平, DS6 點(diǎn)亮
  37. P0=Tab2[x%100/10]; // 顯示個(gè)位
  38. delay1ms(6);
  39. P2=0xf7; //P2.3 引腳輸出低電平, DS7 點(diǎn)亮
  40. P0=Tab1[x%10]; // 顯示 0.1 位
  41. delay1ms(6);
  42. P2=0xff;
  43. }

  44. /*******************************************
  45. 函數(shù)功能:主函數(shù)
  46. ******************************************/
  47. void main(void)
  48. {
  49. x=0;
  50. TMOD=0x01; // TMOD=0000 0001B, 使用計(jì)數(shù)器 T0 的工作方式 1
  51. EA=1; // 開起總中斷
  52. ET0=1; // 允許定時(shí)器 T0 的中斷
  53. EX0=1; // 允許外中斷 INT0
  54. IT0=1; //INT0 為下負(fù)脈沖觸發(fā)方式
  55. TH0=(65536-50000)/256; // 計(jì)數(shù)器 T0 高 8 位賦初值
  56. TL0=(65536-50000)%256; // 計(jì)數(shù)器 T0 低 8 位賦初值
  57. TF0=0; // 溢出標(biāo)志位清零
  58. while(1)
  59. {//beep函數(shù)//
  60. bit BeepEn=0;
  61. void Beep()
  62. {
  63. static unsigned char delay25ms=0;
  64. static unsigned char BeepLong=0;
  65. if(BeepEn)
  66. {
  67. if(delay25ms++>=20)
  68. {
  69. delay25ms=0;
  70. baojing=!baojing;
  71. if(BeepLong++>=20)
  72. {
  73. BeepEn=0;
  74. }
  75. }
  76. }
  77. else{
  78. baojing=1;
  79. BeepLong=0;
  80. delay25ms=0;
  81. }
  82. }
  83. /************************************************************
  84. ****************K5 P1.3 按一次加 1 開關(guān) S1***************************/
  85. if(K5==0)
  86. {
  87. delay1ms(20);
  88. if(K5==0)
  89. {
  90. x=x+10;
  91. }
  92. while(!K5); // 摁鍵關(guān)斷 摁一次觸發(fā)一次
  93. }
  94. /***********************************************************
  95. ************K6 P1.4 按一次減 1 開關(guān) S2**************************/
  96. if(K6==0)
  97. {
  98. delay1ms(20);
  99. if(K6==0)
  100. {
  101. if(x==0)
  102. {
  103. x=10; // 在 00.0 的時(shí)候停止
  104. }
  105. x=x-10;
  106. }
  107. while(!K6); // 摁鍵關(guān)斷 摁一次觸發(fā)一次
  108. }
  109. /*********************************************************************
  110. ******************K7 P1.5 初始值 賦值為 60.0 秒開關(guān) S5********************/
  111. if(K7==0)
  112. {
  113. delay1ms(20);
  114. if(K7==0)
  115. {
  116. x=600; // 賦初值 60.0 秒
  117. }
  118. while(!K7); // 摁鍵關(guān)斷 摁一次觸發(fā)一次
  119. }
  120. /*********************************************************************
  121. ******************S60 控制 60S 停止開關(guān) P1.2****************************/
  122. if(x==600)
  123. {
  124. if(S60==0) // 如果 P1.2 口是低電平,秒表變化范圍 00.0~60.0
  125. {
  126. TR0=0;
  127. }
  128. }
  129. /********************************************************************
  130. ******************K8 P1.6 清零 clear0 摁鍵開關(guān) S3************************/
  131. if(K8==0)
  132. {
  133. delay1ms(20); // 延時(shí)消震
  134. if(K8==0)
  135. {
  136. x=0; // 數(shù)據(jù)清 0 數(shù)碼管顯示 000.0
  137. TR0=0; // 溢出標(biāo)志位清 0
  138. }
  139. }
  140. /************ 數(shù)碼管顯示 ***************************************/
  141. Display(x);
  142. }
  143. }
  144. /**********INT0 中斷函數(shù) 用于開始或暫停開關(guān) S4******************
  145. **************************************************************/
  146. void begin_stop() interrupt 0
  147. {
  148. if(int0==0)
  149. {
  150. delay1ms(30); // 延時(shí)消震
  151. if(int0==0)
  152. {
  153. TR0=~TR0; // 按鍵摁一次 讀秒開始或暫停
  154. if(x==0&&SUB60==0)
  155. {
  156. TR0=0;
  157. }
  158. }
  159. }
  160. }
  161. /*********************************************************
  162. ******T0 計(jì)數(shù)器中斷 控制每隔加 0.1 秒 ***********************/
  163. void add_one0() interrupt 1
  164. {
  165. k++;
  166. if(k==2)
  167. {
  168. k=0;
  169. TF0=0;
  170. if(SUB60==1) // 當(dāng) P1.1 口是高電平時(shí)秒表加 0.1s
  171. // 當(dāng) P1.1 口是低電平時(shí)秒表減 0.1s
  172. {
  173. x=x+1; // 秒表加 0.1s
  174. }
  175. else
  176. {
  177. x=x-1; // 秒表減 0.1s
  178. }
  179. if(x==0)
  180. {
  181. TR0=0;
  182. }
  183. if(x==9999)
  184. {
  185. TR0=0;
  186. }
  187. }
  188. TH0=(65536-50000)/256; // 計(jì)數(shù)器 T0 高 8 位賦初值
  189. TL0=(65536-50000)%256; // 計(jì)數(shù)器 T0 低 8 位賦初值
  190. }
復(fù)制代碼
回復(fù)

使用道具 舉報(bào)

本版積分規(guī)則

小黑屋|51黑電子論壇 |51黑電子論壇6群 QQ 管理員QQ:125739409;技術(shù)交流QQ群281945664

Powered by 單片機(jī)教程網(wǎng)

快速回復(fù) 返回頂部 返回列表