nemon

【PSoC4】遗簪见取终安用,敝竽虽微亦自珍

0
阅读(6799)

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


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

在神奇的http://zh.wikipedia.org/wiki/%E9%9F%B3%E9%AB%98 上,可以查到这个表格,记载了各个音高的对应频率:

频率,单位为赫兹 (括号内为半音距离,"(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个:


引脚这样分配的:

实物接线更简单:


下面是代码:


#include <device.h>

void main()
{
    Clock_1_Start();
    PWM_1_Start();
    for(;;)
    {
        if(!Pin_Button_1_Read()){
            Pin_LED_Write(0);
            PWM_1_WritePeriod(3822);
            PWM_1_WriteCompare1(3822>>1);
        }else if(!Pin_Button_2_Read()){
            Pin_LED_Write(0);
            PWM_1_WritePeriod(3405);
            PWM_1_WriteCompare1(3405>>1);
        }else if(!Pin_Button_3_Read()){
            Pin_LED_Write(0);
            PWM_1_WritePeriod(3034);
            PWM_1_WriteCompare1(3034>>1);
        }else if(!Pin_Button_4_Read()){
            Pin_LED_Write(0);
            PWM_1_WritePeriod(2863);
            PWM_1_WriteCompare1(2863>>1);
        }else if(!Pin_Button_5_Read()){
            Pin_LED_Write(0);
            PWM_1_WritePeriod(2551);
            PWM_1_WriteCompare1(2551>>1);
        }else if(!Pin_Button_6_Read()){
            Pin_LED_Write(0);
            PWM_1_WritePeriod(2273);
            PWM_1_WriteCompare1(2273>>1);
        }else if(!Pin_Button_7_Read()){
            Pin_LED_Write(0);
            PWM_1_WritePeriod(2025);
            PWM_1_WriteCompare1(2025>>1);
        }else{
            Pin_LED_Write(1);
            PWM_1_WritePeriod(9999);
            PWM_1_WriteCompare1(0);
        }
    }
}

最后请大家屈尊听一下这音闹梁,挥之不去的效果:

12345-20131028184816.rar