2014唐山工业职业技术学院毕业设计封面

更新时间:2024-06-27 15:05:01 阅读量: 综合文库 文档下载

说明:文章内容仅供预览,部分内容可能不全。下载后的文档,内容与下面显示的完全一致。下载之前请确认下面内容是否您想要的,是否完整无缺。

基于单片机的光立方电路设计

唐山工业职业技术学院

毕业设计(论文、创作)说明书

题目 基于单片机的 光立方电路设计

系别 班级 姓名 学号 指导教师

2014 年 5 月 6 日

1

基于单片机的光立方电路设计

目 录

摘 要.........................................................1 关键词.........................................................1 一、概述.......................................................2 1.1 课题的目的及意义........................................2 1.2 光立方电路设计..........................................2 二、功能需求分析...............................................5 2.1 课题背景及发展现状......................................5 2.2 光立方的介绍............................................5 三、具体设计...................................................6 3.1 元器件选择..............................................6 3.2 显示模块................................................7 3.3 驱动模块 ...............................................9 3.4 主控模块...............................................10 3.5 音频模块...............................................10 3.6 调试...................................................11 四、总结......................................................12 参 考 文 献...................................................13 附录..........................................................14 主程序........................................................14 573锁存相关程序...............................................23 频谱显示程序..................................................37

2

基于单片机的光立方电路设计

基于单片机的光立方电路设计

(11机电11班)

摘 要

光立方是一个长、宽、高由8×8×8 个LED 灯组成的真实3D 立方体显示器。其最大的特点,就是带给观赏者立体的超酷的3D视觉体验。因此各大网站也充斥着各种各样的光立方版本。

但是这各种版本的光立方的制作方法都很复杂,而且成本也很高,而本设计与之相比则制作简单精美,成本低廉。

为保证光立方精美的外形,本设计还提供了一种光立方的制作模板,以确保将动手能力导致的美观差异降到最低。

为降低其成本,本设计采用了STC12C5A60S2单片机,这种单片机自带有A/D转换模块;使用的锁存器是常用的74HC573。这样可以保证在降低制作成本的情况下,毫不影响作品的美观;再加上显示效果极佳的雾面的蓝色LED,硬件电路无需添加额外的驱动和上拉电阻,即可实现其强大的功能:除了能显示3D 图形,还可以支持多级亮度和速度调整,允许用户自拓展音频显示功能,就像音乐显示器一样。用户还可以在不改动硬件电路的情况下设计出自己喜欢的的自定义图形。这些充分体现了制作成本低、显示效果好、功能完善的特点。

最后,经过软硬件调试,解决了一些硬件电路短路,程序报错的问题,完美地实现了多种图形动态显示,流畅的图形变换和音频显示的多种功能。

关键词: 光立方 制作模板 音频显示 A/D转换

3

基于单片机的光立方电路设计

一、概 述

1.1课题的目的及意义

“光立方”一词正逐渐引起了全国人民的关注,并得到了全球的高度肯定。由此,也掀起了光立方的设计与学习热潮,在原有的基础上不断增加难度,增加变换花样,吸引电子爱好者对其研究、创新。

事实上,“光立方”已经渗透到以下几个方面:照明类LED光效——户外景观照明展开的视觉装饰活动;信息传播类LED光效——各种类型的大屏幕点缀着人们的生活;光立方制作所需材料较常见,成本低廉、性价比高等优点具有较高的研究价值。

本次毕业设计一改传统的平面流水灯的风格,而是从平面向立体发展,通过更宽广的三维空间呈现出更加绚丽的效果,直接冲击着人们审美视觉,不在停留在乏味的平面成像。设计并采用更优于89C51的STC12C5A60S2 单片机,使系统具有更强大的功能和驱动能力。再者,从平面向立体这符合科技发展的要求,适应主流。3D8光立方主体部分由512LED灯组成,在制作过程中锻炼学习动手焊接能力,并以低成本,智能化产品对实现经济利益、商业价值的形成具有积极的推动作用。 1.2光立方电路设计

主要分为主控模块、驱动音频模块

4

四个模块分别是模块、显示模块、

基于单片机的光立方电路设计

图1-1 主控电路

1主控电路

这个设计选单片机选型号时候需要考虑带AD功能和较大的程序存储空间,STC12C5A60S2单片机是STC公司生产的单时钟/机器周期(1T)的单片机,是高速,低功耗,超抗干扰的新一代8051单片机,指令代码完全兼容传统8051,但速度快8-12倍。内部集成MAX810专用复位电路,2路PWM,8路高速10位A/D转换,应用程序空间高达60K,尤其适合做光立方。如图1-1

图1-2 驱动电路

5

基于单片机的光立方电路设计

2驱动电路

主要部件74HC573锁存器,74HC573包含八进制3态非反转透明锁存器,是一种高性能硅门CMOS器件。它的数据锁存功能,在输入的数据消失时,在芯片的输出端,数据仍然保持。真值表如下.

图1-3 真值表 图1-4 显示电路

3.显示电路

显示电路所有的灯的负端都是接在一起的,每一组都是控制光立方的一个面,控制的是光立方的竖起来的面,而横着的面由图2的ULN2803达林顿管驱动器控置。

4.音频电路

音频电路是本设计的特色,单片机的P1.0和P1.1分别连接音频输入口端口的两个引脚,用单片机内部AD采样音频信号。经过快速傅里叶变换,在光立方上显示出来音乐的频谱。

6

基于单片机的光立方电路设计

二、 功能需求分析

2.1课题的背景和发展状况

LED 点阵显示屏已经应用到了我们生活中的方方面面,科技发展的脚步一直向前,3D 电影给人们带来了更加震撼的视觉体验,于是设计出一种 3D 显示屏。

光立方是由四千多棵光艺高科技“发光树”组成的,在2009年10月1日天安门广场举行的国庆联欢晚会上面世,这是新中国成立六十周年国庆晚会最具创意的三大法宝之首,自从国庆60周年联欢晚会开始演练后,一个全新的名词“光立方”,吸引了全国人民的关注。国庆联欢晚会三样法宝,光立方为最,“光立方”在气势和整体感觉上,融合了北京奥运会开幕式“击缶而歌”和“活字印刷”的风格,而各种图案则与贯穿奥运会开幕式的“画卷”有异曲同工之妙。“光立方”可以根据爱国歌曲的不同内容,展示不同的造型和图案,具有丰富的视觉效果。

2.2 光立方的介绍

光立方顾名思义就是一个立方体,我们采用的是8*8*8的模式,大概的体积是17cm*17cm*17cm(长.宽.高),主要分为四个模块:主控模块驱动模块显示模块和音频模块;我们所做的光立方驱动电路,主控电路等都是纯手工焊接。采用的主控芯片STC12C5A60S2芯片,驱动电路是采用我们常用的74HC573数字芯片。本设计采用C语言编程实现不同图案的转变,利用单片机控制512个LED灯的亮灭,采用延时控制LED亮灭时间使LED灯图案转变的速度不同,最终使得整个立体呈现不同的造型和图案,使其变得美轮美奂、绚丽多彩。

LED光立方显示技术的特色之处:

一是节能(直接功耗,间接耗能)高空间利用率, 二是基本无电离辐射。

LED 点阵显示屏的特点还有比数码管具有实用、便宜、亮度高等优点,而且做出来的 LED 显示很耐用。LED 显示屏还具有亮度高、工作电压低、功耗小、小型化、寿命长、耐冲击和性能稳定等优点。LED 点阵显示屏的发展前景极为广阔,目前正朝着更高亮度,更高耐气候性,更高的发光密度,形状的多样性,更高的发光均匀性、可靠性、多色化方向发展。

7

基于单片机的光立方电路设计

三、具体设计

3.1 元器件选择

1)由于光立方的程序量比较大,而且要求相对比较高,因此用 51 系列的增强型芯片 STC12C5A60S2,选择的理由:1.超强抗干扰;2.内部集成高可靠复位电路,外部复位可用可不用;3.速度快,比 8051 快 8-12 倍。

2)由于灯的个数比较多,因此所需要的电流相对也比较大,所以选择ULN2803达林顿管驱动器。

3)驱动部分使用了熟悉的74HC573,其优点有 1.高阻态,就是输出既不是高电平,也不是低电平,而是高阻抗的状态;在这种状态下,可以多个芯片并联输出;2.数据锁存;当输入的数据消失时,在芯片的输出端,数据仍然保持;3.数据缓冲、加强驱动能力。 4)LED 灯的选择,因为光立方主体骨架是由LED灯脚架接而成,且距离不小,所以应该选用长脚LED,由于高亮灯散射现象不明显,发光比较集中,所以选用效果较好的雾状灯。综上,最终选择的是长脚蓝色雾状灯。

图 3-1 雾状LED灯

8

基于单片机的光立方电路设计

3.2 显示模块

我首先完成的是LED光立方的搭接,为了保持整体的通透性、立体感,3D8光立方没有设计额外的LED支架,所有的搭建全部使用LED的自身的管脚。 1)水平弯折:基本徒手就可以保证焊接的整齐性和保持角度的统一。

2)垂直弯折:可借助尖嘴钳,目的是让阴极摆出发光体一部,使其可以与其上下的LED进行搭接。 (1)由点到线

准备一块水平板,在上面打上8*8的64个孔,分布均匀,孔径以配合LED为准。将弯折好的LED插入一排插孔后,其阴极正好可以搭接在一起,进行焊接,实现线行内共阴的操作。 (2)由线到面

将焊接好的一条一条LED平躺在平面上,实现水平方向阴极的焊接,左方LED与右方LED阴极搭接的位置,可用LED自身根部的突起作为标志,控制层与层间距。 (3)由面到体

将水平各面依次插到面板上面,以后将上下层直接的阳极进行焊接,实现各8*8平面的层共阳,实现层共阳以后,我们就得到了共计8条对阴极引线,通过漆包铜线,实现各层的阴极线与主板的连接。见图3-2 (4)静态测试

进行LED的静态测试,对内部常亮点、常暗点进行更换。由于LED还是比较娇贵的元件,焊接过程中,应避免静电造成LED的损伤。对面内各点进行测试,从面避免在各层都实现共阴连接以后再从中拆出个别坏点。就原理图来说,3D8的LED搭接结果相对简单,512个LED,分别为64束,8层,束内共阳,层内共阴。见图3-3 (5)线路板背部焊接

在线路板上均匀分布焊接64个针脚,并把针脚引到一条水平线上,等待下面与驱动电路焊接。见图3-4

9

基于单片机的光立方电路设计

图3-2

3-3

10

基于单片机的光立方电路设计

图3-4

3.3驱动模块

驱动电路由于线比较多电路比较复杂,由八个74HC573锁存器组成的,所以我们有比较多的跳线,首先分别把74HC573锁存器的1号和10号引脚焊接起来,20号引脚也连接起来,然后焊接的是74HC573锁存器的12-18引脚与64个引脚,最后把8个74HC573锁存器的2-8引脚连接起来与单片机的P0.0至P0.7连接,如图3-5:

图3-5

3.4主控模块

主控电路是最简单的电路,是以STC125A60S2单片机为核心的控制电路,其中还有一个控制层的ULN2803达林顿管驱动器与STC125A60S2单片机的P3.0-P3.7焊接在一起,晶振和电容焊接在单片机的18和19引脚。如图3-6所示:

11

基于单片机的光立方电路设计

图3-6 3.5音频模音频模块是

此次毕业设

计的创新之处,通过按键进行模式切换,光立方可以随着输入的音乐信号进行跳动。将单片机的P1.0和P1.1分别连接音频输入口端口的两个引脚,最后把所有的VCC和GND焊接到一起,把口焊接到线路板上

图3-7 3.6调试

首先我用Keil编程软件编写的单片机程序,烧写进单片机里。 其次是检查全部的灯是否正常工作:

(1)通电后,发现有一列没有点亮,我用排除法来检查电路,首先是检查灯的线路是否虚焊,断路,果真是这列断路了,把它接上后这一列也亮了。

(2)调试过程中有几个灯一直不亮,用万用表欧姆档测量发现灯已经烧坏,拆下坏掉,但是有2个灯是存在虚焊问题,从新焊接后正常工作。

USB供电口和下载就完工了。

12

基于单片机的光立方电路设计

最后完美运行,如图3-8

图3-8

四、总结

其实在很早之前就知道光立方这种东西,只是在许多地方找到的资料不是制作方式太复杂,就是电路设计难懂,制作精美的光立方也往往价格不菲。

而本设计旨在设计出一种制作简单、低花费、高质量的光立方。经过查阅大量的相关资料,最终设计出了以STC125A60S2单片机为核心的控制电路,并用常用锁存器74HC573和8路非门ULN2803达林顿管驱动器设计了光立方驱动电路。最初焊接光立方8×8的面时,每个LED引脚的连接都是很困难的。在这个过程中,我想到了一个制作模板,并最终加快了显示部分的焊接速度和焊接质量。每焊好一层LED,都要仔细测试是

13

基于单片机的光立方电路设计

否有虚焊或者短接,花了三天时间才把8层LED焊好。

之后在焊接64个插针时,由于每个插针在焊接前难以固定,所以一手拿镊子一手拿烙铁,先用焊锡固定插针,然后再把插针调整得笔直。每一排,每一列还要最终调整得排列整齐,这个过程也很辛苦。

设计结束了,但学习仍在继续。从这次的设计中,我真正的意识到,在以后的学习中,要理论联系实际,把我们所学的理论知识用到实际当中,实践是检验真理的唯一标准。在今后的人生中,不断对自己所学的知识进行更新,进行补充。

14

基于单片机的光立方电路设计

参 考 文 献

[1] 谢自美.电子线路设计.实验.测试.武汉:华中科技大学出版社.2006 [2] 关积珍.LED显示屏发展状况及趋势[J].世界电子元器件,2000 [3] 康华光,陈大钦,张林.电子技术基础.华中科技大学出版社.2002 [4] 邱光源.电路(第五版)[M].北京:高等教育出版社,2006 [5] 张瑞玲.单片机原理与应用 西北工业大学出版社2010 [6]

.单片机C51程序设计教程与实验 北京航空航天大学出版社2006

[7] 江世明,基于Proteus的单片机应用技术[M],北京,电子工业出版社,2009 [8] 王为青, 程国钢,单片机Keil Cx51应用开发技术,北京,人民邮电出版社, 2007 [9] 阮永松,打造音乐频谱时钟,无线电[J],2012

[10]刘兴钊,数字信号处理[M],北京,电子工业出版社,2010

[11]张毅刚,基于Proteus的单片机课程的基础实验与课程设计[M],北京,人民邮电出版社, 2012

15

基于单片机的光立方电路设计

附录

程序 主程序

#include //

#include\芯片头文件

#include\ //FFT(快速傅里叶变换)功能头文件 #include\ //按键扫描头文件 #include\ // #include\ //hc573驱动 #include\ //

#define anum P3 //定义ULN2803数据端口 sbit LED =P1^3; //指示用LED(未使用)

uchar flag1; //变量区分定时器0功能(0:用于音乐频谱,1:用于动画)uchar ADC_Count=0,LINE=15,G=0,T;//uchar COUNT=15;//uchar COUNT1=0; //uchar code tablew[]={0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80}; //uchar code tablew[]={0x80,0x40,0x20,0x10,0x08,0x04,0x02,0x01}; //uchar code tablew[]={0xff,0x7f,0x3f,0x1f,0x0f,0x07,0x03,0x01}; uchar code tablew[]={0x00,0x80,0xC0,0xE0,0xF0,0xF8,0xFC,0xFE}; uchar G;

uchar buffer[8]; //功能初始化 void Init() {

//IO口默认状态

P0 = 0x00; //74HC573数据口 P2 = 0x00; //74HC573位选端 P3 = 0x00; //ULN2803数据口

//IO口模式初始化

P3M0 = 0xff; //ULN2803输出口设置为推挽输出 P3M1 = 0x00;

P0M0 = 0xff; //P0、P2用于控制74HC573,推挽输出 P0M1 = 0x00; P2M0 = 0xff; P2M1 = 0x00;

P4M0 = 0x00; //P4端口接有按键,设置为输入 P4M1 = 0xff;

//573初始化 initial573(); //----- ADC初始

化16

基于单片机的光立方电路设计

------------------------------------------------------------------------------

P1ASF = 0x02; //0000,0010, 将 P1.1 置成模拟口 AUXR1 &=0xFB; //1111,1011, 令 ADRJ=0 EADC =1; //AD中断打开

ADC_CONTR = ADC_POWER | ADC_SPEEDHH | ADC_START | channel; //1110 1001 1打开 A/D (ADC_POWER)转换电源;11速度为90周期一次;

//0中断标志清零;1启动adc(ADC_START);001AD通道打开(这里为P1.1); //----- 定时器初始化 ------------------------------------------------------------------------------

ET0 = 1; //定时器0中断 启用 TR0 = 0; //定时器0 关闭 ET1 = 1; //定时器1中断 启用 TR1 = 0; //定时器1 关闭 PT1 = 0; //定时器1 低优先级 PT0 = 1; //定时器0 高优先级 IPH = PADCH;

IP = PADC; //中断优先级 EA = 1; //总中断打开 clear(0); //清空显示缓冲区

//按键设置

P4SW = 0x70; //将NA、ALE、EX_LVD设置为准IO口(P4.4、P4.5、P4.6) }

/******** 主函数 ***************************************************************************************/ void main() {

uchar i = 0; //for循环变量 //设备初始化 Init();

//正常工作循环 while(1)

{

clear(0); //清空刷新显示缓冲区 key_scan(); //扫描按键 //关闭显示

if(key1flag==1) {

key1flag = 0; xiansi1(); //关闭所有573输出 anum = 0xff; //关闭ULN2083输出 TR1 = 0; //定时器1 关闭

17

基于单片机的光立方电路设计

TR0 = 0; //定时器0 关闭 }

//FFT

if(key2flag==1) {

TMOD = 0x12; //T0: 8位自动重装 T1: 16位模式 TH0 = 0x60; //ADC采样周期(80us或6.66us) TL0 = 0x60; // while(1) {

flag1 = 0;

TR1 = 1; //刷新显示 TR0 = 1; //控制采样速率 ADC_Count=0;

TR1 = 1; //开启定时器中断1 TR0 = 1; //开启定时器中断0 EADC = 1; //开启ADC

while(ADC_Count<128); //转换128次

for(i=0;i<128;i++) //FFT参数虚部赋值 {

Fft_Image[i]=0; //原始数据 虚部赋值为0 }

FFT(); //FFT运算并转换为各频段幅值 //其他按钮,跳出 key_scan();

if(key2flag == 0) break; } }

//顺序循环

if(key3flag==1) {

TMOD=0x11; while(1) {

clear(0);

flag1=1; //定时器0功能控制 TR1=0; //关闭定时器1 TR0=1; //开启定时器0 //TH0=0xf0; //TL0=0xff; flash_6();

clear(0); key_scan(); if(key3flag == 0) break; flash_5();

clear(0); key_scan(); if(key3flag == 0) break; flash_1();

18

基于单片机的光立方电路设计

clear(0); key_scan(); if(key3flag == 0) break; flash_2();

clear(0); key_scan(); if(key3flag == 0) break; flash_4();

clear(0); key_scan(); if(key3flag == 0) break; flash_3();

clear(0); key_scan(); if(key3flag == 0) break; flash_8();

clear(0); key_scan(); if(key3flag == 0) break; flash_7();

clear(0); key_scan(); if(key3flag == 0) break; flash_11();

clear(0); key_scan(); if(key3flag == 0) break; flash_9();

clear(0); key_scan(); if(key3flag == 0) break; flash_10();

clear(0); key_scan(); if(key3flag == 0) break; flash_11();

clear(0); key_scan(); if(key3flag == 0) break; flash_6();

clear(0); key_scan(); if(key3flag == 0) break; flash_5();

clear(0); key_scan(); if(key3flag == 0) break; flash_4();

clear(0); key_scan(); if(key3flag == 0) break; flash_7();

clear(0); key_scan(); if(key3flag == 0) break; flash_9();

clear(0); key_scan(); if(key3flag == 0) break; flash_8();

clear(0); key_scan(); if(key3flag == 0) break; flash_4();

clear(0); key_scan(); if(key3flag == 0) break; flash_2();

clear(0); key_scan(); if(key3flag == 0) break; } } } }

//定时器1中断 用于刷新显示(只在频谱显示时使用)

void LED_Display() interrupt 3 //中断一次显示一列{

TH1 = 0xfd; //刷新显示周期(300us或25us) 刷新率 0Xa8; //

G++; if(G>=17) G=1;

TL1 = 19

基于单片机的光立方电路设计

switch(G) //往点阵屏填充一列的数据 {

//(LED_TAB[1] )%8取八的余数

case 1: anum=tablew[(LED_TAB[1] )%8];hang1();break; case 2: anum=tablew[(LED_TAB[2] )%8];hang1();break;

case 3: anum=tablew[(LED_TAB[3] )%8];hang2();break; case 4: anum=tablew[(LED_TAB[4] )%8];hang2();break; case 5: anum=tablew[(LED_TAB[5] )%8];hang3();break; case 6: anum=tablew[(LED_TAB[6] )%8];hang3();break; case 7: anum=tablew[(LED_TAB[7] )%8];hang4();break; case 8: anum=tablew[(LED_TAB[8] )%8];hang4();break; case 9: anum=tablew[(LED_TAB[9] )%8];hang5();break; case 10:anum=tablew[(LED_TAB[10])%8];hang5();break; case 11:anum=tablew[(LED_TAB[11])%8];hang6();break; case 12:anum=tablew[(LED_TAB[12])%8];hang6();break; case 13:anum=tablew[(LED_TAB[13])%8];hang7();break; case 14:anum=tablew[(LED_TAB[14])%8];hang7();break; case 15:anum=tablew[(LED_TAB[15])%8];hang8();break; case 16:anum=tablew[(LED_TAB[15])%8];hang8();break; }

LED=0; }

//ADC转换完成中断

void ADC_Finish() interrupt 5 {

ADC_CONTR &= !ADC_FLAG;

Fft_Real[LIST_TAB[ADC_Count]] = (int)((ADC_RES)<<1)+(ADC_RESL>>1)*2;

if(ADC_Count<=127){ ADC_Count++; }

else { EADC=0;TR0=0; } }

//定时器0中断

void Ad_Control() interrupt 1 {

uchar i;

static uchar layer=0; if(flag1==1) {

anum = 0;

for(i=0;i<8;i++) {

buffer[i]=display[layer][i]; }

xiansi();

anum = 0x01<

20

基于单片机的光立方电路设计

// anum = 0x80>>layer; if(layer<7) layer++; else layer=0;

delay(5); TH0=0xf5;

TL0=0xe0; }

//控制采样速率 else {

ADC_CONTR = ADC_POWER | ADC_SPEEDHH| ADC_START | channel; //开始AD采集 } }

573锁存相关程序

21

基于单片机的光立方电路设计

unsigned char buffer[8]=\赋初值 //端口定义

sbit cs1 = P2^7; //低电平时,数据锁存 sbit cs2 = P2^6; sbit cs3 = P2^5; sbit cs4 = P2^4; sbit cs5 = P2^3; sbit cs6 = P2^2; sbit cs7 = P2^1; sbit cs8 = P2^0;

#define DATA_573 P0 //573的数据端口

/*显示缓存,上层需要使用*/

/*--------------- 初始化 --------------*/ void initial573() {

//SH_CP = 0; //ST_CP = 0; //DS = 0; //关闭所有灯

cs1 = cs2 = cs3 = cs4 = cs5 = cs6 = cs7 = cs8 = 1; //输出锁存 DATA_573 = 0x00;

cs1 = cs2 = cs3 = cs4 = cs5 = cs6 = cs7 = cs8 = 0; //输出锁存}

/*--------------- 发送数据 ---------------*/ /*void send_data(unsigned char d) {

unsigned char i; for(i=0;i<8;i++) {

DS = d&0x80; //发送最低位 SH_CP = 1; SH_CP = 0; //移位寄存器移位 d = d<<1; //数据移位 } } */

/*--------------- 扫描数码管,供上层调用 ---------------*/

void xiansi() {

/*send_data(buffer[0]); //发送段选数据

22

基于单片机的光立方电路设计

send_data(buffer[1]); //发送位选数据 send_data(buffer[2]); send_data(buffer[3]);

send_data(buffer[4]); //发送段选数据 send_data(buffer[5]); //发送位选数据 send_data(buffer[6]); send_data(buffer[7]); ST_CP=1;

ST_CP=0; //更新锁存数据 */ cs1 = 1; DATA_573 = buffer[7]; cs1 = 0; // cs2 = 1; DATA_573 = buffer[6]; cs2 = 0; // cs3 = 1; DATA_573 = buffer[5]; cs3 = 0; // cs4 = 1; DATA_573 = buffer[4]; cs4 = 0; // cs5 = 1; DATA_573 = buffer[3]; cs5 = 0; // cs6 = 1; DATA_573 = buffer[2]; cs6 = 0; // cs7 = 1; DATA_573 = buffer[1]; cs7 = 0; // cs8 = 1; DATA_573 = buffer[0]; cs8 = 0; // }

void xiansi1() {

/* send_data(0x00); //发送段选数据 send_data(0x00); //发送位选数据 send_data(0x00); send_data(0x00);

send_data(0x00); //发送段选数据 send_data(0x00); //发送位选数据 send_data(0x00); send_data(0x00); send_data(0x00); ST_CP=1;

ST_CP=0; //更新锁存数据 */

cs1 = 1; _nop_(); DATA_573 = 0x00; _nop_(); cs1 = 0; // cs2 = 1; _nop_(); DATA_573 = 0x00; _nop_(); cs2 = 0; // cs3 = 1; _nop_(); DATA_573 = 0x00; _nop_(); cs3 = 0; // cs4 = 1; _nop_(); DATA_573 = 0x00; _nop_(); cs4 = 0; // cs5 = 1; _nop_(); DATA_573 = 0x00; _nop_(); cs5 = 0; // cs6 = 1; _nop_(); DATA_573 = 0x00; _nop_(); cs6 = 0; // cs7 = 1; _nop_(); DATA_573 = 0x00; _nop_(); cs7 = 0; // cs8 = 1; _nop_(); DATA_573 = 0x00; _nop_(); cs8 = 0; // }

void hang1() {

/* send_data(0xff); //发送段选数据 send_data(0x00); //发送位选数据

23

基于单片机的光立方电路设计

send_data(0x00); send_data(0x00);

send_data(0x00); //发送段选数据 send_data(0x00); //发送位选数据 send_data(0x00); send_data(0x00);

ST_CP=1; ST_CP=0;*/ //更新锁存数据

cs1 = 1; _nop_(); DATA_573 = 0x00; _nop_(); cs1 = 0; // cs2 = 1; _nop_(); DATA_573 = 0x00; _nop_(); cs2 = 0; // cs3 = 1; _nop_(); DATA_573 = 0x00; _nop_(); cs3 = 0; // cs4 = 1; _nop_(); DATA_573 = 0x00; _nop_(); cs4 = 0; // cs5 = 1; _nop_(); DATA_573 = 0x00; _nop_(); cs5 = 0; // cs6 = 1; _nop_(); DATA_573 = 0x00; _nop_(); cs6 = 0; // cs7 = 1; _nop_(); DATA_573 = 0x00; _nop_(); cs7 = 0; // cs8 = 1; _nop_(); DATA_573 = 0xff; _nop_(); cs8 = 0; // }

void hang2() {

/* send_data(0x00); //发送段选数据 send_data(0xff); //发送位选数据 send_data(0x00); send_data(0x00);

send_data(0x00); //发送段选数据 send_data(0x00); //发送位选数据 send_data(0x00); send_data(0x00);

ST_CP=1; ST_CP=0;*/ //更新锁存数据

cs1 = 1; _nop_(); DATA_573 = 0x00; _nop_(); cs1 = 0; // cs2 = 1; _nop_(); DATA_573 = 0x00; _nop_(); cs2 = 0; // cs3 = 1; _nop_(); DATA_573 = 0x00; _nop_(); cs3 = 0; // cs4 = 1; _nop_(); DATA_573 = 0x00; _nop_(); cs4 = 0; // cs5 = 1; _nop_(); DATA_573 = 0x00; _nop_(); cs5 = 0; // cs6 = 1; _nop_(); DATA_573 = 0x00; _nop_(); cs6 = 0; // cs7 = 1; _nop_(); DATA_573 = 0xff; _nop_(); cs7 = 0; // cs8 = 1; _nop_(); DATA_573 = 0x00; _nop_(); cs8 = 0; // }

void hang3() {

24

基于单片机的光立方电路设计

/* send_data(0x00); //发送段选数据 send_data(0x00); //发送位选数据 send_data(0xff); send_data(0x00);

send_data(0x00); //发送段选数据 send_data(0x00); //发送位选数据 send_data(0x00); send_data(0x00);

ST_CP=1; ST_CP=0;*/ //更新锁存数据

cs1 = 1; DATA_573 = 0x00; cs1 = 0; // cs2 = 1; DATA_573 = 0x00; cs2 = 0; // cs3 = 1; DATA_573 = 0x00; cs3 = 0; // cs4 = 1; DATA_573 = 0x00; cs4 = 0; // cs5 = 1; DATA_573 = 0x00; cs5 = 0; // cs6 = 1; DATA_573 = 0xff; cs6 = 0; // cs7 = 1; DATA_573 = 0x00; cs7 = 0; // cs8 = 1; DATA_573 = 0x00; cs8 = 0; // }

void hang4() {

/* send_data(0x00); //发送段选数据 send_data(0x00); //发送位选数据 send_data(0x00); send_data(0xff);

send_data(0x00); //发送段选数据 send_data(0x00); //发送位选数据 send_data(0x00); send_data(0x00);

ST_CP=1;

ST_CP=0; //更新锁存数据

cs1 = 1; DATA_573 = 0x00; cs1 = 0; // cs2 = 1; DATA_573 = 0x00; cs2 = 0; // cs3 = 1; DATA_573 = 0x00; cs3 = 0; // cs4 = 1; DATA_573 = 0x00; cs4 = 0; // cs5 = 1; DATA_573 = 0xff; cs5 = 0; // cs6 = 1; DATA_573 = 0x00; cs6 = 0; // cs7 = 1; DATA_573 = 0x00; cs7 = 0; // cs8 = 1; DATA_573 = 0x00; cs8 = 0; // }

25

*/

基于单片机的光立方电路设计

void hang5() {

/* send_data(0x00); //发送段选数据 send_data(0x00); //发送位选数据 send_data(0x00); send_data(0x00);

send_data(0xff); //发送段选数据 send_data(0x00); //发送位选数据 send_data(0x00); send_data(0x00);

ST_CP=1; ST_CP=0;*/ //更新锁存数据

cs1 = 1; DATA_573 = 0x00; cs1 = 0; // cs2 = 1; DATA_573 = 0x00; cs2 = 0; // cs3 = 1; DATA_573 = 0x00; cs3 = 0; // cs4 = 1; DATA_573 = 0xff; cs4 = 0; // cs5 = 1; DATA_573 = 0x00; cs5 = 0; // cs6 = 1; DATA_573 = 0x00; cs6 = 0; // cs7 = 1; DATA_573 = 0x00; cs7 = 0; // cs8 = 1; DATA_573 = 0x00; cs8 = 0; // }

void hang6() {

/* send_data(0x00); //发送段选数据 send_data(0x00); //发送位选数据 send_data(0x00); send_data(0x00);

send_data(0x00); //发送段选数据 send_data(0xff); //发送位选数据 send_data(0x00); send_data(0x00);

ST_CP=1; ST_CP=0;*/ //更新锁存数据

cs1 = 1; DATA_573 = 0x00; cs1 = 0; // cs2 = 1; DATA_573 = 0x00; cs2 = 0; // cs3 = 1; DATA_573 = 0xff; cs3 = 0; // cs4 = 1; DATA_573 = 0x00; cs4 = 0; // cs5 = 1; DATA_573 = 0x00; cs5 = 0; // cs6 = 1; DATA_573 = 0x00; cs6 = 0; // cs7 = 1; DATA_573 = 0x00; cs7 = 0; // cs8 = 1; DATA_573 = 0x00; cs8 = 0; //

26

基于单片机的光立方电路设计

}

void hang7() {

/* send_data(0x00); //发送段选数据 send_data(0x00); //发送位选数据 send_data(0x00); send_data(0x00);

send_data(0x00); //发送段选数据 send_data(0x00); //发送位选数据 send_data(0xff); send_data(0x00);

ST_CP=1; ST_CP=0;*/ //更新锁存数据

cs1 = 1; DATA_573 = 0x00; cs1 = 0; // cs2 = 1; DATA_573 = 0xff; cs2 = 0; // cs3 = 1; DATA_573 = 0x00; cs3 = 0; // cs4 = 1; DATA_573 = 0x00; cs4 = 0; // cs5 = 1; DATA_573 = 0x00; cs5 = 0; // cs6 = 1; DATA_573 = 0x00; cs6 = 0; // cs7 = 1; DATA_573 = 0x00; cs7 = 0; // cs8 = 1; DATA_573 = 0x00; cs8 = 0; // }

void hang8() {

/* send_data(0x00); //发送段选数据 send_data(0x00); //发送位选数据 send_data(0x00); send_data(0x00);

send_data(0x00); //发送段选数据 send_data(0x00); //发送位选数据 send_data(0x00); send_data(0xff);

ST_CP=1; ST_CP=0;*/ //更新锁存数据

cs1 = 1; DATA_573 = 0xff; cs1 = 0; // cs2 = 1; DATA_573 = 0x00; cs2 = 0; // cs3 = 1; DATA_573 = 0x00; cs3 = 0; // cs4 = 1; DATA_573 = 0x00; cs4 = 0; // cs5 = 1; DATA_573 = 0x00; cs5 = 0; //

27

基于单片机的光立方电路设计

cs6 = 1; DATA_573 = 0x00; cs6 = 0; // cs7 = 1; DATA_573 = 0x00; cs7 = 0; // cs8 = 1; DATA_573 = 0x00; cs8 = 0; // } /*

void hang9() {

send_data(0x0f); //发送段选数据 send_data(0x00); //发送位选数据 send_data(0x00); send_data(0x00);

send_data(0x00); send_data(0x00); send_data(0x00); send_data(0x00);

ST_CP=1;

ST_CP=0; }

void hang10() {

send_data(0x00); send_data(0x0f); send_data(0x00); send_data(0x00);

send_data(0x00); send_data(0x00); send_data(0x00); send_data(0x00); ST_CP=1;

ST_CP=0; }

void hang11() {

send_data(0x00); send_data(0x00); send_data(0x0f); send_data(0x00);

send_data(0x00); send_data(0x00); send_data(0x00); send_data(0x0f);

发送段选数据 发送位选数据 //更新锁存数据 发送段选数据 发送位选数据 发送段选数据 发送位选数据 //更新锁存数据 发送段选数据 发送位选数据 发送段选数据 发送位选数据

28

// // // // // // // // // //基于单片机的光立方电路设计

ST_CP=1;

ST_CP=0; //更新锁存数据 }

void hang12() {

send_data(0x00); //发送段选数据 send_data(0x00); //发送位选数据 send_data(0x00); send_data(0x0f);

send_data(0x00); // send_data(0x00); // send_data(0x00); send_data(0x00); ST_CP=1;

ST_CP=0; }

void hang13() {

send_data(0x00); // send_data(0x00); // send_data(0x00); send_data(0x00);

send_data(0x0f); // send_data(0x00); // send_data(0x00); send_data(0x00); ST_CP=1;

ST_CP=0; }

void hang14() {

send_data(0x00); // send_data(0x00); // send_data(0x00); send_data(0x00);

send_data(0x00); // send_data(0x0f); // send_data(0x00); send_data(0x00); ST_CP=1;

ST_CP=0; }

void hang15() {

send_data(0x00); //发送段选数据 发送位选数据 //更新锁存数据 发送段选数据 发送位选数据 发送段选数据 发送位选数据 //更新锁存数据 发送段选数据 发送位选数据 发送段选数据 发送位选数据 //更新锁存数据 发送段选数据

29

基于单片机的光立方电路设计

send_data(0x00); //发送位选数据 send_data(0x00); send_data(0x00);

send_data(0x00); //发送段选数据 send_data(0x00); //发送位选数据 send_data(0x0f); send_data(0x00); ST_CP=1;

ST_CP=0; //更新锁存数据 }

void hang16() {

send_data(0x00); //发送段选数据 send_data(0x00); //发送位选数据 send_data(0x00); send_data(0x00);

send_data(0x00); //发送段选数据 send_data(0x00); //发送位选数据 send_data(0x00); send_data(0x0f); ST_CP=1;

ST_CP=0; //更新锁存数据 }*/

频谱显示程序

typedef unsigned char uchar; typedef unsigned int uint;

#define channel 0x01 //设置AD通道为 P1.0 #define ADC_POWER (1<<7) #define ADC_SPEEDHH (0x03<<5) #define ADC_START (1<<3) #define PADCH (1<<5) #define ADC_FLAG (1<<4) code char SIN_TAB[128]={0,6,12,18,24,30,36,42,48,54,59,65,70,75,80,85,89,94,98,102, 105,108,112,114,117,119,121,123,124,125,126,126,126,126,126,125,124,123,121,119,117,114,112,108,105,102,98,94,89,85,80,75,70,65,59,54,48,42,36,30,24,18,12,6,0,-6,-12,-18,-24,-30,-36,-42,-48,-54,-59,-65,-70,-75,-80,-85,-89,-94,-98,-102,-105,-108,-112,-114,-117,-119,-121,-123,-124,-125,-126,-126,-126,-126,-126,-125,-124,-123,-121,-119,-117,-114,-112,-108,-105,-102,-98,-94,-89,-85,-80,-75,-70,-65,-59,-54,-48,-42,-36,-30,-24,-18,-12,-6}; //放大128倍后的cos整数表(128) code char COS_TAB[128]={127,126,126,125,124,123,121,119,117,114,112,108,105,102,98,94

30

基于单片机的光立方电路设计

,

89,85,80,75,70,65,59,54,48,42,36,30,24,18,12,6,0,-6,-12,-18,-24,-30,-36, -42,-48,-54,-59,-65,-70,-75,-80,-85,-89,-94,-98,-102,-105,-108,-112,-114, -117,-119,-121,-123,-124,-125,-126,-126,-126,-126,-126,-125,-124,-123, -121,-119,-117,-114,-112,-108,-105,-102,-98,-94,-89,-85,-80,-75,-70,-65, -59,-54,-48,-42,-36,-30,-24,-18,-12,-6,0,6,12,18,24,30,36,42,48,54,59,65,70,

75,80,85,89,94,98,102,105,108,112,114,117,119,121,123,124,125,126,126}; //采样存储序列表 code char LIST_TAB[128] =

{0,64,32,96,16,80,48,112,8,72,40,104,24,88,56,120,4,68,36,100,20,84,52,116, 12,76,44,108,28,92,60,124,2,66,34,98,18,82,50,114,10,74,42,106,26,90,58,122,6,70,38,102,22,86,54,118,14,78,46,110,30,94,62,126,1,65,33,97,17,81,49,113,9,73,41,105,25,89,57,121,5,69,37,101,21,85,53,117,13,77,45,109,29,93,61,125,3,67,35,99,19,83,51,115,11,75,43,107,27,91,59,123,7,71,39,103,23,87,55,119,15,79,47,111,31,95,63,127}; uchar i = 0,j = 0,k = 0; // uchar b = 0,p = 0;//anum; //

int Temp_Real = 0,Temp_Imag = 0,temp = 0; //中间临时变量 uint TEMP1 = 0,maxa = 0; //中间临时变量 int xdata Fft_Real[128]; //FFT的实部 int xdata Fft_Image[128]; //FFT的虚部

//uchar xdata LED_TAB2[16]; //记录 漂浮物 是否需要 停顿一下 uchar xdata LED_TAB[16]; //记录红色柱状 //uchar xdata LED_TAB1[16]; //记录 漂浮点

void FFT() //基2fft {

for(i=1; i<=7; i++) /* for(1) */ {

b=1;

b <<=(i-1); //碟式运算,用于计算隔多少行计算例如 第一极 1和2行计算

for(j=0; j<=b-1; j++) /* for (2) */ {

p=1;

p <<= (7-i); p = p*j;

for(k=j; k<128; k=k+2*b) /* for (3) */ {

Temp_Real=Fft_Real[k]; Temp_Imag=Fft_Image[k]; temp=Fft_Real[k+b];

31

基于单片机的光立方电路设计

Fft_Real[k]=Fft_Real[k]+((Fft_Real[k+b]*COS_TAB[p])>>7)+((Fft_Image[k+b]*SIN_TAB[p])>>7);

Fft_Image[k]=Fft_Image[k]-((Fft_Real[k+b]*SIN_TAB[p])>>7)+((Fft_Image[k+b]*COS_TAB[p])>>7);

Fft_Real[k+b]=Temp_Real-((Fft_Real[k+b]*COS_TAB[p])>>7)-((Fft_Image[k+b]*SIN_TAB[p])>>7);

Fft_Image[k+b]=Temp_Imag+((temp*SIN_TAB[p])>>7)-((Fft_Image[k+b]*COS_TAB[p])>>7); // 移位.防止溢出. 结果已经是本值的 1/64 Fft_Real[k] >>= 1; Fft_Image[k] >>= 1;

Fft_Real[k+b] >>= 1; Fft_Image[k+b] >>= 1; } } }

for(j=0;j<16;j++) //16分频 {

TEMP1=((((Fft_Real[j+1]*

Fft_Real[j+1]))+((Fft_Image[j+1]*Fft_Image[j+1])))>>1);//求各频段幅值 if(TEMP1<1) TEMP1=0; LED_TAB[j] = TEMP1;

if(LED_TAB[j]>maxa) maxa = LED_TAB[j]; //maxa是本次转换的最大值 }

if(maxa>16) //分级量化 {

maxa /= 16;

for(j=0;j<16;j++)

LED_TAB[j] /= maxa; //LED_TAB[j] = 0; } }

void delay2us(void) //2us延时 {

unsigned char a=0,b=0; for(b=112;b>0;b--)

for(a=113;a>0;a--); }

32

本文来源:https://www.bwwdw.com/article/1g83.html

Top