Кстати а в каком же исходнике я меню то смотрел? Вроде папка называлать Годо/Зак.
Скорее всего, это был "старый" годограф, для дисплея Nokia.
/*--------------------------------------------------------------------------------------------------
Name : go200.c
Description : Main project file for the Godo v2.04
Version : 1.01
Author : Nickolay Zakrzhevsky
Created : 18 jun 2006
Home page :
www.md4u.ru/godo.html E-Mail :
go@md4u.ru--------------------------------------------------------------------------------------------------*/
// Target : M32
// Crystal : 8.0Mhz (int. osc.)
// Fuse bit : 0xD9E1
#include <iom32v.h>
#include <macros.h>
#include <MATH.H>
#include "KS108LCD.h"
#define btn_left 128 // PB7
#define btn_up 64 // PB6
#define btn_down 32 // PB5
#define btn_right 16 // PB4
///////////////////////// PB3 (OC0) - sound
#define btn_soft1 4 // PB2
#define btn_soft2 2 // PB1
/////////////////////////////////Menu items definitions
#define profile item1[3].value
#define mode item1[4].value
#define freq item1[5].value
#define VCO_sel item2[1][1].value[item1[3].value]
#define VCO_mode item2[1][2].value[item1[3].value]
typedef struct
{
unsigned char name[9];
unsigned char min;
unsigned char max;
unsigned char value;
}itm;
typedef struct
{
unsigned char name[9];
unsigned char min;
unsigned char max;
unsigned char value[5];
}itm2;
// name min max value
itm item1[7] = {{"DISPLAY ",0, 0, 0}, // 0 sub menu
{"SOUND ",0, 0, 0}, // 1 sub menu
{"BATTERY ",0, 0, 0}, // 2 sub menu
{"Profile ",0, 4, 0}, // 3
{"Mode ",0, 2, 0}, // 4
{"Freq ",0, 2, 0}, // 5
{"Save set ",0, 1, 0}}; // 6
// name min max value[5] (profiles 0..4 )
itm2 item2[3][7] = {{{"Trace len",0,191,{190,190,190,190,190}}, // 0 0
{"Aprox cnt",0, 99,{ 05, 05, 05, 05, 05}}, // 1
{"X offset ",0,250,{117,127,127,127,127}}, // 2
{"Fall spd ",0, 50,{ 10, 10, 10, 10, 10}}, // 3
{"VDI disp ",0, 1,{ 1, 1, 1, 1, 1}}, // 4
{"Invert X ",0, 1,{ 0, 0, 0, 0, 0}}, // 5
{"Invert Y ",0, 1,{ 0, 0, 0, 0, 0}}},// 6
{{"All sound",0, 1,{ 1, 1, 1, 1, 1}}, // 0 1
{"VCO ",0, 1,{ 1, 1, 1, 1, 1}}, // 1
{"VCO mode ",0, 4,{ 0, 0, 0, 0, 0}}, // 2
{"VCO thr. ",0,100,{ 05, 20, 40, 05, 05}}, // 3
{"Keypad ",0, 1,{ 1, 1, 1, 1, 1}}, // 4
{"Power on ",0, 1,{ 1, 1, 1, 1, 1}}, // 5
{"Batt low ",0, 1,{ 1, 1, 1, 1, 1}}},// 6
{{"Thr. #3 ",0,255,{155,160,160,160,160}}, // 0 2
{"Thr. #2 ",0,255,{148,130,130,130,130}}, // 1
{"Thr. #1 ",0,255,{135,110,110,110,110}}, // 2
{"Thr. beep",0,255,{131,100,100,100,100}}, // 3
{"Disp.val.",0, 1,{ 0, 0, 0, 0, 1}}, // 4
{" N/A ",0, 2,{ 0, 0, 0, 0, 0}}, // 5
{" N/A ",0, 2,{ 0, 0, 0, 0, 0}}}}; // 6
unsigned char ADC_enable,n_clr;
unsigned char mnu_sel_n,mnu2_sel_n,mnu_mod;
unsigned char sound_time;
unsigned char spec[18]={0,0,0,0,0,0,0,0,0,0,0,0,0};//{35,1,2,4,8,16,32,64,128,255,128,80,60,50,40,30,20,66};
unsigned char tan_t[46]={0,4,9,13,18,22,27,31,36,41,45,50,54,59,64,69,73,78,83,88,93,98,103,109,
114,119,125,130,136,142,148,154,160,166,173,179,186,193,200,207,215,223,231,239,247,256};
void ee_write(unsigned int uiAddress, unsigned char ucData);
unsigned char ee_read(unsigned int uiAddress);
void draw_bat(unsigned char value);
void timer1_init8k(void);
void timer1_init6k(void);
void init_devices(void);
void welcome_screen(char eeprom_read);
void draw_cpy(void);
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
#pragma interrupt_handler timer1_ovf_isr:10
void timer1_ovf_isr(void) //TIMER1 has overflowed
{
if (freq==0)
{
TCNT1H = 0xFE; // 8192x2Hz
TCNT1L = 0x2d; //
}
else
{
TCNT1H = 0xFD; // 6592x2Hz
TCNT1L = 0xB2; //
}
}
void DrawMenu(void)
{
unsigned char i;
LcdClear();
if ((mnu_mod==1) || (mnu_mod==2))
{
LcdStr(" MAIN MENU",1,1);
for(i=0;i<7;i++)
{
LcdStr(item1[i].name,2,i+2);
if (item1[i].max == 0) LcdStr(" >", 12,i+2);
if (item1[i].max == 1) {if (item1[i].value==1) LcdStr("Yes", 12,i+2); else LcdStr(" No", 12,i+2); }
if (item1[i].max > 1) LcdDrawIntN(item1[i].value,3,10,i+2);
}
}
if (mnu_mod>2)
{
LcdStr(item1[mnu_sel_n].name,1,1);
for(i=0;i<7;i++)
{
LcdStr(item2[mnu_sel_n][i].name,2,i+2);
if (item2[mnu_sel_n][i].max == 1) { if (item2[mnu_sel_n][i].value[profile]==1 ) LcdStr("Yes", 12,i+2); else LcdStr(" No", 12,i+2); }
if (item2[mnu_sel_n][i].max > 1) LcdDrawIntN(item2[mnu_sel_n][i].value[profile],3,10,i+2);
}
}
if (mnu_mod==1) InvStr(2,mnu_sel_n+2,13);
if (mnu_mod==2) InvStr(12,mnu_sel_n+2,3);
if (mnu_mod==3) InvStr(2,mnu2_sel_n+2,13);
if (mnu_mod==4) InvStr(12,mnu2_sel_n+2,3);
}
////////////////////////////////////////////////////////////////////////////////
void DrawSpectrum(void)
{
unsigned char i,j,k,c,b,spe;
for (j=1;j<8;j++)
{
SetPage(j);
for (i=0;i<18;i++)
{
SetColumn(7*i);
if ((i*7)>63) c=LCD_CS2; else c=LCD_CS1;
SendLcdData(0xEE,c);
if (spec[i]<((8-j)*32)) if (spec[i]>((7-j)*32)) b= 0xff^(0xff >> ((spec[i]%32)/4));
if (spec[i]>((8-j)*32)) b=0xff;
if (spec[i]<((7-j)*32)) b=0;
if (i==9) { SetColumn(64); c=LCD_CS2;} // if col=9 then right side(cs2) ?
for (k=0;k<6;k++) SendLcdData(b,c); //repeat 6 times
if (i==17) SendLcdData(0xEE,c);
}
}
}
////////////////////////////////////////////////////////////////////////////////
void beep(char delay, char snd_freq)
{
char i;
if (item2[1][0].value[profile]==1) TCCR0 = 0x1A; //if Sound enable
OCR0 = snd_freq;
sound_time=delay;
}
////////////////////////////////////////////////////////////////////////////////
#pragma interrupt_handler timer2_ovf_isr:6
void timer2_ovf_isr(void)
{
if (sound_time>0) sound_time--; else TCCR0 = 0x00; //Sound off
if (n_clr>0) n_clr--; /// not solved
TCNT2 = 0xB2; //reload counter value
}
////////////////////////////////////////////////////////////////////////////////
void SaveProfile(char ProfileN )
{
unsigned char aa,bb,cc;
CLI(); //disable all interrupts
for (aa=0; aa<7; aa++)
{
for (bb=0; bb<3; bb++)
{
cc=item2[bb][aa].value[ProfileN];
ee_write((char)(10+aa+(bb*7)+(ProfileN*21)),cc); //10 is for more safety
}
}
cc=profile; ee_write(201,cc);
cc=mode; ee_write(202,cc);
cc=freq; ee_write(203,cc);
SEI(); //re-enable interrupts
}
////////////////////////////////////////////////////////////////////////////////
unsigned char LoadProfiles(void )
{
unsigned char aa,bb,cc,pp;
CLI(); //disable all interrupts
cc=ee_read(10); //read first cell
if ((cc!=255)&&(PINB & btn_soft1)) // if EE not clear & soft1 not pressed
{
for (aa=0; aa<7; aa++)
{
for (bb=0; bb<3; bb++)
{
for (pp=0; pp<5; pp++)
{
cc=ee_read((char)(10+aa+(bb*7)+(pp*21)));
item2[bb][aa].value[pp]=cc;
}
}
}
cc=ee_read(201); profile=cc; // main menu load !
cc=ee_read(202); mode=cc;
cc=ee_read(203); freq=cc;
}
cc=ee_read(10); //read first cell
SEI(); //re-enable interrupts
return cc; // return 0xFF if EEPROM is Clear
}
////////////////////////////////////////////////////////////////////////////////
void delay_s(unsigned char time)
{
unsigned int i,j;
for (i=0;i<50000;i++) for (j=0;j<time;j++)asm("nop"); // delay
}
////////////////////////////////////////////////////////////////////////////////
void main(void)
{
unsigned char adc_val;
unsigned char x,y;
unsigned int x_acc,y_acc; // calc coord
unsigned char dx,dy,dx2,dy2,mx2,my2;
unsigned char sp_y;
unsigned char spe_i;
unsigned char mx[200],my[200],mi; // store dots coord
unsigned char v_bat;
unsigned int cy_cnt;
unsigned int ADC_cnt;
unsigned int a,b,xx;
int x_off;
float AMP,a_f,b_f;
unsigned char curAMP,maxAMP;
unsigned char VDI,i,ang;
unsigned char ADC_cnt_aprox=0;
unsigned char batt_beep_delay_cnt;
init_devices();
LcdInit();
batt_beep_delay_cnt=0;
adc_val=LoadProfiles();
if (freq==0) timer1_init8k(); else timer1_init6k();
if (freq==0) LcdStr("8192Hz",12,4); else LcdStr("6592Hz",12,4);
welcome_screen(adc_val);
if (item2[1][5].value[profile]==1) //if PWR on Sound enable
{
delay_s(6);
beep(6,250);
delay_s(3);
beep(6,230);
delay_s(2);
beep(6,200);
delay_s(1);
} else delay_s(15);
if (adc_val==255) // EEPROM CLEAR ?
for (adc_val=0;adc_val<5;adc_val++) SaveProfile(adc_val); // Save def. settings for all profiles in EEPROM
n_clr=0; v_bat=250; ADC_cnt=0; cy_cnt=1;
LcdClear();
mode=0;
for (x=0;x<199;x++) { mx[x]=63;my[x]=63;}
dx=63;dy=63;dx2=63;dy2=63;mx2=63;my2=63;mi=1;
maxAMP=0;curAMP=0;
ADC_cnt_aprox=0;
ADC_enable =1;
while(1) ///////////////////////////////////////////////////////////////////////
{
if (((ADCSRA & (1<<ADSC)) == 0)&(ADC_enable !=0 )) // if ADC complete then start ADC subroutine
{
adc_val=ADCH; // read ADC
if (ADMUX == 0xE0)
{
ADMUX=0xE1;
if (item2[0][6].value[profile]==1) y=(255-adc_val); else y=adc_val; // if invert Y
y_acc+=y;
ADC_cnt_aprox++;
} else // ADC channel 0 (y)
if (ADMUX == 0xE1)
{
ADMUX=0xE0;
if (item2[0][5].value[profile]==1) x=(255-adc_val); else x=adc_val; // if inv X
// x_acc+=(x+127-item2[0][2].value[profile]);
// LcdDrawIntN((char)x_off,3,16,4);
x_off=(x+item2[0][2].value[profile]-127); // NE RABOTAET ????????
x_acc+=(char)x_off;
ADC_cnt_aprox++;
if (ADC_cnt==30) ADMUX=0xe3; // Get BAT voltage
if ( ADC_cnt<255) ADC_cnt++; else ADC_cnt=0; // inc ADC counter
} else // ADC channel 1 (X)
if (ADMUX == 0xE3) {ADMUX=0xE0; v_bat=adc_val; } // ADC channel 3 ext pow. +12v
if( ADC_cnt_aprox==(item2[0][1].value[profile]*2))
{
//////////////////////////////////////////// VDI calc begin //////
a=255-(y_acc/item2[0][1].value[profile]);
b=(x_acc/item2[0][1].value[profile]);
ang=8;
VDI=0;
if (b>=127) // 0..90 grad
{
if (a<(b-127)) { xx=(a*256)/(b-127); ang= 0;} // 0..45 grad
if (a>(b-127)) { xx=((b-127)*256)/a; ang= 1;} //46..90 grad
}
if (b< 127) //90..180 grad
{
if (a>(127-b)) { xx=((127-b)*256)/a; ang= 2;} // 90..135 grad
if (a<(127-b)) { xx=(a*256)/(127-b); ang= 3;} //135..180 grad
}
for (i=0;i<45;i++) { if (tan_t[i]<=xx) {if (tan_t[i+1]>xx) VDI=i;} }
if (ang==1) VDI=45+(45-VDI); else
if (ang==2) VDI=90+VDI; else
if (ang==3) VDI=135+(45-VDI); else
a_f=(a*a);
b_f=((b-127)*(b-127));
AMP=sqrt(a_f+b_f);
if (AMP>255) AMP=255;
curAMP=(char)AMP;
if (curAMP>item2[1][3].value[profile]) // AMP > VCOthreshold ?
{
if (maxAMP<curAMP) // tit gluki est'
{
maxAMP=curAMP;
if (item2[0][4].value[profile]==1) //VDI disp enabled ?
{ LcdStr("'",6,1); LcdDrawIntN((char)VDI,3,5,1); } // draw "V" and VDI value
}
}
else
{
maxAMP=0;
}
// LcdDrawIntN(curAMP,3,16,4);
// LcdDrawIntN(maxAMP,3,16,5);
// LcdDrawIntN((char)a,3,12,2); //a
// LcdDrawIntN((char)b,3,16,2); //b
// LcdDrawIntN((char)VDI,3,5,1); // draw "V" and VDI value
//////////////////////////////////////////// VDI calc end//////
if (mode==0) // if GODOGRAPH mode
{
dx2=dx;
dy2=dy;
// dx=(char)(x_acc/(item2[0][1].value[profile]*2)); //2x scale
// dy=(char)(y_acc/(item2[0][1].value[profile]*4)); //4x scale
dx=(char)(x_acc/(item2[0][1].value[profile]))-64; //2x scale
dy=(char)(y_acc/(item2[0][1].value[profile]*2))-64; //4x scale
if(dy>63)dy=63; /////// NE RABOTAET
if(dy<1)dy=1;
if(dx>127)dx=127;
if(dx<1)dx=1;
LcdLine(dx2,dy2,dx,dy,PIXEL_ON);// LcdPixel(dx,dy,PIXEL_ON);
mx[mi]=dx;
my[mi]=dy;
if (mi <item2[0][0].value[profile]) mi++; else mi=0;
if (mi <item2[0][0].value[profile]) { mx2=mx[mi+1]; my2=my[mi+1];} else { mx2=mx[0]; my2=my[0];}
LcdLine(mx[mi],my[mi],mx2,my2,PIXEL_OFF);// LcdPixel(mx[mi],my[mi],PIXEL_OFF);
}
if (mode==1) // if SPECTRUM mode
{
sp_y=(char)(curAMP*5);
spe_i=(VDI/10);
if (spec[spe_i]<sp_y) spec[spe_i]=sp_y;
DrawSpectrum();
for (spe_i=0;spe_i<18;spe_i++)
{
if (spec[spe_i]>item2[0][3].value[profile]) spec[spe_i]-=item2[0][3].value[profile];
else spec[spe_i]=4;
}
}
//////////////////////make sound
if (curAMP>item2[1][3].value[profile]) // AMP > Threshold ?
if (VCO_sel==1) // if VCO Enabled
{
if (VCO_mode==0) beep(1, 10+(VDI+(VDI/2)));
if (VCO_mode==1) if (VDI<90) beep(1, 20+VDI+VDI);
if (VCO_mode==2) if (VDI<90) beep(1, 70+((VDI/16)*32)); // VCO mode select !!!
if (VCO_mode==3) if (VDI<90) beep(1, 250-(VDI+VDI));
if (VCO_mode==4) if (VDI<90) beep(1, 250-((VDI/16)*32));
}
//////////////////////// sound end
x_acc=0;
y_acc=0;
ADC_cnt_aprox=0;
}//adc_cnt_aprox end!
if (ADC_enable !=0 ) ADCSRA |= (1<<ADSC); // start ADC
}
///////////////////////////////////////////////////////////////////////////////
///////////////////////// ADC subroutine END /////////////////////////////
///////////////////////////////////////////////////////////////////////////////
if ( cy_cnt<500) cy_cnt++; else cy_cnt=0;
if (mnu_mod>0) { if (n_clr==10) DrawMenu(); ADC_enable=0;}
if (item1[6].value==1) // if SAVE Select !!!!
{
item1[6].value=0; // menu item OFF
SaveProfile(profile);
beep(5,220);
mnu_mod=1;
}
if ((cy_cnt ==10)&& (mnu_mod==0))
{
if (v_bat >= item2[2][0].value[profile]) draw_bat(3); else
if (v_bat >= item2[2][1].value[profile]) draw_bat(2); else
if (v_bat >= item2[2][2].value[profile]) draw_bat(1); else draw_bat(0);
if (item2[1][6].value[profile]==1) // key Batt low sound enable?
if (v_bat < item2[2][3].value[profile])
if (batt_beep_delay_cnt<2) beep(5,153);
if (batt_beep_delay_cnt<255)batt_beep_delay_cnt++; else batt_beep_delay_cnt=0;
if ( item2[2][4].value[profile]!=0 ) LcdDrawIntN(v_bat,3,14,1);
LcdChr('P',13,1); LcdChr('0'+profile,14,1); //profile N
// Go Sp
if (mode==0) LcdStr("<",1,1); else if (mode==1) LcdStr("=",1,1);
if (VCO_sel==1){LcdStr("_",3,1);LcdChr('0'+VCO_mode,4,1); }else LcdStr(" ",3,1);
}
if (!(PINB & btn_left)) //// "<" Left
if (n_clr==0)
{
if (mnu_mod==0) if (profile>0)profile--; else profile=4;
if (mnu_mod==4) mnu_mod=3; else
if (mnu_mod==3) mnu_mod=1; else
if (mnu_mod==2) mnu_mod=1;
if (item2[1][4].value[profile]==1) beep(1,120); // key beep sound enable?
n_clr=30;
}
if (!(PINB & btn_up)) //// "^" UP
if (n_clr==0)
{
if (mnu_mod==0)if (VCO_mode<4) VCO_mode++; else VCO_mode=0;
if (mnu_mod==1)if (mnu_sel_n>0) mnu_sel_n--;
if (mnu_mod==2)if (item1[mnu_sel_n].value < item1[mnu_sel_n].max) item1[mnu_sel_n].value++;
if (mnu_mod==3)if (mnu2_sel_n>0) mnu2_sel_n--;
if (mnu_mod==4)if (item2[mnu_sel_n][mnu2_sel_n].value[profile] < item2[mnu_sel_n][mnu2_sel_n].max) item2[mnu_sel_n][mnu2_sel_n].value[profile]++;
if (item2[1][4].value[profile]==1) beep(1,120); // key beep sound enable?
n_clr=30;
}
if (!(PINB & btn_right)) //// ">" right
if (n_clr==0)
{
if (mnu_mod==0){if (mode==1) mode=0; else mode=1; LcdClear();}
if (mnu_mod==3) mnu_mod=4;
if (mnu_mod==1)
{
if (item1[mnu_sel_n].max==0)
{ mnu_mod=3; mnu2_sel_n=0;} else mnu_mod=2;
}
if (item2[1][4].value[profile]==1) beep(1,120); // key beep sound enable?
n_clr=30;
}
if (!(PINB & btn_down)) //// "v" down
if (n_clr==0)
{
if (mnu_mod==0)if (VCO_sel==1) VCO_sel=0; else VCO_sel=1;
if (mnu_mod==1)if (mnu_sel_n<6) mnu_sel_n++;
if (mnu_mod==2)if (item1[mnu_sel_n].value>item1[mnu_sel_n].min) item1[mnu_sel_n].value--;
if (mnu_mod==3)if (mnu2_sel_n<6) mnu2_sel_n++;
if (mnu_mod==4)if (item2[mnu_sel_n][mnu2_sel_n].value[profile]>item2[mnu_sel_n][mnu2_sel_n].min) item2[mnu_sel_n][mnu2_sel_n].value[profile]--;
if (item2[1][4].value[profile]==1) beep(1,120); // key beep sound enable?
n_clr=30;
}
if (!(PINB & btn_soft1)) //// soft1 (left)
if (n_clr==0)
{
LcdClear();
// if (mode < 2) mode++; else mode=1;
if (profile<4)profile++; else profile=0;
if (item2[1][4].value[profile]==1) beep(1,120); // key beep sound enable?
n_clr=30;
}
if (!(PINB & btn_soft2)) //// soft2 (right)
if (n_clr==0)
{
if (mnu_mod==0) mnu_mod=1; else
{
if ((mnu_mod==4) && (mode==2)) draw_cpy(); else
mnu_mod=0; LcdClear(); ADC_enable=1;
}
if (item2[1][4].value[profile]==1) beep(1,120); // key beep sound enable?
n_clr=30;
}
}///while end /////////////////////////////////////////////////////////////////
}
Ой, что-то я сейчас посмотрел.... такая ерунда
как я мог такое написать, это не серьёзно всё...