基于单片机的光立方电路设计
附录
程序 主程序
#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