步进电机以及无源蜂鸣器这些都需要脉冲信号才能够驱动,这里将用GPIO的PWM接口驱动无源蜂鸣器弹奏乐曲,本文基于树莓派Mode B+,其他版本树莓派实现时需参照相关资料进行修改!

1 预备知识

1.1 无源蜂鸣器和有源蜂鸣器

无源蜂鸣器:内部没有震荡源,直流信号无法让它鸣叫。必须用去震荡的电流驱动它,2K-5KHZ的方波PWM (Pulse Width Modulation脉冲宽度调制)。5KHZ的电流方波就是每秒震动5K次,每一个完整的周期占用200us的时间,高点平占一部分时间,低电平占一部分时间。声音频率可控,可以做出不同的音效。

有源蜂鸣器:内部带震荡电路,一通电就鸣叫,所以可以跟前面LED一样,给个高电平就能响,编程比无源的更方便。

本文利用无源蜂鸣器弹奏乐曲,用的就是淘宝上普通的电磁式阻抗16欧交流/2KHz 3V 5V 12V通用无源蜂鸣器,如果手边没有无源蜂鸣器,用普通的耳机也可以来代替无源蜂鸣器。

1.2 PWM

PWM(Pulse Width Modulation)即脉冲宽度调制,是一种利用微处理器的数字输出来控制模拟电路的控制技术。可以用下面的一幅图来形象地说明PWM:

图中tpwm就是一个周期的时间长度。对于2KHz频率来说,那么周期就是1s/2K=500us。图中的D叫做占空比,指的是高电平的时间占用整个周期时间的百分比。第一个周期D=50%,那么就是高电平低电平的时间各占一半。接下来的D为33%,那就是通电时间为33%,剩余的不通电时间占用67%。树莓派Model B+有4个PIN脚支持PWM输出,如下图最右侧:

但是,需要注意的是BCM2835芯片只支持两路PWM输出,所以以上12 Pin脚和32 Pin脚对应的都是channel 1的PWM输出,即如果这两个Pin的功能都选择的是PWM输出,则它们输出的PWM是完全相同的,同理33 Pin脚和35 Pin脚对应芯片channel 2的PWM输出。

博通公司公布的BCM2835芯片资料BCM2835 ARM Peripherals中第9章比较详细的介绍了PWM相关内容,此外还可参考网上整理好的寄存器介绍资料rip-registers,通过阅读可以得知树莓派Model B+支持两种模式的PWM输出:一种是Balanced mode(平衡模式),一种是Mark-Space mode(MS模式)。另外树莓派的PWM输出基础频率是19.2MHz,PWM输出频率受这个基础频率的限制。

1.3 树莓派PWM分析

进行分析前先看一下实验的物理电路连接:

图中,红色杜邦线一头连接树莓派的32 Pin脚(PWM0),一头连接示波器的探针;绿色杜邦线一头连接树莓派的12 Pin脚(PWM0),一头连接无源蜂鸣器的正极;黄色杜邦线一头连接树莓派的6 Pin脚(ground),一头连接无源蜂鸣器的负极,此外示波器探针的ground也连接到黄色杜邦线,结合bcm2835 C library来进行分析:

(1)下载bcm2835库:wget http://www.airspayce.com/mikem/bcm2835/bcm2835-1.50.tar.gz

(2)解压:tar -zxvf bcm2835-1.50.tar.gz

(3)进入目录:cd bcm2835-1.35

(4)编译:./configure && make

(5)安装:sudo make install

修改examples/pwm/pwm.c的内容如下:

 1 // pwm.c
 2 //
 3 // Example program for bcm2835 library
 4 // Shows how to use PWM to control GPIO pins
 5 //
 6 // After installing bcm2835, you can build this
 7 // with something like:
 8 // gcc -o pwm pwm.c -l bcm2835
 9 // sudo ./pwm
10 //
11 // Or you can test it before installing with:
12 // gcc -o pwm -I ../../src ../../src/bcm2835.c pwm.c
13 // sudo ./pwm
14 //
15 // Author: Mike McCauley
16 // Copyright (C) 2013 Mike McCauley
17 // $Id: RF22.h,v 1.21 2012/05/30 01:51:25 mikem Exp $
18
19 #include <bcm2835.h>
20 #include <stdio.h>
21
22 // PWM output on RPi Plug P1 pin 12 (which is GPIO pin 18)
23 // in alt fun 5.
24 // Note that this is the _only_ PWM pin available on the RPi IO headers
25 #define PIN RPI_GPIO_P1_12
26 // and it is controlled by PWM channel 0
27 #define PWM_CHANNEL 0
28 // This controls the max range of the PWM signal
29 #define RANGE 1024
30
31 #define PIN2 RPI_BPLUS_GPIO_J8_32
32
33 int main(int argc, char **argv)
34 {
35     if (!bcm2835_init())
36         return 1;
37
38     // Set the output pin to Alt Fun 5, to allow PWM channel 0 to be output there
39     bcm2835_gpio_fsel(PIN, BCM2835_GPIO_FSEL_ALT5);
40
41     bcm2835_gpio_fsel(PIN2, BCM2835_GPIO_FSEL_ALT0);    // 打开PI 32 Pin脚的PWM0输出功能
42
43     // Clock divider is set to 16.
44     // With a divider of 16 and a RANGE of 1024, in MARKSPACE mode,
45     // the pulse repetition frequency will be
46     // 1.2MHz/1024 = 1171.875Hz, suitable for driving a DC motor with PWM
47     bcm2835_pwm_set_clock(BCM2835_PWM_CLOCK_DIVIDER_16);
48     bcm2835_pwm_set_mode(PWM_CHANNEL, 0, 1);
49     bcm2835_pwm_set_range(PWM_CHANNEL, RANGE);
50
51     printf("this is banlance mode, anykey will change to markspace mode\n");
52     bcm2835_pwm_set_data(PWM_CHANNEL, RANGE/4);
53     getchar();
54
55     printf("change to markspace mode, anykey to exit\n");
56     bcm2835_pwm_set_mode(PWM_CHANNEL, 1, 1);
57     bcm2835_pwm_set_range(PWM_CHANNEL, RANGE);
58     bcm2835_pwm_set_data(PWM_CHANNEL, RANGE/4);
59     getchar();
60
61     bcm2835_close();
62     return 0;
63 }

pwm.c

代码中首先设置PWM输出为平衡模式,之后按任意键切换为MS模式,编译:gcc -o pwm pwm.c -lbcm2835,运行:sudo ./pwm,示波器分别捕获到如下波形图:

代码第47行用divider=16对19.2MHz的基础频率进行调整,调整后的pwm频率为19.2MHz/16=1.2MHz,根据BCM2835芯片资料及代码49行和52行内容可知占空比应为N/M=(RANGE/4)/RANGE=256/1024,平衡模式力求任意一段时间占空比都最接近N/M=1/4,即把256个高电平时钟周期平均的分配到1024个之中周期中,可以这样进行处理,每4个时钟周期为一组,其中的一个周期内为高电平,这样即可实现“平衡”,这时真实的PWM输出帧率为1.2MHz/4=300KHz,如以上左图所示;对于MarkSpace模式来说,占空比为M/S=(RANGE/4)/RANGE=256/1024,这种模式不需要进行平衡,即可以认为1024个时钟周期的前256个为高电平,其余的为低电平,这时真实的PWM输出帧率为1.2MHz/1024=1171.875Hz,如以上右图所示。

2 树莓派播放音乐

2.1 乐理知识

一首乐曲有若干音符组成,每个音符由音调和演奏时间组成。不同的音调在物理上就对应不同频率的音波。所以我们只要控制输出的频率和时长就能输出一首音乐了。当然实际的音乐很复杂,又有连接,还有重音什么的,这个就先不在讨论范围内了。

每个音符都会播放一定的时间,这样就能构成一首歌曲。在音乐上,音符节奏分为1拍、1/2拍、1/4拍、1/8拍,假设一拍音符的时间为1;半拍为0.5;1/4拍为0.25;1/8拍为0.125……,所以我们可以为每个音符赋予这样的拍子播放出来,音乐就成了。

Arduino官方网站给出了不同音符对应的不同频率的头文件pitches.h,相关内容可以参考博文,在本文我们把pitches.h文件直接应用到树莓派,该文件内容如下:

 1 /*************************************************
 2  * Public Constants
 3  *************************************************/
 4
 5 #define NOTE_B0  31
 6 #define NOTE_C1  33
 7 #define NOTE_CS1 35
 8 #define NOTE_D1  37
 9 #define NOTE_DS1 39
10 #define NOTE_E1  41
11 #define NOTE_F1  44
12 #define NOTE_FS1 46
13 #define NOTE_G1  49
14 #define NOTE_GS1 52
15 #define NOTE_A1  55
16 #define NOTE_AS1 58
17 #define NOTE_B1  62
18 #define NOTE_C2  65
19 #define NOTE_CS2 69
20 #define NOTE_D2  73
21 #define NOTE_DS2 78
22 #define NOTE_E2  82
23 #define NOTE_F2  87
24 #define NOTE_FS2 93
25 #define NOTE_G2  98
26 #define NOTE_GS2 104
27 #define NOTE_A2  110
28 #define NOTE_AS2 117
29 #define NOTE_B2  123
30 #define NOTE_C3  131
31 #define NOTE_CS3 139
32 #define NOTE_D3  147
33 #define NOTE_DS3 156
34 #define NOTE_E3  165
35 #define NOTE_F3  175
36 #define NOTE_FS3 185
37 #define NOTE_G3  196
38 #define NOTE_GS3 208
39 #define NOTE_A3  220
40 #define NOTE_AS3 233
41 #define NOTE_B3  247
42 #define NOTE_C4  262
43 #define NOTE_CS4 277
44 #define NOTE_D4  294
45 #define NOTE_DS4 311
46 #define NOTE_E4  330
47 #define NOTE_F4  349
48 #define NOTE_FS4 370
49 #define NOTE_G4  392
50 #define NOTE_GS4 415
51 #define NOTE_A4  440
52 #define NOTE_AS4 466
53 #define NOTE_B4  494
54 #define NOTE_C5  523
55 #define NOTE_CS5 554
56 #define NOTE_D5  587
57 #define NOTE_DS5 622
58 #define NOTE_E5  659
59 #define NOTE_F5  698
60 #define NOTE_FS5 740
61 #define NOTE_G5  784
62 #define NOTE_GS5 831
63 #define NOTE_A5  880
64 #define NOTE_AS5 932
65 #define NOTE_B5  988
66 #define NOTE_C6  1047
67 #define NOTE_CS6 1109
68 #define NOTE_D6  1175
69 #define NOTE_DS6 1245
70 #define NOTE_E6  1319
71 #define NOTE_F6  1397
72 #define NOTE_FS6 1480
73 #define NOTE_G6  1568
74 #define NOTE_GS6 1661
75 #define NOTE_A6  1760
76 #define NOTE_AS6 1865
77 #define NOTE_B6  1976
78 #define NOTE_C7  2093
79 #define NOTE_CS7 2217
80 #define NOTE_D7  2349
81 #define NOTE_DS7 2489
82 #define NOTE_E7  2637
83 #define NOTE_F7  2794
84 #define NOTE_FS7 2960
85 #define NOTE_G7  3136
86 #define NOTE_GS7 3322
87 #define NOTE_A7  3520
88 #define NOTE_AS7 3729
89 #define NOTE_B7  3951
90 #define NOTE_C8  4186
91 #define NOTE_CS8 4435
92 #define NOTE_D8  4699
93 #define NOTE_DS8 4978

pitches.h

可以看到,这是一张类似表格的东西,里面是定义的大量的宏,即用宏名代替了频率名,对应到键盘的各个按键上。我们需要对应相应的音符到宏名上,为了实现这个首先看看钢琴大谱表与钢琴琴键的对照表:

为了将个音符的音名直观的看出来,给出以下表格:

2.2 播放音乐

对照以上表格及射雕英雄传主题曲铁血丹心简谱实现树莓派播放,铁血丹心简谱如下:

上面的简谱中缺少前奏,程序中增加了从其他版本中摘录的前奏部分,主程序tiexuedanxin.c代码如下:

  1 #include <stdio.h>
  2 #include <stdlib.h>
  3 #include <stdint.h>
  4
  5 #include <bcm2835.h>
  6 #include "pitches.h"
  7
  8 #define PWM_CHANNEL 0
  9 typedef struct _TONE{
 10   int freq;
 11   int t_ms;
 12 } TONE,*PTONE;
 13
 14 int pin = RPI_GPIO_P1_12;
 15 int baseFreq = 600000;          // BCM2835_PWM_CLOCK_DIVIDER_32 对应600KHz
 16
 17 typedef struct _melodyNode{
 18   int note;
 19   float fDuration;
 20 }melodyNode;
 21
 22 melodyNode melody[]= {
 23   // 1
 24   {NOTE_A4, 1.5},      // 6
 25   {NOTE_G4, 0.5},      // 5
 26   {NOTE_A4, 1},        // 6
 27   {NOTE_G4, 0.5},      // 5
 28   {NOTE_E4, 0.5},      // 3
 29
 30   // 2
 31   {NOTE_G4, 1},        // 5
 32   {NOTE_D4, 3},        // 2
 33
 34   // 3
 35   {NOTE_C4, 1.5},      // 1
 36   {NOTE_A3, 0.5},      // .6
 37   {NOTE_D4, 0.5},      // 2
 38   {NOTE_E4, 0.5},      // 3
 39   {NOTE_G4, 0.5},      // 5
 40   {NOTE_F4, 0.5},      // 4
 41
 42   // 4
 43   {NOTE_E4, 3},        // 3
 44   {NOTE_E4, 0.5},      // 3
 45   {NOTE_G4, 0.5},      // 5
 46
 47   // 5
 48   {NOTE_A4, 1.5},      // 6
 49   {NOTE_G4, 0.5},      // 5
 50   {NOTE_A4, 1},        // 6
 51   {NOTE_G4, 0.5},      // 5
 52   {NOTE_E4, 0.5},      // 5
 53
 54   // 6
 55   {NOTE_G4, 1},        // 5
 56   {NOTE_D4, 3},        // 2
 57
 58   // 7
 59   {NOTE_C4, 1.5},      // 1
 60   {NOTE_A3, 0.5},      // .6
 61   {NOTE_D4, 0.5},      // 2
 62   {NOTE_E4, 0.5},      // 3
 63   {NOTE_G3, 0.5},      // .5
 64   {NOTE_B3, 0.5},      // .7
 65
 66   // 8
 67   {NOTE_A3, 4},        // .6
 68
 69   {0, 1},              // 0
 70   {NOTE_E4, 0.5},      // 3
 71   {NOTE_D4, 0.5},      // 2
 72   {NOTE_C4, 1.5},      // 1
 73   {NOTE_B3, 0.5},      // .7
 74
 75   //
 76   {NOTE_A3, 1.5},      // .6
 77   {NOTE_E3, 0.5},      // .3
 78   {NOTE_A3, 2},        // .6
 79
 80   //{NOTE_A3, 1},        // .6
 81   {NOTE_A4, 0.5},      // 6
 82   {NOTE_G4, 0.5},      // 5
 83   {NOTE_E4, 1},        // 3
 84   {NOTE_G4, 0.5},      // 5
 85   {NOTE_D4, 0.5},      // 2
 86
 87   {NOTE_E4, 3},        // 3
 88
 89   {NOTE_E4, 0.5},      // 3
 90   {NOTE_D4, 0.5},      // 2
 91   {NOTE_C4, 1.5},      // 1
 92   {NOTE_B3, 0.5},      // .7
 93
 94   {NOTE_A3, 1.5},        // .6
 95   {NOTE_E3, 0.5},        // .6
 96   {NOTE_A3, 2},          // .6
 97
 98   {0, 1},              // 0
 99   {NOTE_D4, 0.5},      // 2
100   {NOTE_C4, 0.5},      // 1
101   {NOTE_A3, 1},        // .6
102   {NOTE_C4, 0.5},      // 1
103   {NOTE_D4, 0.5},      // 1
104
105   {NOTE_E4, 3},        // 3*/
106   {NOTE_E4, 1},        // 3 逐草四方
107
108   {NOTE_A4, 1.5},      // 6
109   {NOTE_G4, 0.5},      // 5
110   {NOTE_A4, 1},        // 6
111   {NOTE_G4, 0.5},      // 5
112   {NOTE_E4, 0.5},      // 3
113
114   {NOTE_G4, 1},        // 5
115   {NOTE_D4, 3},        // 2
116
117   {NOTE_C4, 1.5},      // 1
118   {NOTE_A3, 0.5},      // .6
119   {NOTE_D4, 0.5},      // 2
120   {NOTE_E4, 0.5},      // 3
121   {NOTE_G4, 0.5},      // 5
122   {NOTE_FS4, 0.5},     // #4
123
124   {NOTE_E4, 3},        // 3
125   {NOTE_E4, 0.5},      // 3
126   {NOTE_G4, 0.5},      // 5
127
128   {NOTE_A4, 1.5},      // 6
129   {NOTE_G4, 0.5},      // 5
130   {NOTE_A4, 1.0},      // 6
131   {NOTE_G4, 0.5},      // 5
132   {NOTE_E4, 0.5},      // 3
133
134   {NOTE_G4, 1.0},      // 5
135   {NOTE_D4, 3},        // 2
136
137   {NOTE_C4, 1.5},      // 1
138   {NOTE_A3, 0.5},      // .6
139   {NOTE_D4, 0.5},      // 2
140   {NOTE_E4, 0.5},      // 3
141   {NOTE_G3, 0.5},      // .5
142   {NOTE_B3, 0.5},      // .7
143
144   {NOTE_A3, 3},         // .6
145
146   {0, 1},              // 0
147   {NOTE_E4, 0.5},      // 3 应知爱意似
148   {NOTE_D4, 0.5},      // 2
149   {NOTE_C4, 1.0},      // 1
150   {NOTE_C4, 0.5},      // 1
151   {NOTE_B3, 0.5},      // .7
152
153   {NOTE_A3, 1.5},      // .6
154   {NOTE_E3, 0.5},      // .3
155   {NOTE_A3, 2.0},      // .6
156
157   {0, 1},              // 0
158   {NOTE_A3, 0.5},      // .6
159   {NOTE_G3, 0.5},      // .5
160   {NOTE_E3, 1.0},      // .3
161   {NOTE_G3, 0.5},      // .5
162   {NOTE_D3, 0.5},      // .2
163
164   {NOTE_E3, 3.0},      // .3
165
166   {0, 1},              // 0
167   {NOTE_E4, 0.5},      // 3 身经百劫也
168   {NOTE_D4, 0.5},      // 2
169   {NOTE_C4, 1.0},      // 1
170   {NOTE_C4, 0.5},      // 1
171   {NOTE_B3, 0.5},      // .7
172
173   {NOTE_A3, 1.5},      // .6
174   {NOTE_E4, 0.5},      // 3
175   {NOTE_D4, 2.0},      // 2
176
177   {0, 1},              // 0
178   {NOTE_D4, 0.5},      // 2
179   {NOTE_C4, 0.5},      // 1
180   {NOTE_A3, 1.0},      // .6
181   {NOTE_B3, 0.5},      // .7
182   {NOTE_G3, 0.5},      // .5
183
184   {NOTE_A3, 3.0},      // .6
185 };
186
187 void beep(int freq, int t_ms)
188 {
189     int range;
190     /*if(freq<2000||freq>5000)
191     {
192         printf("invalid freq\n");
193         return;
194     }*/
195     if(freq == 0)
196         range=1;
197     else
198         range=baseFreq/freq;
199     printf("will call bcm2835_pwm_set_range freq: %d range: %d\n", freq, range);
200     bcm2835_pwm_set_range(PWM_CHANNEL, range);
201     bcm2835_pwm_set_data(PWM_CHANNEL, range/2);
202     if(t_ms>0)
203     {
204         delay(t_ms);
205     }
206 }
207
208 void init()
209 {
210     if (!bcm2835_init())
211         exit (1) ;
212
213     printf("will init pin %d\n", pin);
214     // Set the output pin to Alt Fun 5, to allow PWM channel 0 to be output there
215     bcm2835_gpio_fsel(pin, BCM2835_GPIO_FSEL_ALT5);
216     bcm2835_pwm_set_clock(BCM2835_PWM_CLOCK_DIVIDER_32);
217     bcm2835_pwm_set_mode(PWM_CHANNEL, 1, 1);
218 }
219
220 int main (void)
221 {
222     int index=0;
223     int nLen = sizeof(melody)/sizeof(melody[0]);
224     init();
225
226     for ( ; index<nLen; index++)
227     {
228         int noteDuration = 600*melody[index].fDuration;
229         beep(melody[index].note, noteDuration);
230         printf("will call bcm2835_pwm_set_data 0 after beep\n");
231         bcm2835_pwm_set_data(PWM_CHANNEL, 0);
232         printf("index: %d nLen: %d@@@@@@@@@@@@\n", index, nLen);
233         //delay(100);
234     }
235
236     bcm2835_pwm_set_data(PWM_CHANNEL, 0);
237     bcm2835_close();
238
239     return 0 ;
240 }

tiexuedanxin

注意代码中195行做了特殊处理,这时候频率并不是为0,只是让树莓派不再发声。

转载于:https://www.cnblogs.com/zhaoweiwei/p/RaspberryMusic.html

详解树莓派Model B+控制蜂鸣器演奏乐曲相关推荐

  1. 玩转树莓派---详解树莓派的系统烧录,基础使用及基于树莓派制作手势控制的小车(附详细代码及演示效果)

    目录 一.写在前面 二.系统实现: Author:qyan.li Date:2022.6.10 Topic:详解树莓派的使用及基于树莓派制作手势控制的小车 Reference:如何给树莓派安装操作系统 ...

  2. MQTT协议详解 三、MQTT控制包(CONNECT)

    文章目录 系列文章目录 前言 CONNECT(客户端请求连接服务端) 一.固定包头(2字节) 二.可变包头(10字节) 协议名字(6字节) 协议等级(1字节) 连接标识(1字节) Clean Sess ...

  3. 详解Unity的移动控制实现

    前言 上一篇写了数种Unity中的移动方式,有物理移动,有非物理移动等,这篇我们来谈谈Unity中的移动控制方式,来结合上一篇所说的方法,用起来.一般控制是通过获取用户输入来处理角色移动逻辑的,而用户 ...

  4. MQTT协议详解 二、MQTT控制包格式

    文章目录 系列文章目录 前言 一.MQTT控制包格式 二.固定包头 控制包类型 控制包类型标识 剩余长度 三.可变包头 数据包标识 四.载荷 系列文章目录 MQTT协议详解 一.MQTT简介 MQTT ...

  5. 详解spring的IOC控制反转和DI依赖注入

    转载 详解spring的IOC控制反转和DI依赖注入 2018-06-05 15:45:34 jiuqijack 阅读数 2945 文章标签: spring IOC控制反转 DI依赖注入 更多 分类专 ...

  6. 51单片机蜂鸣器演奏《小苹果》C语言程序,单片机控制蜂鸣器演奏音阶实例

    单片机可以控制蜂鸣器发声音 蜂鸣器是非常常见的发音元器,音乐卡.报警装置.电子琴.各种小家电等都会用到.单片机的PWM功能可以设置输出不同频率的信号,所以我们可以利用单片机的PWM控制三极管的通断来推 ...

  7. java condition详解_Java使用Condition控制线程通信的方法实例详解

    Java使用Condition控制线程通信的方法实例详解 发布于 2020-4-20| 复制链接 摘记: 本文实例讲述了Java使用Condition控制线程通信的方法.分享给大家供大家参考,具体如下 ...

  8. php怎么自定义设置打印区域,JavaScript_jQuery实现区域打印功能代码详解,使用CSS控制打印样式,需要设 - phpStudy...

    jQuery实现区域打印功能代码详解 使用CSS控制打印样式,需要设置样式media="print",并且将页面中不需要打印的元素的样式display属性设置为none.如DEMO ...

  9. php output详解,PHP输出缓冲控制Output Control系列函数详解,output函数详解

    PHP输出缓冲控制Output Control系列函数详解,output函数详解 概述 以前研究过PHP的输入输出缓冲,不过博客搬家以后,原来文章找不到了,今天看到一篇好文,顺便转载过来. 简介 说到 ...

最新文章

  1. html 多项选择,选项标签中的HTML多字段选择
  2. FPGA设计中MEMORY型数据怎么综合到blockRAM里面
  3. Liferay 集群 (fail-over)
  4. python查看模块功能_Python模块Os系统功能
  5. action怎么获得 ajax date参数_ajax()gt;load()事件的新用法!!!
  6. java scanner类 构造器,Java Scanner类
  7. RAP框架练习(续)
  8. 毕业后想拿大厂offer?你得完整拥有这些计算机知识体系!
  9. 6467t 1080php,DM6467T开发板领航——开发环境的文件配置
  10. SQL Server 数据库之字符串函数
  11. linux上apk免杀,kali 免杀工具shellter安装以及使用(示例代码)
  12. 手机浏览器获取某东cookie
  13. CFD(计算流体动力学)在直升机中的应用
  14. python 多态app_Python——多态
  15. 1905 杨辉三角
  16. pip的安装,更新,卸载模块以及使用方法 python
  17. 定时开机-开机自动运行程序-定时关机(windows 下)
  18. python按照号段生成手机号接收验证码,「 python 」 python 实现短信验证码
  19. 当前发布的sku信息中包含疑似与商品无关的字段,请核实修改后重新提交
  20. C#如何开发扫雷游戏

热门文章

  1. Gromacs安装教程及一些思考
  2. 二进制方式搭建kubernetes集群-部署master组件
  3. 外卖系统注意功能源码
  4. 数二-多元函数可微性
  5. 手机号码转码_手机号码导入数据库乱码
  6. 商用密码应用与安全性评估要点笔记(密码标准和产品)
  7. java连oracle代码,连oracle
  8. VUE预览PDF文件并利用pdf.js获取鼠标选中的文字和搜索,在iframe中获取选中文字,监听鼠标事件,右键菜单
  9. 独立架设车牌识别服务器
  10. 半导体产业,城市,发展讨论