1回答

0收藏

[原创] 【PSoC4 Pioneer Kit 手记】遗簪见取终安用,敝竽虽微亦自珍

英飞凌 英飞凌 5647 人阅读 | 1 人回复 | 2013-11-29


《韩非子·内储说上》中有一段寓言:“齐宣王使人吹竽,必三百人。南郭处士请为王吹竽,宣王悦之,廪食以数百人。宣王死,湣王立,好一一听之,处士逃。”用今天的话说就是齐宣王让人吹竽,一定要三百人一起吹。南郭处士请求为齐宣王吹竽,宣王很高兴。官仓供养的乐手有好几百人。齐宣王死后,他的儿子湣王继位。湣王也喜欢听吹竽,但他喜欢让他们一个一个地吹,南郭处士只好逃走了。今天提起这个故事,一是要喷一喷PWM,二则是五音不全的楼主秀一下音乐羞痒(脸皮之厚,南郭弗如。呵呵)。

PWM大家都知道,输出占空比的。频率很低的时候可以用来闪LED,频率高了的话就不只是调LED亮度了,可以当作模拟输出,记得有个用法是提供LCD偏压,算是低调奢华有内涵的方式。今天博主分享的,是比较土憋矫情无下限的用法——驱动蜂鸣器奏乐。

在神奇的wiki 上,可以查到这个表格,记载了各个音高的对应频率:

频率,单位为赫兹 (括号内为半音距离,"(0)"为中央C)
八度 →
音名 ↓
0
1
2
3
4
5
6
7
8
9
C
16.352 (?48)32.703 (?36)65.406 (?24)130.81 (?12)261.63 (0)523.25 (+12)1046.5 (+24)2093.0 (+36)4186.0 (+48)8372.0 (+60)
C?/D?
17.324 (?47)34.648 (?35)69.296 (?23)138.59 (?11)277.18 (+1)554.37 (+13)1108.7 (+25)2217.5 (+37)4434.9 (+49)8869.8 (+61)
D
18.354 (?46)36.708 (?34)73.416 (?22)146.83 (?10)293.66 (+2)587.33 (+14)1174.7 (+26)2349.3 (+38)4698.6 (+50)9397.3 (+62)
D?/E?
19.445 (?45)38.891 (?33)77.782 (?21)155.56 (?9)311.13 (+3)622.25 (+15)1244.5 (+27)2489.0 (+39)4978.0 (+51)9956.1 (+63)
E
20.602 (?44)41.203 (?32)82.407 (?20)164.81 (?8)329.63 (+4)659.26 (+16)1318.5 (+28)2637.0 (+40)5274.0 (+52)10548 (+64)
F
21.827 (?43)43.654 (?31)87.307 (?19)174.61 (?7)349.23 (+5)698.46 (+17)1396.9 (+29)2793.8 (+41)5587.7 (+53)11175 (+65)
F?/G?
23.125 (?42)46.249 (?30)92.499 (?18)185.00 (?6)369.99 (+6)739.99 (+18)1480.0 (+30)2960.0 (+42)5919.9 (+54)11840 (+66)
G
24.500 (?41)48.999 (?29)97.999 (?17)196.00 (?5)392.00 (+7)783.99 (+19)1568.0 (+31)3136.0 (+43)6271.9 (+55)12544 (+67)
G?/A?
25.957 (?40)51.913 (?28)103.83 (?16)207.65 (?4)415.30 (+8)830.61 (+20)1661.2 (+32)3322.4 (+44)6644.9 (+56)13290 (+68)
A
27.500 (?39)55.000 (?27)110.00 (?15)220.00 (?3)440.00 (+9)880.00 (+21)1760.0 (+33)3520.0 (+45)7040.0 (+57)14080 (+69)
A?/B?
29.135 (?38)58.270 (?26)116.54 (?14)233.08 (?2)466.16 (+10)932.33 (+22)1864.7 (+34)3729.3 (+46)7458.6 (+58)14917 (+70)
B
30.868 (?37)61.735 (?25)123.47 (?13)246.94 (?1)493.88 (+11)987.77 (+23)1975.5 (+35)3951.1 (+47)7902.1 (+59)15804 (+71)


由于这次只用中音1234567,所以我们只关注八度为4的CDEFGAB,取其倒数,乘1000000取整,就变成了3822 ,3405 ,3034 ,2863 ,2551 ,2273 ,2025,这就是每秒震动次数,然后以此为基础,设置CompareValue为其1/2即可。

组件很简单,因为没有用连续的Pin所以输入定义了6个:


引脚这样分配的:



实物接线更简单:

下面是代码:
  1. #include <device.h>

  2. void main()
  3. {
  4.     Clock_1_Start();
  5.     PWM_1_Start();
  6.     for(;;)
  7.     {
  8.         if(!Pin_Button_1_Read()){
  9.             Pin_LED_Write(0);
  10.             PWM_1_WritePeriod(3822);
  11.             PWM_1_WriteCompare1(3822>>1);
  12.         }else if(!Pin_Button_2_Read()){
  13.             Pin_LED_Write(0);
  14.             PWM_1_WritePeriod(3405);
  15.             PWM_1_WriteCompare1(3405>>1);
  16.         }else if(!Pin_Button_3_Read()){
  17.             Pin_LED_Write(0);
  18.             PWM_1_WritePeriod(3034);
  19.             PWM_1_WriteCompare1(3034>>1);
  20.         }else if(!Pin_Button_4_Read()){
  21.             Pin_LED_Write(0);
  22.             PWM_1_WritePeriod(2863);
  23.             PWM_1_WriteCompare1(2863>>1);
  24.         }else if(!Pin_Button_5_Read()){
  25.             Pin_LED_Write(0);
  26.             PWM_1_WritePeriod(2551);
  27.             PWM_1_WriteCompare1(2551>>1);
  28.         }else if(!Pin_Button_6_Read()){
  29.             Pin_LED_Write(0);
  30.             PWM_1_WritePeriod(2273);
  31.             PWM_1_WriteCompare1(2273>>1);
  32.         }else if(!Pin_Button_7_Read()){
  33.             Pin_LED_Write(0);
  34.             PWM_1_WritePeriod(2025);
  35.             PWM_1_WriteCompare1(2025>>1);
  36.         }else{
  37.             Pin_LED_Write(1);
  38.             PWM_1_WritePeriod(9999);
  39.             PWM_1_WriteCompare1(0);
  40.         }
  41.     }
  42. }
复制代码
最后请大家屈尊听一下这竽音闹梁,挥之不去的效果:
12345-20131028184816.rar (1.22 MB, 下载次数: 22)





分享到:
回复

使用道具 举报

回答|共 1 个

倒序浏览

沙发

在路上的旁观者

发表于 2013-12-3 16:10:15 | 只看该作者

給力啊
您需要登录后才可以回帖 注册/登录

本版积分规则

关闭

站长推荐上一条 /3 下一条