CH32V003,自带运放、SPI、PWM等外设模块,关键还便宜,便宜,便宜!

可以尝试来实现一个低成本的音乐谱显示。

1. 硬件设计

显示方面,使用64颗ws2812组成8*8的显示阵列,通过 CH32V003 的SPI模拟ws2812的时序进行驱动。

音频采集,使用CH32V003内部运放+麦克风即可。

整体硬件原理图如下:

2. SPI 驱动 ws2812

2.1 ws2812 简介

ws2812 将控制电路和RGB灯集成在一个封装中,通过级联,MCU使用 800Kbps 单线通讯即可完成 30fps 下1024个ws2812灯的控制。

通讯协议如下:

不同厂家生产的 ws2812 时序可能有区别,不过一般在误差范围内都可以识别。

2.2 SPI+DMA模拟ws2812时序

通过上一节对 ws2812 时序的介绍,完成一个 ws2812 控制需要发送 24bit GRB 的颜色数据,比特率为 800Kbps。

为了可以使用 SPI 模拟 ws2812 的时序,需要将 GRB 颜色数据中每 1 个 bit 膨胀为 4 个 bit,即:

  • 1 表示为:1110
  • 0 表示为:1000

这样 0 bit 中高电平约占 1/4,低电平约占 3/4。1 bit 中高电平约占 3/4,低电平约占 1/4。符合通讯协议。

此时,驱动一个 ws2812,SPI MOSI 引脚需要发送 4 x 24 bits = 12 Bytes。SPI 的时钟频率设置为 800 x 4 = 3.2MHz 左右。

CH32V003 主频设置为 48MHz, SPI 设置 16 分频,为 3MHz,在误差范围内,实测可以正常驱动WS2812。

代码如下:

/**
* @brief
*
* @param ws2812_bit_buffer
* @param ws2812_byte_buffer
*
* 1bit 膨胀位 4bit
* 1:1110
* 0:1000
*/
void ws2812_set_grb(ws2812_bit_buffer_t *ws2812_bit_buffer, ws2812_byte_buffer_t *ws2812_byte_buffer)
{
ws2812_byte_buffer_t ws2812_color_data =
{
.green = ws2812_byte_buffer->green,
.red = ws2812_byte_buffer->red,
.blue = ws2812_byte_buffer->blue
}; for(uint8_t i = 0; i<4; i++)
{
ws2812_bit_buffer->green >>= 8;
ws2812_bit_buffer->red >>= 8;
ws2812_bit_buffer->blue >>= 8;
/**
* @brief
* 每 2 bit 的 RGB 数据膨胀为 1byte 的 spi 数据
* 每个 byte 中,第 8bit 和第 3bit 位固定为 1,第 4bit 和第 0bit 位固定为 0,剩余 bit 根据颜色值设定
*/
ws2812_bit_buffer->green |= ( 0x88 | ((ws2812_color_data.green & 0x80)>>1) | ((ws2812_color_data.green & 0x80)>>2)| \
((ws2812_color_data.green & 0x40)>>4) | ((ws2812_color_data.green & 0x40)>>5) )<<24;
ws2812_bit_buffer->red |= ( 0x88 | ((ws2812_color_data.red & 0x80)>>1) | ((ws2812_color_data.red & 0x80)>>2)| \
((ws2812_color_data.red & 0x40)>>4) | ((ws2812_color_data.red & 0x40)>>5) )<<24;
ws2812_bit_buffer->blue |= ( 0x88 | ((ws2812_color_data.blue & 0x80)>>1) | ((ws2812_color_data.blue & 0x80)>>2)| \
((ws2812_color_data.blue & 0x40)>>4) | ((ws2812_color_data.blue & 0x40)>>5) )<<24; ws2812_color_data.green <<= 2;
ws2812_color_data.red <<= 2;
ws2812_color_data.blue <<= 2;
}
}

MOSI 输出时序如下:

时序模拟正确后,就可以将需要显示的颜色数据准备好,通过DMA+SPI推出去即可。

2.3 将 HSV 转化为 RGB

HSV 表达彩色图像的方式由三个部分组成:

  • Hue(色调、色相)。Hue 用角度度量,取值范围为0~360°,表示色彩信息,即所处的光谱颜色的位置。如Hue=0 表示红色,Hue=120 表示绿色,Hue=240 表示蓝色等等
  • Saturation(饱和度、色彩纯净度)。饱和度表示颜色接近光谱色的程度。饱和度越高,说明颜色越深,越接近光谱色饱和度越低,说明颜色越浅,越接近白色。饱和度为0表示纯白色。取值范围为0~100%,值越大,颜色越饱和。
  • Value(明度)。 明度决定颜色空间中颜色的明暗程度,明度越高,表示颜色越明亮,范围是 0-100%。明度为0表示纯黑色(此时颜色最暗)。

HSV 转化成 RGB 的方法如下:

:::tip参考wiki

:::

因为HSV使用起来更加直观、方便,所以代码逻辑部分通常使用 HSV。但WS2812B 灯珠的驱动使用的是RGB,所以需要进行转换。

参考代码如下:

/**
* @brief 将HSV颜色空间转换为RGB颜色空间
*
* @param h HSV颜色空间的H:色调。单位°,范围0~360。(Hue 调整颜色,0°-红色,120°-绿色,240°-蓝色,以此类推)
* @param s HSV颜色空间的S:饱和度。单位%,范围0~100。(Saturation 饱和度高,颜色深而艳;饱和度低,颜色浅而发白)
* @param v HSV颜色空间的V:明度。单位%,范围0~100。(Value 控制明暗,明度越高亮度越亮,越低亮度越低)
* @param rgb_buffer RGB值的指针
*
* Wiki: https://en.wikipedia.org/wiki/HSL_and_HSV
*
*/
void ws2812_hsv2rgb(uint32_t h, uint32_t s, uint32_t v, ws2812_byte_buffer_t *rgb_buffer)
{
h %= 360; // h -> [0,360]
uint32_t rgb_max = v * 2.55f;
uint32_t rgb_min = rgb_max * (100 - s) / 100.0f; uint32_t i = h / 60;
uint32_t diff = h % 60; // RGB adjustment amount by hue
uint32_t rgb_adj = (rgb_max - rgb_min) * diff / 60; switch (i) {
case 0:
rgb_buffer->red = rgb_max;
rgb_buffer->green = rgb_min + rgb_adj;
rgb_buffer->blue = rgb_min;
break;
case 1:
rgb_buffer->red = rgb_max - rgb_adj;
rgb_buffer->green = rgb_max;
rgb_buffer->blue = rgb_min;
break;
case 2:
rgb_buffer->red = rgb_min;
rgb_buffer->green = rgb_max;
rgb_buffer->blue = rgb_min + rgb_adj;
break;
case 3:
rgb_buffer->red = rgb_min;
rgb_buffer->green = rgb_max - rgb_adj;
rgb_buffer->blue = rgb_max;
break;
case 4:
rgb_buffer->red = rgb_min + rgb_adj;
rgb_buffer->green = rgb_min;
rgb_buffer->blue = rgb_max;
break;
default:
rgb_buffer->red = rgb_max;
rgb_buffer->green = rgb_min;
rgb_buffer->blue = rgb_max - rgb_adj;
break;
}
}

使用HSV,可以轻松实现呼吸灯的效果:

3. 麦克风采集音频

3.1 OPA+ADC+DMA 采集音频

因为 CH32V003 内部自带 OPA 运放,所以外围只需接上麦克风,搭好放大电路,即可开启 ADC 采集数据。

考虑到平常我们听到的音乐频率一般都低于5KHz,所以将 ADC 的采样频率设置为10KHz。

ADC 通过定时器 TRGO 事件触发采集。

启用 DMA 搬运 ADC 采集结果。

3.2 FFT 分析频谱

音乐谱,最重要的还得分析出频谱,这时候就得靠 FFT 了,参考了网上大牛的超简洁 FFT 算法,代码如下:

点击查看代码
/* fix_fft.c - Fixed-point in-place Fast Fourier Transform  */
/*
All data are fixed-point short integers, in which -32768
to +32768 represent -1.0 to +1.0 respectively. Integer
arithmetic is used for speed, instead of the more natural
floating-point.
For the forward FFT (time -> freq), fixed scaling is
performed to prevent arithmetic overflow, and to map a 0dB
sine/cosine wave (i.e. amplitude = 32767) to two -6dB freq
coefficients. The return value is always 0.
For the inverse FFT (freq -> time), fixed scaling cannot be
done, as two 0dB coefficients would sum to a peak amplitude
of 64K, overflowing the 32k range of the fixed-point integers.
Thus, the fix_fft() routine performs variable scaling, and
returns a value which is the number of bits LEFT by which
the output must be shifted to get the actual amplitude
(i.e. if fix_fft() returns 3, each value of fr[] and fi[]
must be multiplied by 8 (2**3) for proper scaling.
Clearly, this cannot be done within fixed-point short
integers. In practice, if the result is to be used as a
filter, the scale_shift can usually be ignored, as the
result will be approximately correctly normalized as is.
Written by: Tom Roberts 11/8/89
Made portable: Malcolm Slaney 12/15/94 malcolm@interval.com
Enhanced: Dimitrios P. Bouras 14 Jun 2006 dbouras@ieee.org
*/
#include "fix_fft.h" #define N_WAVE 1024 /* full length of Sinewave[] */
#define LOG2_N_WAVE 10 /* log2(N_WAVE) */ /*
Henceforth "short" implies 16-bit word. If this is not
the case in your architecture, please replace "short"
with a type definition which *is* a 16-bit word.
*/ /*
Since we only use 3/4 of N_WAVE, we define only
this many samples, in order to conserve data space.
*/
const int16_t Sinewave[N_WAVE-N_WAVE/4] = {
0, 201, 402, 603, 804, 1005, 1206, 1406,
1607, 1808, 2009, 2209, 2410, 2610, 2811, 3011,
3211, 3411, 3611, 3811, 4011, 4210, 4409, 4608,
4807, 5006, 5205, 5403, 5601, 5799, 5997, 6195,
6392, 6589, 6786, 6982, 7179, 7375, 7571, 7766,
7961, 8156, 8351, 8545, 8739, 8932, 9126, 9319,
9511, 9703, 9895, 10087, 10278, 10469, 10659, 10849,
11038, 11227, 11416, 11604, 11792, 11980, 12166, 12353,
12539, 12724, 12909, 13094, 13278, 13462, 13645, 13827,
14009, 14191, 14372, 14552, 14732, 14911, 15090, 15268,
15446, 15623, 15799, 15975, 16150, 16325, 16499, 16672,
16845, 17017, 17189, 17360, 17530, 17699, 17868, 18036,
18204, 18371, 18537, 18702, 18867, 19031, 19194, 19357,
19519, 19680, 19840, 20000, 20159, 20317, 20474, 20631,
20787, 20942, 21096, 21249, 21402, 21554, 21705, 21855,
22004, 22153, 22301, 22448, 22594, 22739, 22883, 23027,
23169, 23311, 23452, 23592, 23731, 23869, 24006, 24143,
24278, 24413, 24546, 24679, 24811, 24942, 25072, 25201,
25329, 25456, 25582, 25707, 25831, 25954, 26077, 26198,
26318, 26437, 26556, 26673, 26789, 26905, 27019, 27132,
27244, 27355, 27466, 27575, 27683, 27790, 27896, 28001,
28105, 28208, 28309, 28410, 28510, 28608, 28706, 28802,
28897, 28992, 29085, 29177, 29268, 29358, 29446, 29534,
29621, 29706, 29790, 29873, 29955, 30036, 30116, 30195,
30272, 30349, 30424, 30498, 30571, 30643, 30713, 30783,
30851, 30918, 30984, 31049, 31113, 31175, 31236, 31297,
31356, 31413, 31470, 31525, 31580, 31633, 31684, 31735,
31785, 31833, 31880, 31926, 31970, 32014, 32056, 32097,
32137, 32176, 32213, 32249, 32284, 32318, 32350, 32382,
32412, 32441, 32468, 32495, 32520, 32544, 32567, 32588,
32609, 32628, 32646, 32662, 32678, 32692, 32705, 32717,
32727, 32736, 32744, 32751, 32757, 32761, 32764, 32766,
32767, 32766, 32764, 32761, 32757, 32751, 32744, 32736,
32727, 32717, 32705, 32692, 32678, 32662, 32646, 32628,
32609, 32588, 32567, 32544, 32520, 32495, 32468, 32441,
32412, 32382, 32350, 32318, 32284, 32249, 32213, 32176,
32137, 32097, 32056, 32014, 31970, 31926, 31880, 31833,
31785, 31735, 31684, 31633, 31580, 31525, 31470, 31413,
31356, 31297, 31236, 31175, 31113, 31049, 30984, 30918,
30851, 30783, 30713, 30643, 30571, 30498, 30424, 30349,
30272, 30195, 30116, 30036, 29955, 29873, 29790, 29706,
29621, 29534, 29446, 29358, 29268, 29177, 29085, 28992,
28897, 28802, 28706, 28608, 28510, 28410, 28309, 28208,
28105, 28001, 27896, 27790, 27683, 27575, 27466, 27355,
27244, 27132, 27019, 26905, 26789, 26673, 26556, 26437,
26318, 26198, 26077, 25954, 25831, 25707, 25582, 25456,
25329, 25201, 25072, 24942, 24811, 24679, 24546, 24413,
24278, 24143, 24006, 23869, 23731, 23592, 23452, 23311,
23169, 23027, 22883, 22739, 22594, 22448, 22301, 22153,
22004, 21855, 21705, 21554, 21402, 21249, 21096, 20942,
20787, 20631, 20474, 20317, 20159, 20000, 19840, 19680,
19519, 19357, 19194, 19031, 18867, 18702, 18537, 18371,
18204, 18036, 17868, 17699, 17530, 17360, 17189, 17017,
16845, 16672, 16499, 16325, 16150, 15975, 15799, 15623,
15446, 15268, 15090, 14911, 14732, 14552, 14372, 14191,
14009, 13827, 13645, 13462, 13278, 13094, 12909, 12724,
12539, 12353, 12166, 11980, 11792, 11604, 11416, 11227,
11038, 10849, 10659, 10469, 10278, 10087, 9895, 9703,
9511, 9319, 9126, 8932, 8739, 8545, 8351, 8156,
7961, 7766, 7571, 7375, 7179, 6982, 6786, 6589,
6392, 6195, 5997, 5799, 5601, 5403, 5205, 5006,
4807, 4608, 4409, 4210, 4011, 3811, 3611, 3411,
3211, 3011, 2811, 2610, 2410, 2209, 2009, 1808,
1607, 1406, 1206, 1005, 804, 603, 402, 201,
0, -201, -402, -603, -804, -1005, -1206, -1406,
-1607, -1808, -2009, -2209, -2410, -2610, -2811, -3011,
-3211, -3411, -3611, -3811, -4011, -4210, -4409, -4608,
-4807, -5006, -5205, -5403, -5601, -5799, -5997, -6195,
-6392, -6589, -6786, -6982, -7179, -7375, -7571, -7766,
-7961, -8156, -8351, -8545, -8739, -8932, -9126, -9319,
-9511, -9703, -9895, -10087, -10278, -10469, -10659, -10849,
-11038, -11227, -11416, -11604, -11792, -11980, -12166, -12353,
-12539, -12724, -12909, -13094, -13278, -13462, -13645, -13827,
-14009, -14191, -14372, -14552, -14732, -14911, -15090, -15268,
-15446, -15623, -15799, -15975, -16150, -16325, -16499, -16672,
-16845, -17017, -17189, -17360, -17530, -17699, -17868, -18036,
-18204, -18371, -18537, -18702, -18867, -19031, -19194, -19357,
-19519, -19680, -19840, -20000, -20159, -20317, -20474, -20631,
-20787, -20942, -21096, -21249, -21402, -21554, -21705, -21855,
-22004, -22153, -22301, -22448, -22594, -22739, -22883, -23027,
-23169, -23311, -23452, -23592, -23731, -23869, -24006, -24143,
-24278, -24413, -24546, -24679, -24811, -24942, -25072, -25201,
-25329, -25456, -25582, -25707, -25831, -25954, -26077, -26198,
-26318, -26437, -26556, -26673, -26789, -26905, -27019, -27132,
-27244, -27355, -27466, -27575, -27683, -27790, -27896, -28001,
-28105, -28208, -28309, -28410, -28510, -28608, -28706, -28802,
-28897, -28992, -29085, -29177, -29268, -29358, -29446, -29534,
-29621, -29706, -29790, -29873, -29955, -30036, -30116, -30195,
-30272, -30349, -30424, -30498, -30571, -30643, -30713, -30783,
-30851, -30918, -30984, -31049, -31113, -31175, -31236, -31297,
-31356, -31413, -31470, -31525, -31580, -31633, -31684, -31735,
-31785, -31833, -31880, -31926, -31970, -32014, -32056, -32097,
-32137, -32176, -32213, -32249, -32284, -32318, -32350, -32382,
-32412, -32441, -32468, -32495, -32520, -32544, -32567, -32588,
-32609, -32628, -32646, -32662, -32678, -32692, -32705, -32717,
-32727, -32736, -32744, -32751, -32757, -32761, -32764, -32766,
}; /*
FIX_MPY() - fixed-point multiplication & scaling.
Substitute inline assembly for hardware-specific
optimization suited to a particluar DSP processor.
Scaling ensures that result remains 16-bit.
*/
int16_t FIX_MPY(int16_t a, int16_t b)
{
/* shift right one less bit (i.e. 15-1) */
int c = ((int)a * (int)b) >> 14;
/* last bit shifted out = rounding-bit */
b = c & 0x01;
/* last shift + rounding bit */
a = (c >> 1) + b;
return a;
} /*
fix_fft() - perform forward/inverse fast Fourier transform.
fr[n],fi[n] are real and imaginary arrays, both INPUT AND
RESULT (in-place FFT), with 0 <= n < 2**m; set inverse to
0 for forward transform (FFT), or 1 for iFFT.
*/
int fix_fft(int16_t fr[], int16_t fi[], int16_t m, int16_t inverse)
{
int16_t mr, nn, i, j, l, k, istep, n, scale, shift;
int16_t qr, qi, tr, ti, wr, wi; n = 1 << m; /* max FFT size = N_WAVE */
if (n > N_WAVE)
return -1; mr = 0;
nn = n - 1;
scale = 0; /* decimation in time - re-order data */
for (m=1; m<=nn; ++m) {
l = n;
do {
l >>= 1;
} while (mr+l > nn);
mr = (mr & (l-1)) + l; if (mr <= m)
continue;
tr = fr[m];
fr[m] = fr[mr];
fr[mr] = tr;
ti = fi[m];
fi[m] = fi[mr];
fi[mr] = ti;
} l = 1;
k = LOG2_N_WAVE-1;
while (l < n) {
if (inverse) {
/* variable scaling, depending upon data */
shift = 0;
for (i=0; i<n; ++i) {
j = fr[i];
if (j < 0)
j = -j;
m = fi[i];
if (m < 0)
m = -m;
if (j > 16383 || m > 16383) {
shift = 1;
break;
}
}
if (shift)
++scale;
} else {
/*
fixed scaling, for proper normalization --
there will be log2(n) passes, so this results
in an overall factor of 1/n, distributed to
maximize arithmetic accuracy.
*/
shift = 1;
}
/*
it may not be obvious, but the shift will be
performed on each data point exactly once,
during this pass.
*/
istep = l << 1;
for (m=0; m<l; ++m) {
j = m << k;
/* 0 <= j < N_WAVE/2 */
wr = Sinewave[j+N_WAVE/4];
wi = -Sinewave[j];
if (inverse)
wi = -wi;
if (shift) {
wr >>= 1;
wi >>= 1;
}
for (i=m; i<n; i+=istep) {
j = i + l;
tr = FIX_MPY(wr,fr[j]) - FIX_MPY(wi,fi[j]);
ti = FIX_MPY(wr,fi[j]) + FIX_MPY(wi,fr[j]);
qr = fr[i];
qi = fi[i];
if (shift) {
qr >>= 1;
qi >>= 1;
}
fr[j] = qr - tr;
fi[j] = qi - ti;
fr[i] = qr + tr;
fi[i] = qi + ti;
}
}
--k;
l = istep;
}
return scale;
} /*
fix_fftr() - forward/inverse FFT on array of real numbers.
Real FFT/iFFT using half-size complex FFT by distributing
even/odd samples into real/imaginary arrays respectively.
In order to save data space (i.e. to avoid two arrays, one
for real, one for imaginary samples), we proceed in the
following two steps: a) samples are rearranged in the real
array so that all even samples are in places 0-(N/2-1) and
all imaginary samples in places (N/2)-(N-1), and b) fix_fft
is called with fr and fi pointing to index 0 and index N/2
respectively in the original array. The above guarantees
that fix_fft "sees" consecutive real samples as alternating
real and imaginary samples in the complex array.
*/
int fix_fftr(int16_t f[], int m, int inverse)
{
int i, N = 1<<(m-1), scale = 0;
int16_t tt, *fr=f, *fi=&f[N]; if (inverse)
scale = fix_fft(fi, fr, m-1, inverse);
for (i=1; i<N; i+=2) {
tt = f[N+i-1];
f[N+i-1] = f[i];
f[i] = tt;
}
if (! inverse)
scale = fix_fft(fi, fr, m-1, inverse);
return scale;
}

`int fix_fft(short fr[], short fi[], short m, short inverse)` 是 FFT 算法的计算函数,fr[] 是 ADC 采集到信号值的实部,fi[] 是 ADC 采集到信号值的虚部。经过 `fix_fft` 函数处理之后,fr[] 是 FFT 计算所得的实部,fi[] 是计算所得的虚部。

4. 效果演示

:::tip开源

项目开源地址: https://github.com/Taoyukai/ch32v003_ws2812_music

:::

CH32V00+WS2812制作音乐谱显示的更多相关文章

  1. jQuery - 制作点击显示二级菜单效果

    <!DOCTYPE html> <html> <head lang="en"> <meta charset="UTF-8&quo ...

  2. Qt5制作鼠标悬停显示Hint的ToolTip

    在日常生活中的使用的软件中,我们经常会遇到这样的情况. 我们在网页上,有些网页链接的文字(比如文章标题,知乎问题标题,百度的词条等)因为太长了,而显示不出来,但是鼠标悬停在上面的时候就可以显示出来.  ...

  3. C# Note20: 制作延时改变显示的标题栏

    前言 在使用wpf构建一个窗体时,其中有这样一个功能,在保存数据或加载数据时,我们希望在改变标题栏的显示以标志当前保存成功的状态或者加载数据的名称信息,而且标题信息更新显示几秒后,再恢复到默认的状态. ...

  4. php 制作验证码不显示的问题

    php制作验证码的代码,这里就不多说了,网上有很多的,这里说一些可能遇到的问题. 1. 首先是检查自己的php.ini文件,是否支持gd库. 2.保证代码没有出问题. 3.检查字体文件路径是否正确. ...

  5. jQuery制作鼠标经过显示图片大图,生成图片tips效果

    一般tips都是文字,这个可以支持图片,很漂亮: 演示   <script type="text/javascript"> // Load this script on ...

  6. C# 制作关键字醒目显示控件

    实现方式:WinForm自定义控件,继承系统Label控件实现. 第1步:创建“组件”,取名为:MarkLabel     第2步:修改添加如下代码: /* 添加命名空间引用: * using Sys ...

  7. 个人简历制作(Dreamweaver)

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...

  8. pjsip视频通信开发(上层应用)之数字键盘的制作

    在pjsip视频通信开发(上层应用)之EditText重写中我制作了一个显示输入内容的EditText,这里将制作一个数字键盘,其实跟计算器一样,最多的就是用TableLayout来实现,内部通过权重 ...

  9. iReport 4.1 报表制作,子报表,实例解析

    开发使用步骤(iReport 4.1.1) (个人总结,如有问题请留言,另外知道table控件用法的给我留言或者发邮件谢谢.Email:jiazx0107@163.com) 目录 1.      开发 ...

  10. SpriteBuilder中使用GUI界面快速搭建RPG游戏中的地图名显示动画

    大熊猫猪·侯佩原创或翻译作品.欢迎转载,转载请注明出处. 如果觉得写的不好请告诉我,如果觉得不错请多多支持点赞.谢谢! hopy ;) 在RPG游戏中我们在进入一个新的场景时,比如一个房间,一个村庄, ...

随机推荐

  1. JZOJ 4872.集体照

    \(\text{Problem}\) 一年一度的高考结束了,我校要拍集体照.本届毕业生共分 \(n\) 个班,每个班的人数为 \(A_i\).这次拍集体照的要求非常奇怪:所有学生站一排,且相邻两个学生 ...

  2. rin和快速迭代

    链接:https://ac.nowcoder.com/acm/contest/3002/E rin最近喜欢上了数论. 然而数论实在太复杂了,她只能研究一些简单的问题. 这天,她在研究正整数因子个数的时 ...

  3. 在vs code中进行本地调试和开启本地服务器

    https://blog.csdn.net/tangxiujiang/article/details/80927699

  4. pat乙级:模拟链表问题(汇总,包含所有pat中链表题目分析)

    更新:优化文章结构,增加了部分内容如(1110区块反转)和自己代码和他人代码分析.看完你就懂了 转载请注明出处和链接地址:(https://www.cnblogs.com/ahappyfool/p/1 ...

  5. Integer使用==比较的问题

    Integer使用==比较的问题 new一个对象 public Integer(int value) { this.value = value; } 自动装箱 public static Intege ...

  6. pip使用阿里云镜像

    pip config set global.index-url https://mirrors.aliyun.com/pypi/simple/ pip config set install.trust ...

  7. centos7 部署 loonflow

    a workflow engine base on django 基于django的工作流引擎系统(通过http接口调用,可以作为企业内部统一的工作流引擎,提供诸如权限申请.资源申请.发布申请.请假. ...

  8. DevExpress gridControl 字体居住

    设置列的标题居中显示: Designer - Views -右侧输入框中输入Appearance-HeaderPanel-TextOptions-设置HAlignment为Center 设置单元格内容 ...

  9. ERROR 2003 (HY000): Can't connect to MySQL server on 'localhost:3306' (10061)

    ERROR 2003 (HY000): Can't connect to MySQL server on 'localhost:3306' (10061) 报错原因:电脑之前有个5.0.2版本的mys ...

  10. C++ MFC学习 (一)

    MFC:微软基础类库,以C++形式封装了WindowsAPI,并且包含一个应用程序框架,以减少应用程序开发人员的工作量.    其中包含的类包含大量Windows句柄封装类和很多Windows的内建控 ...