/******************************************************************** 函数功能:在LCD上显示频谱。 入口参数:无。 返 回:无。 备 注:无。 ********************************************************************/ void ShowSpectrum(void) { int i,x,y,j,p; //对输入信号进行缩小 for(i=0;i<LENGTH;i++) { AudioOutBuf[i]/=32; } FftInput(AudioOutBuf); //位倒序 FftExe(AudioOutBuf,Re,Im); //做FFT运算 LcdCls(); //清屏 //显示X、Y轴坐标 LcdSetPoint(0,35); LcdPrints("0V"); LcdDrawLine(13,39,15,39); LcdSetPoint(0,23); LcdPrints("1V"); LcdDrawLine(13,27,15,27); LcdSetPoint(0,11); LcdPrints("2V"); LcdDrawLine(13,15,15,15); LcdSetPoint(0,0); LcdPrints("3V"); LcdDrawLine(13,3,15,3); LcdSetPoint(14,40); LcdPrints("0"); LcdSetPoint(13+26,40); LcdPrints("3K"); LcdSetPoint(84-20,40); LcdPrints("16K"); //直流分量直接显示 x=17; y=MAX_HEIGHT-(Re[0]*MAX_HEIGHT/LENGTH)/1024; LcdDrawLine(x,y,x,MAX_HEIGHT); ProcPeak(0,y); //处理峰值 //每1点显示 for(i=1;i<14;i++) { x++; y=sqrt(Re[i]*Re[i]+Im[i]*Im[i]); //计算模值 y/=10; y=Compress(y); //压缩 y=MAX_HEIGHT-y; //换算为屏幕y轴位置 ProcPeak(i,y); //处理峰值 LcdDrawLine(x,y,x,MAX_HEIGHT); //画线 } //每2点显示 p=14; for(i=14;i<24;i++) { x++; y=0; for(j=0;j<2;j++) { y+=sqrt(Re[p]*Re[p]+Im[p]*Im[p]); //计算模值 p++; } y/=20; //取平均值 y=Compress(y); //压缩 y=MAX_HEIGHT-y; //换算为屏幕y轴位置 ProcPeak(i,y); //处理峰值 LcdDrawLine(x,y,x,MAX_HEIGHT); //画线 } //每3点显示 for(i=24;i<34;i++) { x++; y=0; for(j=0;j<3;j++) { y+=sqrt(Re[p]*Re[p]+Im[p]*Im[p]); //计算模值 p++; } y/=30; //取平均值 y=Compress(y); //压缩 y=MAX_HEIGHT-y; //换算为屏幕y轴位置 ProcPeak(i,y); //处理峰值 LcdDrawLine(x,y,x,MAX_HEIGHT); //画线 } //每4点显示 for(i=34;i<44;i++) { x++; y=0; for(j=0;j<4;j++) { y+=sqrt(Re[p]*Re[p]+Im[p]*Im[p]); //计算模值 p++; } y/=40; //取平均值 y=Compress(y); //压缩 y=MAX_HEIGHT-y; //换算为屏幕y轴位置 ProcPeak(i,y); //处理峰值 LcdDrawLine(x,y,x,MAX_HEIGHT); //画线 } //每6点显示 for(i=44;i<54;i++) { x++; y=0; for(j=0;j<6;j++) { y+=sqrt(Re[p]*Re[p]+Im[p]*Im[p]); //计算模值 p++; } y/=60; //取平均值 y=Compress(y); //压缩 y=MAX_HEIGHT-y; //换算为屏幕y轴位置 ProcPeak(i,y); //处理峰值 LcdDrawLine(x,y,x,MAX_HEIGHT); //画线 } //每9点显示 for(i=54;i<64;i++) { x++; y=0; for(j=0;j<9;j++) { y+=sqrt(Re[p]*Re[p]+Im[p]*Im[p]); //计算模值 p++; } y/=90; //取平均值 y=Compress(y); //压缩 y=MAX_HEIGHT-y; //换算为屏幕y轴位置 ProcPeak(i,y); //处理峰值 LcdDrawLine(x,y,x,MAX_HEIGHT); //画线 } for(i=0;i<64;i++) { LcdDrawPoint(i+17,Peak[i]); } LcdRefresh(); //刷新 }
void show_menu() { LcdClearBuf(); switch(menu.screen) { case WELCOME: { LcdSetXY(0,0); LcdPutStr("StrobeTuner", NORMAL); LcdSetXY(0,10); LcdPutStr("(C) MK 2016", NORMAL); LcdSetXY(0,35); LcdPutStr("Press any key.", NORMAL); } break; case MAIN_SCREEN: { LcdSetXY(0,0); switch(get_vfd_status()) { case VFD_STOPPED: LcdPutStr("Stopped", NORMAL); break; case VFD_SPIN_UP: LcdPutStr("SpinUp", NORMAL); break; case VFD_SPIN_DOWN: LcdPutStr("SpinDown", NORMAL); break; case VFD_IN_SYNC: LcdPutStr("Running", NORMAL); break; } LcdSetXY(0, 9); print_pitch_name(tuner_cfg()->resultant_note, NORMAL); LcdPutInt(tuner_cfg()->octave_index, 0, NORMAL); LcdSetXY(47, 9); if(tuner_cfg()->cent_offset > 0) { LcdPutStr("+ ", NORMAL); LcdPutInt(tuner_cfg()->cent_offset, 0, NORMAL); } else if (tuner_cfg()->cent_offset < 0) { LcdPutStr("- ", NORMAL); LcdPutInt(-tuner_cfg()->cent_offset, 0, NORMAL); } else { LcdPutStr("+/- 0", NORMAL); } LcdPutStr("c", NORMAL); LcdSetXY(0, 18); print_temperament_name(tuner_cfg()->temperament, NORMAL); LcdSetXY(0, 27); LcdPutStr("A4= ", NORMAL); LcdPutInt(tuner_cfg()->A_ref_freq/10, 0, NORMAL); LcdPutStr(".", NORMAL); LcdPutInt(tuner_cfg()->A_ref_freq%10, 0, NORMAL); LcdPutStr("Hz", NORMAL); LcdSetXY(0, 42); LcdPutStr("F= ", NORMAL); LcdPutInt(tuner_cfg()->final_freq/1000, 0, NORMAL); LcdPutStr(".", NORMAL); LcdPutInt(tuner_cfg()->final_freq%1000, 3, NORMAL); LcdPutStr("Hz", NORMAL); } break; case SETTINGS: { LcdSetXY(7,0); LcdPutStr("-SETTINGS-", NORMAL); LcdSetXY(0,8); LcdPutStr(" root ", (menu.settings_scr.selection == SEL_ROOT ? INVERTED : NORMAL)); print_pitch_name(tuner_cfg()->root_note, (menu.settings_scr.selection == SEL_ROOT ? INVERTED : NORMAL)); LcdSetXY(0,16); LcdPutStr(" temperament ", (menu.settings_scr.selection == SEL_TEMPERAMENT ? INVERTED : NORMAL)); LcdSetXY(0,24); LcdPutStr(" A frequency ", (menu.settings_scr.selection == SEL_A_FREQ ? INVERTED : NORMAL)); LcdSetXY(0,32); LcdPutStr(" screen setup", (menu.settings_scr.selection == SEL_SCREEN ? INVERTED : NORMAL)); LcdSetXY(0,40); LcdPutStr(" exit ", (menu.settings_scr.selection == SEL_EXIT ? INVERTED : NORMAL)); } break; case SET_ROOT_NOTE: { LcdSetXY(3, 0); LcdPutStr("-ROOT NOTE-", NORMAL); LcdSetXY(10, 15); LcdPutStr("< ", NORMAL); print_pitch_name(tuner_cfg()->root_note, NORMAL); LcdSetXY(53, 15); LcdPutStr(">", NORMAL); LcdSetXY(0,30); LcdPutStr(" exit ", INVERTED); } break; case SET_TEMPERAMENT: { LcdSetXY(3, 0); LcdPutStr("-TEMPERAM.-", NORMAL); LcdSetXY(0,15); print_temperament_name(tuner_cfg()->temperament, NORMAL); LcdSetXY(1, 24); LcdPutStr("< ", NORMAL); LcdSetXY(79, 24); LcdPutStr(">", NORMAL); LcdSetXY(0,36); LcdPutStr(" exit ", INVERTED); } break; case SET_A_FREQ: { LcdSetXY(6, 0); LcdPutStr("-REF. PITCH-", NORMAL); LcdSetXY(10, 15); LcdPutStr("< ", NORMAL); LcdPutInt(tuner_cfg()->A_ref_freq/10, 0, NORMAL); LcdPutStr(".", NORMAL); LcdPutInt(tuner_cfg()->A_ref_freq%10, 0, NORMAL); LcdPutStr("Hz", NORMAL); LcdSetXY(70, 15); LcdPutStr(">", NORMAL); LcdSetXY(0,30); LcdPutStr(" exit ", INVERTED); } break; case SET_SCREEN: { LcdSetXY(2, 0); LcdPutStr("-LCD SETUP-", NORMAL); LcdSetXY(0,10); LcdPutStr(" backlight ", (menu.lcd_settings_scr.selection == SEL_SCR_BRIGHT ? INVERTED : NORMAL)); LcdSetXY(0,20); LcdPutStr(" contrast ", (menu.lcd_settings_scr.selection == SEL_SCR_CON ? INVERTED : NORMAL)); LcdSetXY(0,30); LcdPutStr(" exit ", (menu.lcd_settings_scr.selection == SEL_SCR_EXIT ? INVERTED : NORMAL)); } break; case SET_CONTRAST: { LcdSetXY(4, 0); LcdPutStr("-CONTRAST-", NORMAL); LcdSetXY(32, 15); LcdPutStr("< ", NORMAL); LcdPutInt(lcd_cfg()->contrast, 0, NORMAL); LcdSetXY(50, 15); LcdPutStr(">", NORMAL); LcdSetXY(0,30); LcdPutStr(" exit ", INVERTED); } break; case SET_BRIGHTNESS: { LcdSetXY(3, 0); LcdPutStr("-BACKLIGHT-", NORMAL); LcdSetXY(32, 15); LcdPutStr("< ", NORMAL); LcdPutInt(lcd_cfg()->brightness, 0, NORMAL); LcdSetXY(50, 15); LcdPutStr(">", NORMAL); LcdSetXY(0,30); LcdPutStr(" exit ", INVERTED); } break; default: break; } LcdRefresh(); }
/******************************************************************** 函数功能:主函数。 入口参数:无。 返 回:无。 备 注:无。 ********************************************************************/ void main(void) { #ifdef DEBUG0 int i; #endif int InterruptSource; SystemClockInit(); //系统时钟初始化 LedInit(); //LED对应的管脚初始化 LcdInit(); //LCD初始化 AdcInit(); //ADC初始化 Timer1Init(); //定时器1初始化,用来产生10ms的定时扫描信号 KeyInit(); //键盘初始化 Uart0Init(); //串口0初始化 #ifdef DEBUG0 for(i=0;i<16;i++) //显示头信息 { Prints(HeadTable[i]); } #endif UsbChipInit(); //初始化USB部分 while(1) { InterruptSource=(*AT91C_UDP_ISR)&(0x0F|(1<<8)|(1<<12)); //取出需要的中断 if(InterruptSource) //如果监视的中断发生 { if(InterruptSource&(1<<8)) { *AT91C_UDP_ICR=1<<8; //清除中断 UsbBusSuspend(); //总线挂起中断处理 } if(InterruptSource&(1<<12)) { *AT91C_UDP_ICR=1<<12; //清除中断 UsbBusReset(); //总线复位中断处理 } if(InterruptSource&(1<<0)) { if(AT91C_UDP_CSR[0]&((1<<1)|(1<<2)|(1<<6))) //如果是SETUP包、缓冲未空等 { UsbEp0Out(); //端点0输出中断处理 } if(AT91C_UDP_CSR[0]&(1<<0)) //如果是端点0输入完成 { UsbEp0In(); //端点0输入中断处理 } } if(InterruptSource&(1<<1)) { UsbEp1In(); //端点1输入中断处理 } if(InterruptSource&(1<<2)) { UsbEp2Out(); //端点2输出中断处理 } if(InterruptSource&(1<<3)) { UsbEp3In(); //端点3输入中断处理 } } if(KeyUp||KeyDown) //如果用户操作了按键 { DispKey(); //在LCD上显示按键情况 if(ConfigValue!=0) //如果已经设置为非0的配置,则可以返回报告数据 { if(!Ep1InIsBusy) //如果端点1输入没有处于忙状态,则可以发送数据 { KeyCanChange=0; //禁止按键扫描 if(KeyUp||KeyDown) //如果有按键事件发生 { SendReport(); //则返回报告 } KeyCanChange=1; //允许按键扫描 } } //清除KeyUp和KeyDown KeyUp=0; KeyDown=0; LcdRefresh(); //刷新LCD显示 } } }