LED音乐频谱之点阵

转载请注明出处:http://blog.youkuaiyun.com/ruoyunliufeng/article/details/37967455

一.硬件

这里的LED选择直插的雾面LED,亮度可以还不失美观。注意每行要加上限流电阻。74HC138(三八译码器)作为列选,每行都连着74HC595(移位寄存器)实现串行输入,并行输出。

       

二.软件

led.h

#ifndef __Led_H
#define __Led_H

#include "STC12C5A.h"

#define uint unsigned int
#define uchar unsigned char
#define light 127

sbit _SER    = P0^0;				// 74hc595 串行数据输入端
sbit _RCLK   = P0^1;				// 74hc595 数据输出时钟线
sbit _SRCLK  = P0^2;				// 74hc595 数据输入时钟线
sbit ACT_Key = P0^3; 				// 模式开关
sbit key1	 = P0^6;				// pwm调节+
sbit Key_2   = P3^3;				// 时钟调节按键


extern void delayled(int );
extern void LineInput(uint dat);
//extern void DisplayTime(void);
//extern void TimeSetting(void);
extern void ruoyun(void);


#endif

led.c

#include "Led.h"


uint   code table1[80]={
0x0C,0x01,0x10,0x11,0xFE,0x11,0x44,0x3F,
0x44,0x11,0x44,0x3D,0x7E,0x11,0x00,0x11,/*"若",0*/

0x00,0x00,0x0C,0x01,0x34,0x11,0xC4,0x11,
0x04,0x11,0x14,0x11,0x0E,0x01,0x00,0x01,/*"云",0*/

0x04,0x10,0xFC,0x1F,0x00,0x1F,0xFC,0x00,
0x00,0x1F,0xFC,0x1F,0x04,0x10,0x00,0x00,/*"M",0*/


0xE0,0x03,0x18,0x0C,0x04,0x10,0x04,0x10,
0x04,0x10,0x08,0x10,0x10,0x1C,0x00,0x00,/*"C",0*/



0x00,0x10,0xF8,0x1F,0x04,0x10,0x04,0x00,
0x04,0x00,0x04,0x10,0xF8,0x1F,0x00,0x10,/*"U",0*/

						};

							
uchar  code ColScan[16]   =  {0x20,0x24,0x22,0x26,0x21,0x25,0x23,0x27,
			     0x10,0x14,0x12,0x16,0x11,0x15,0x13,0x17};					    // 74hc138 进行列扫描
	
void delayled(int z)				// 延时函数
{
	int x,y;
	for(x=0;x<z;x++)
		for(y=0;y<110;y++);
}

void WriteByte(char dat)			//写一个字节的数据
{
	char i;								  
	for(i=0;i<8;i++)				 //循环8次把编码传给锁存器
		{
			dat=dat>>1;				 //右移一位,取出该字节的最低位
			_SER=CY;					 //将该字节的最低位传给R
			_SRCLK=0;					  //将数据取出,上升沿
			_SRCLK=1;
		}
}
void LineInput(uint dat)			   	// 单列数据显示
{
    uchar n;
    _RCLK = 0;
    for(n=0;n<16;n++)
    {
        _SRCLK = 0;
        _SER  = (dat>>n)&0x01;		 //将数据的值串入输入SER中,然后并行输出
        _SRCLK = 1;
    }
    _RCLK = 1;
}

void ruoyun()
{
	int num,k,j;//,move,speed;

		for(k=0;k<25;k++)				  //控制动画移动
		{	for(j=0;j<150;j++)			  //延时
			{
 				for(num=0;num<16;num++)			//控制每一帧
				{
					WriteByte(table1[2*(num+k)]);		 //送出一个字节
					WriteByte(table1[2*(num+k)+1]);
					P2=ColScan[num];						   //行选
					_RCLK=1;							//输出锁存器数据下降沿
					_RCLK=0;
					delayled(2);
				}
			}	
		}				

我想最核心的东西,应该就是怎么通过三个循环实现左移的吧(虽然这样做用来三个循环,现在看来并不是很好),下面详细讲讲这段代码。

代码思路:我们都知道要想实现点阵显示只要向595串行输入16个字模数据就OK了。那么如何叫它向左面移动呢?其实很简单,下面我画图说明:

最里面的那层for循环实现了点阵的显示,就是从左到右刷一遍。

中间那层for循环是一箭双雕,有两个作用,第一个就是为了点阵能够稳定显示,就是快速的多刷几遍(要不刷一遍谁看得清)。第二个作用就是为了向左移动提供延时(要不瞬间不就左移到头了嘛)。其实规范点的写法应该是这个for提供稳定点阵显示,然后外面在加一个延时控制向左移动的速率。后来我看写的太复杂就给省略了。

最外面的那层循环控制的是左移的列数(就是向左移动多少):

		for(k=0;k<25;k++)				  //控制动画移动

K的值代表想做移动的列数,为什么是25,因为一共是5个字每个字占8行              

初始状态:                     *若 云*MCU

终止状态:              若云*MCU*

也就是像左面移动三个字,3*8=24,所以K<25。

最后还有一个LineInput()函数,干嘛用的呢?留个悬念,后续博客讲解。

### ESP32-S3 点阵屏实现频谱显示 为了实现在ESP32-S3上通过点阵屏展示音频信号的频谱图,可以采用以下方法。此过程涉及读取麦克风输入的数据并将其转换成适合视觉化的形式。 #### 初始化硬件连接 确保已正确设置麦克风模块与ESP32-S3之间的I2S接口通信线路,并且点阵显示屏也已经过适当配置以便接收来自微控制器的信息流[^1]。 #### 安装必要的库文件 项目依赖于几个Arduino IDE中的外部库来简化开发工作量: - `Adafruit_GFX` 和 `Adafruit_RGBmatrixPanel`: 这两个库用于控制矩阵LED屏幕。 - `AudioZero`: 提供了处理声音数据的能力,支持FFT变换等功能。 可以通过Arduino库管理器安装上述所需资源。 #### 编写程序框架 下面给出了一段简单的C++代码片段作为起点,它展示了如何获取环境噪音水平并通过调用快速傅里叶变换(FFT)算法计算频率分布情况,最后映射到像素亮度变化上来形成直观的效果。 ```cpp #include <Wire.h> #include <SPI.h> #include "Adafruit_GFX.h" #include "RGBmatrixPanel.h" #include "AudioZero.h" // Define matrix configuration parameters here... #define CLK 18 #define LAT 5 #define OE 4 #define A 0 #define B 1 #define C 2 RGBmatrixPanel matrix(CLK, LAT, OE, A, B, C); const int MIC_PIN = 34; // Microphone analog input pin number. int sampleRate = 16000; unsigned long previousMillis = 0; void setup() { Serial.begin(9600); Audio.setPin(AUDIO_IN_PIN, MIC_PIN); Audio.setSampleRate(sampleRate); } void loop() { unsigned long currentMillis = millis(); if (currentMillis - previousMillis >= 1000 / frameRate) { float spectrum[128]; memset(spectrum, 0, sizeof(float)*128); Audio.analyzeFrequency(spectrum); drawSpectrogram(spectrum); previousMillis = currentMillis; } } void drawSpectrogram(const float* data){ for(int i=0;i<height;i++){ for(int j=0;j<width;j++){ uint16_t colorValue = map(data[i], minValue, maxValue, minColor, maxColor); matrix.drawPixel(j,i,colorValue); } } } ``` 该脚本定义了一个基本的工作流程:初始化串口通讯;指定采样率以及麦克风模拟输入端口号;利用内置函数分析声波特征得到幅度随时间变化曲线;最终绘制对应的光栅图像表示当前捕捉到的声音特性。 请注意以上仅为概念验证性质的例子,在实际应用中可能还需要考虑更多细节因素比如抗混叠滤波、窗口加权等技术手段提升测量精度和稳定性。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

若云流风

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值