【RA】基于瑞萨MCU频谱灯+1051772A
简介
一个基于瑞萨R7FA2L1AB2DFL单片机做的音乐频谱灯,有汉字显示和七色频谱显示功能,显示亮度空调,由于硬件限制,目前只有这些功能
简介:一个基于瑞萨R7FA2L1AB2DFL单片机做的音乐频谱灯,有汉字显示和七色频谱显示功能,显示亮度空调,由于硬件限制,目前只有这些功能开源协议
:GPL 3.0
描述
简介
这是一个基于瑞萨R7FA2L1AB2DFL单片机做的一个音乐频谱灯,屏幕用的是P4全彩单元板,喜欢玩点阵屏的朋友肯定会喜欢上这种“超大号点阵屏”,由于时间仓促,目前只做了频谱功能,后面会改一下PCB,加上亮度自动调节,温度测量,时钟显示的功能(因为这次的板子上面没有光敏电阻,温度传感器,和纽扣电池)
硬件说明
主控:R7FA2L1AB2DFL
音频输入:麦克风/耳机口
运放:NE5532DR
屏幕:P4全彩单元板(256mmx128mm,16扫)
串口:程序下载1
ADC0通道0:采集音频
ADC0通道1:采集环境亮度
按键:预留有四个按键,其中BOOT和RST下载程序用,KEY1和KEY2用来切换模式、颜色、亮度等
PCB上音频采集部分为了减小干扰没有铺铜
后期扩展:将增加光敏电阻用来自动调节亮度,增加DS18B20检测环境温度,增加DS3231时钟模块(可不加),以及纽扣电池,掉电时给时钟供电
软件说明
屏幕驱动
定时器0以100X16HZ的频率扫描屏幕,中断优先级最高(否则会出现屏幕闪烁),为什么屏幕刷新速度要设为这么高?这是与我的驱动方式有关,我这个屏幕是16扫的,一次扫描2行,共32行分16次扫描完,定时器0产生一次更新中断在中断回调函数中我只扫描一次,也就是只扫描2行,所以刷新整个屏幕需要产生16次中断,由此可知屏幕实际刷新率是100X16HZ/16=100HZ,这是很正常的刷新率了。还有另一种扫描方法如下;
可以将定时器0更新中断就设为100HZ,然后再中断回调函数里面一次性扫描16次,这样也能做到100HZ刷新率,且更容易理解,但是这样的话就增加了在中断回调函数中的时间,实测在这款单片机上会影响到while(1)的循环,对于主频更高的单片机是影响很小的。
ADC采集
定时器1用来触发ADC0的通道0采集音频,常见的音频采样频率都是44100HZ,人对10KHz以上的高频声音更加敏感,虽然这部分所携带的能量小,在屏幕上的幅度较小,不过没关系,我专门预留了一个调整幅度的电位器,此电位器可以调剂音频信号的放大倍数,从而能调节频谱显示的幅度(实测有效),根据奈奎斯特定理,采集10KHz的信号,其采样频率不应低于20KHz,所以这里就将采样频率设为20KHz,定时器1用来触发ADC0通道0采用,采用结果通过DTC传输到指定内存(DTC功能与DMA类似)
注:我这里ADC、TIM、DTC没有用ELC事件连接器连接(不会配置(捂脸.jpg))用ELC效果会更好
快速傅里叶变换
原本计划用256点采样,但是实测运算太慢,不得不采用128点才勉强能用(我怀疑是我e2 Studio配置错了,导致单片机运行速率低的离谱),fft运算用的是江科大自化协UP写的fft.c源码。
实物图片
实物背面如下
下面附上背面简单说明
如下图,PCB电路板通过红色圈中的接口与屏幕通信,蓝色圈中的M3孔可以将PCB固定在屏幕背面,黄色圈中的是屏幕的供电接口
下面附上测面图片
效果图片
由于最近事情多,就没有剪视频发B站,这个过两天补上,大家可以先看一下图片(之前用32做过发了B站,大家可以去看看>https://b23.tv/lyYAUzc?share_medium=android&share_source=qq&bbid=XY190221153CD515F9E44E2D2280C56F73120&ts=1652075244985
)链接要是打不开可以看最下面的视频
16x16汉字显示效果
32x32汉字显示效果
时钟效果我个人觉得非常nice,数字间的切换非常有艺术气息,这个版本没做时钟,因为没有加纽扣电池,下一版会补上,时钟切换效果在32那个视频里面有,感兴趣可以移步去看(>https://b23.tv/lyYAUzc?share_medium=android&share_source=qq&bbid=XY190221153CD515F9E44E2D2280C56F73120&ts=1652075244985)链接要是打不开可以看最下面的视频
全彩单元板驱动详解
接线说明
全彩单元板都是这种HUB75接口
R1,G1,B1是上面16行的颜色控制线,R1,G2,B2是下面16行的颜色控制线;A,B,C,D是地址线,共32行16个地址;CLK是时钟信号线;LAT是数据保存线;OE是显示使能线;
控制时序说明
首先通过A,B,C,D四根地址线选中两行,例如A=0,B=0,C=0,D=0,选中第0行和第16行,A=1,B=0,C=0,D=0,选中第1行和第17行,A=0,B=1,C=0,D=0,选中第2行和第8行……
地址选好后就开始传输颜色数据,这里就以A=1,B=0,C=0,D=0,选中第1行和第17行为例,现在选中了1和17行,然后我让R1=1,G1=0,B1=0,这样第1行的第1个点就是红色(因为只有R为1,G,B都是0),同时R2=0,G2=1,B2=0,这样第17行的第1个点就是绿色(因为只有G为1,R,B都是0),然后拉高CLK,再释放CLK就可以开始给1行和17行的第二个点传送颜色数据了,如此循环64次,第1行和17行的64个点便都写好了我们想要的颜色数据,然后接下来我们把LAT拉高然后释放就可以开始给下一个地址传数据,如此循环16次,屏幕的16个地址32行便都填充好了我们想要的颜色数据,这样就完成了一次屏幕刷新;
以上就是我个人对全彩单元板驱动的理解,有不正确的地方欢迎大家评论指出,我上面说的只能实现7种颜色的显示,真正理解之后就能明白要实现全彩显示屏幕一次刷新要扫描很多次,对单片机性能要求很高,但是也有绕过这个让普通的单片机也能实现全彩显示的办法,这是我在栈指针这位UP主的讲解下才知道的,这里附上栈指针UP主原话,能把复杂的事讲的如此简单明了,实在佩服👍
栈指针UP主:“一个颜色的值就是这个颜色需要亮起的时长,如果我们对每一个灯珠的每一个颜色都点亮这么长的时间以后再去点亮下一个灯珠,效率非常低。因此需要把它拆开。
以8位色深为例。把它拆成二进制,二进制的每一位代表它的权重,例如第0位就是2^0=1,第7位就是2^7=128。8位色深的代码中一共8个循环,每个循环分别点亮1、2、4、8、16、32、64、128个单位时间。在每个循环中我们只点亮所有这个二进制位为1的灯珠。
假设有两个灯珠颜色为0xA3和0x61,二进制10100011b和01100001b,第一个循环我们同时点亮两个灯珠,第二个循环只点亮第一个灯珠,第三四五无,第六个循环都点亮,第七个循环只点亮第二个灯珠,第八个循环只点亮第一个灯珠。这样就实现了对单一颜色的控制。对于RGB三色和更多的灯珠以此类推。用这个思路去看代码应该能看懂了吧?”
其他说明
这个全彩单元板,之前我只能让它显示7种颜色,网上说这种屏幕要想实现全彩显示需要用FPGA,单片机很难实现,直到看到B站UP主——栈指针的视频,然后在他的讲解下,我才知道用32单片机完全可以做到全彩驱动,非常感谢栈指针UP主,这次做的基于瑞萨单片机的频谱灯没有用到全彩显示,只实现了七色,因为这款单片机主频太低,全彩显示时屏幕闪烁明显。
频谱部分的代码参考了——江科大自化协UP主的频谱灯程序,在此也表示感谢
程序上传了微云,需要的可以去下载(里面包含了瑞萨单片机串口下载教程)
>https://share.weiyun.com/afyA1PQR
过几天有时间会重新修改工程,并会附上改好的源码,感兴趣的可以持续关注
做出来的时钟效果如第二个附件视频所示
评论