?lang_form? ?lang_select? ?lang_submit? ?lang_endform?
{HEADER END}
{FILE START}

library

?curdirlinks? - Rev 3

?prevdifflink? - Blame - ?getfile?

// HFV - High Frequency Voltmeter - Firmware
// (c)miho 2002
//
// Historie:
//
//    0.00  Uvodni verze

#define VERSION "0.00"


// Zakladni nastaveni prekladace
//
#include <16F876.h>
#device ADC=10
#use delay(clock=4000000)
#fuses XT,NOWDT,NOBROWNOUT,NOLVP
#case


// Matematicka knihovna
//
#include "MATHA.C"


// Knihovna pro LCD display
//
#define LCD_RS          PIN_B2      // rizeni registru LCD displeje
#define LCD_E           PIN_B1      // enable LCD displeje
#define LCD_DATA_LSB    PIN_C2      // pripojeni LSB bitu datoveho portu LCD displeje (celkem 4 bity vzestupne za sebou)
#include "LCD.C"


// Knihovna pro obsluhu tlacitek
//
#include "KBD_B4.C"


// Knihovna pro pristup do pameti EEPROM
//
#include <EEPROM.C>


// Casova smycka pro zakladni cyklus obsluhy
//
// Predpoklada pripojeni krystalu 32768Hz na TIMER1, slouzi pro definovani delky intervalu
// spanku.
//

#define IPS 64                            // pocet preruseni za sekundu od casovace 1
#define TIMERXTAL 32768                   // frekvence krystalu casovace 1

BOOLEAN Timer1;                           // semafor nastavovany pri vstupu do preruseni od casovace 1

long int TimerCounter;                    // pomocna promenna pro odmerovani spozdeni

#int_timer1
void IntTimer1()
{
   Timer1=TRUE;                           // bylo peruseni od timeru 1

   if (TimerCounter>0) TimerCounter--;    // zmensi pomocny citac

   set_timer1(-TIMERXTAL/IPS);            // znovu natahni Timer 1

   if (kbd_timer!=0 && kbd_state==0)      // kbd_k4.c
   {                                      // kbd_k4.c
      kbd_timer--;                        // kbd_k4.c
   }                                      // kbd_k4.c
}


// Kalibracni konstanty (nactene z EEPROM)
//
long int VREF;
float K1, K2;
#define EE_SUMA   0        // int8     kontrolni suma
#define EE_VREF   1        // int16    napeti reference v mV
#define EE_K1     3        // float    kalibracni konstanta K1
#define EE_K2     7        // float    kalibracni konstanta K2
#define EE_MEMORY 11       // int16    zde zacinaji pametove bunky

#define VREF_LOW     2000     // spodni mez platneho VREF
#define VREF_HIGH    6000     // horni mez platneho VREF
#define VREF_DEFAULT 3735     // defaultni hodnota napeti reference
#define VREF_STEP    5        // krok pro nastavovani hodnoty VREF pri kalibraci


// Mereni napeti baterie
//

#define HFV_ENABLE      PIN_A5            // zapinani detekcni sondy

float Read_Vdd()
{
   long int Vdd;

   setup_adc(ADC_CLOCK_INTERNAL);         // zapni prevodnik
   setup_adc_ports(RA0_RA1_RA3_ANALOG);   // reference je Vdd
   set_adc_channel(3);                    // nastav mereni RA3 - reference
   delay_us(20);                          // pockej na ustaleni
   Vdd=read_adc();                        // precti hodnotu
   setup_adc(ADC_OFF);                    // vypni prevodnik
   return ((float)VREF*1.023)/Vdd;         // prepocti hodnotu na volty
}


// Mereni napeti na vystupu sondy (napeti umerne logaritmu amplitudy signalu)
// Pozor mereni se musi provadet pravidelne a dosatatecne casto (asi 50x za sekundu)
// aby se v pauzach nevybily kondenzatory
//

#DEFINE MULT_FACTOR 10

signed long int read_hfv()
{
   int i;                                 // pocitadlo opakovani mereni
   signed long int Hfv;                   // vysledek

   Hfv=0;                                 // nuluj stradac
   for (i=MULT_FACTOR;i!=0;i--)           // oapkovani
   {
      output_high(HFV_ENABLE);               // zapni sondu
      delay_us(400);                         // pockej na jeji aktivaci
      setup_adc(ADC_CLOCK_INTERNAL);         // nastav prevodnik
      setup_adc_ports(RA0_RA1_ANALOG_RA3_REF);
      set_adc_channel(0);                    // vyber kanal
      delay_us(20);                          // pockej na ustaleni
      Hfv+=read_adc();                       // precti hodnotu
      output_low(HFV_ENABLE);                // odpoj sondu
      setup_adc(ADC_OFF);                    // vypni prevodnik
      sleep();                               // prodleva
   }
   return Hfv;
}


// Spocitej kontrolni soucet EEPROM, casti s kalibracnimi konstantami
//
int Suma()
{
   unsigned int Adr;
   int Sum;

   Sum=0;
   for (Adr=0; Adr<EE_MEMORY; Adr++)
   {
      Sum += read_eeprom(Adr);
   }
   return Sum;
}

#define KLEVEL_HIGH_MAX       20
#define KLEVEL_HIGH_MIN       -50
#define KLEVEL_HIGH_START     0

#define KLEVEL_LOW_MAX        -30
#define KLEVEL_LOW_MIN        -90
#define KLEVEL_LOW_START      -60

#define KLEVEL_STEP           10


// Proved kalibraci
//
void Callibrate(BOOLEAN Requested)
{

   char c;
   signed int L1,L2;
   signed int16 A1,A2;

   printf(lcd_putc,"\f\nESC \20   \21   OK");

   // kalibrace VREF
   //
   do
   {
      printf(lcd_putc,"\rCAL Vref: %4ldmV",VREF);
      c=kbd_waitc();
      if (c==KBD_K1)
         {
            reset_cpu();
         }
      if (c==KBD_K2)
         {
            if (VREF<=VREF_HIGH-VREF_STEP) VREF += VREF_STEP;
         }
      if (c==KBD_K3)
         {
            if (VREF>=VREF_LOW+VREF_STEP) VREF -= VREF_STEP;
         }
   }
   while (c!=KBD_K4);
   EE_WR(EE_VREF, VREF);
   if (!Requested)
   {
      write_eeprom(EE_SUMA,read_eeprom(EE_SUMA)-Suma());       // dopocti kontrolni soucet a uloz ho
   }

   // Kalibrace High urovne
   //
   L1=KLEVEL_HIGH_START;
   do
   {
      printf(lcd_putc,"\rCAL High: %3ddBV",L1);
      c=kbd_waitc();
      if (c==KBD_K1)
         {
            reset_cpu();
         }
      if (c==KBD_K2)
         {
            if (L1<=KLEVEL_HIGH_MAX-KLEVEL_STEP) L1 += KLEVEL_STEP;
         }
      if (c==KBD_K3)
         {
            if (L1>=KLEVEL_HIGH_MIN+KLEVEL_STEP) L1 -= KLEVEL_STEP;
         }
   }
   while (c!=KBD_K4);
   for (c=10;c>0;c--) A1 = read_hfv();

   // Kalibrace Low urovne
   //
   L2=L1-60;
   do
   {
      printf(lcd_putc,"\rCAL Low:  %3ddBV",L2);
      c=kbd_waitc();
      if (c==KBD_K1)
         {
            reset_cpu();
         }
      if (c==KBD_K2)
         {
            if (L2<=L1-2*KLEVEL_STEP) L2 += KLEVEL_STEP;
         }
      if (c==KBD_K3)
         {
            if (L2>=KLEVEL_LOW_MIN+KLEVEL_STEP) L2 -= KLEVEL_STEP;
         }
   }
   while (c!=KBD_K4);
   for (c=10;c>0;c--) A2 = read_hfv();

   // Vypocti kalibracni konstanty a uloz je do EEPROM
   //
   K1 = (float)(L2-L1) / (float)(A2-A1);                    // vypocti K1 (strmost)
   K2 = ((float)L1*A2 - (float)L2*A1) / (float)(A2-A1);     // vypocti K2 (posunuti)
   EE_WR(EE_K1, K1);                                        // uloz K1 do EEPROM
   EE_WR(EE_K2, K2);                                        // uloz K2 do EEPROM
   write_eeprom(EE_SUMA,read_eeprom(EE_SUMA)-Suma());       // dopocti kontrolni soucet a uloz ho
   //printf(lcd_putc,"\fL1 %d L2 %d\nA1 %ld A2 %ld",L1,L2,A1,A2);
   //kbd_waitc();
   //printf(lcd_putc,"\fK1 %f\nK2 %f",K1,K2);
   //kbd_waitc();
}

#include "knob.c"

#define WARNINGVOLTAGE     4.75           // hranice pro varovani vybite baterie

void main()
{
   int c;
   int i;

   int Mode;

   // Inicializace nevyuzitych pinu
   //

   //output_low(PIN_A0);      // zde je analogovy vstup
//   output_low(PIN_A1);      // zde je otocny knoflik
//   output_low(PIN_A2);      // zde je otocny knoflik
   //output_low(PIN_A3);      // zde je napetova refence
   output_low(PIN_A4);
   output_low(PIN_A5);        // zde je rizeni

//   output_low(PIN_B0);      // zde je RTS#
   //output_low(PIN_B1);      // LCD_E
   //output_low(PIN_B2);      // LCD_RS
//   output_low(PIN_B3);      // zde je CTS#
   //output_low(PIN_B4);      // tlaciko 1
   //output_low(PIN_B5);      // tlaciko 2
   //output_low(PIN_B6);      // tlaciko 3
   //output_low(PIN_B7);      // tlaciko 4

   //output_low(PIN_C0);      // xtal 32768Hz
   //output_low(PIN_C1);      // xtal 32768Hz
   //output_low(PIN_C2);      // LCD D4 (LSB)
   //output_low(PIN_C3);      // LCD D5
   //output_low(PIN_C4);      // LCD D6
   //output_low(PIN_C5);      // LCD D7
   output_low(PIN_C6);        // RS232 TX
   output_low(PIN_C7);        // RS232 RX


   // Zakladni vypis
   //
   lcd_init();
   printf(lcd_putc,"\fHF Vmeter " VERSION);
   delay_ms(100);                                           // cas pro ustaleni napajeni
   lcd_define_char(0,LCD_CHAR_UP LCD_CHAR_DOWN);            // Znaky sipka nahoru a sipka dolu od pozice 0


   // Inicializace zakladni casovaci smycky casovane pomoci preruseni od casovace 1
   //
   Timer1=FALSE;                                            // inicializuj pocitadla
   TimerCounter=0;

   setup_timer_1(T1_EXTERNAL | T1_CLK_OUT | T1_DIV_BY_1);   // nastav TIMER1 jako 32768Hz oscilator
   set_timer1(-TIMERXTAL/IPS);                              // definuj casovy interval tak, aby bylo IPS opakovani za sekundu
   enable_interrupts(INT_TIMER1);                           // povol preruseni
   enable_interrupts(GLOBAL);                               // povol globalni preruseni


   // Inicializace obsluhy klavesnice
   //
   kbd_init();                                              // inicializuj klavesnici

knob();

   // Nacteni kalibracnich hodnod z EEPROM
   //
   EE_RD(EE_VREF, VREF);
   EE_RD(EE_K1, K1);
   EE_RD(EE_K2, K2);

   if (VREF<VREF_LOW || VREF>VREF_HIGH)
   {
      VREF = VREF_DEFAULT;
   }


   // Kontrola kontrolniho souctu EEPROM
   //
   if (Suma())                                              // spocitej kontrolni soucet EEPROM (jen kalibracni konstanty)
   {
      printf(lcd_putc,"\nERR: Bad EEPROM");                 // chyba EEPROM
      kbd_waitc();                                          // uzivatel potvrdi
      Callibrate(TRUE);                                     // spust kalibraci s priznakem vnucene kalibrace
   }


   // Mereni napajeciho napeti
   //
   {
      BOOLEAN Wait;
      float Vdd;

      TimerCounter=3*IPS;                                   // timeout 3 sekundy
      Wait=FALSE;                                           // Priznak, ze se ma cekat na klavesu

      do
      {
         Vdd=Read_Vdd();                                    // precti hodnotu
         if (Vdd>=WARNINGVOLTAGE)                           // otestuj zda je dostatecne napajeni
         {
            printf(lcd_putc,"\nVdd: %1.2fV",Read_Vdd());    // je O.K.
         }
         else
         {
            printf(lcd_putc,"\fBattery Low\nVdd: %1.2fV",Read_Vdd());   // baterie je slaba
            Wait=TRUE;                                                  // a budeme cekat na reakci uzivatele
         }
         sleep();                                           // usni
         if (!Wait && kbd_getc()) Wait=TRUE;                // pokud nebyla podminka wait a byla klavesa budeme cekat
         if (Wait && kbd_getc()) break;                     // pokud jiz cekame cekani ukoncime pri stisku klavesy
      }
      while (TimerCounter || Wait);                         // mer dokud neni zmacknuta klavesa nebo dokud nevyprsi timeout
   }



   // Hlavni smycka zpracovani
   //

#define MODE_MIN 0
#define MODE_MAX 2

   Mode=MODE_MIN;

   for (;;)
   {
      printf(lcd_putc,"\f\nMW   \20MODE\21 CFG");              // smaz displej a definuj stavovou radku
      do
      {
         float RES;
         long int HFV;
         HFV = read_hfv();
         RES = K1*HFV+K2;
         if (Mode==0) printf(lcd_putc,"\rLEVEL: %3.1f dB",RES);            // mer a zobrazuj dBV
         if (Mode==1) printf(lcd_putc,"\rLEVEL: %03.3e V",expdb(RES));     // mer a zobrazuj V
         if (Mode==2) printf(lcd_putc,"\rLEVEL: %ld RAW",HFV);             // mer a zobrazuj primo vystup prevodniku
      }
      while (!kbd_key);                                        // dokud uzivatel neco nezmackne

      i=kbd_getc();
      if (i==KBD_K1)  {};
      if (i==KBD_K2)  { if (Mode<MODE_MAX) Mode++; };
      if (i==KBD_K3)  { if (Mode>MODE_MIN) Mode--; };
      if (i==KBD_K4)  { };
   }
}

//Callibrate(FALSE);

//Spravny postup co nejkratsi smycky (vede na instrukci DECFSZ)
//
//   i=12;
//   do
//      lcd_putc(i);
//   while (--i);
//#ifdef SHRT
//#rom 0x2100={0x36, 0x97, 0x0E, 0x78, 0x78, 0x2E, 0x04, 0x85, 0xD3, 0x76, 0x35}
//#endif

// If you need to use any pin on any port use:
// *(pin_to_use/8|0x80) &= ~(1<<(pin_to_use&7)); // **
// *(pin_to_use/8) |= (1<<(pin_to_use&7));
// In all cases pin_to_use is the normal PIN_A0... defines.
{FILE END}
{FOOTER START}

Powered by WebSVN v2.8.3