roboforum.ru

Технический форум по робототехнике.

Помогите перевести программу!

Помогите перевести программу!

Карлсон » 23 июл 2006, 04:04

Есть программа под пик - 12c508A или 12c509A.

все три купленных контроллера оказались уже прошитыми. они просто издеваются.
тратить еще деньги на пики - нету возможности.
но есть 2313.
часть программы переписал, но вот подсчет импульсов я не понимаю.
если кому не сложно, то как преобразовать функцию void CountPulses(BYTE byMeasurementTime) для 2313?

вот исходный код:

Код: Выделить всёРазвернуть
/**************************************************************************\
FILE ..........: BEEPER.C
AUTHOR ........: Vitaly Puzrin
DESCRIPTION ...: Alarm buzzer (lost aircraft locator) firmware
NOTES .........: For non commercial use only.
COPYRIGHT .....: Vitaly Puzrin, 2000
HISTORY .......: DATE        COMMENT                    
                 ---------------------------------------------------
                 11.05.2000  First version.
\**************************************************************************/

#include "12c508.h"

#define BYTE    unsigned char
#define WORD    unsigned long       // !! 16 bit in this C compiler

#define clear_cfg       &= 0, |= 0x03E0
#define MCLR_OFF        &= ~0x10
#define CP_OFF          |= 0x08
#define WDT_OFF         &= ~0x4
#define OSC_INTERNAL    |= 0x02

#pragma    config clear_cfg, MCLR_OFF, CP_OFF,  WDT_OFF, OSC_INTERNAL

#define TIMER_OVERFLOW  26    // Defines system timer rateя - 150 Hz (6ms)
#define PULSE_ONE_MAX   3
#define PULSE_ZERO_MAX  6

#define CYCLE   16      // Measuring cycle length (in 1mHz ticks)
#define PULSE_MIN       (700/CYCLE)     // Min. default possible pulse len.
#define PULSE_MAX       (2200/CYCLE)    // Max. default possible pulse len.
#define ALARM_PERIOD    90  // Sound alsrm pause (used to measure pulses)
#define BAD_PULSE_MAX   4   // Max bad pulses count duging alarm pause
                           // (if more, then alarm turns on)
#define GOOD_PULSE_MIN  15  // Min good pulses count duging alarm pause
                           // (if less, then alarm turns on)
#define CLBR_TIME    30
#define CLBR_BAD_PULSE_MAX  8
#define CLBR_GOOD_PULSE_MIN  1

#define INPUT   GP0       // Control pulses input
#define OUT1    GP4       // Buzzer output 1
#define OUT2    GP5       // Buzzer output 2 (inverted, to get more power)

BYTE BadPulseCnt;   // "bad pulses" counter
BYTE GoodPulseCnt;  // "good pulses" counter

// Control pulse bounds are stored here
BYTE byPulseMin;    // min. pulse bound
BYTE byPulseMax;    // max. pulse bound

#define FILTER_LEN  8   // Filter len
#define FILTER_EXP  3   // Fliter len exp. (for fast division)

BYTE byFilter[FILTER_LEN];  // Filter data aray
BYTE byFilterPtr;
WORD wFilterSum;            // Filter data sum
BYTE byFilterOut;           // Filter output (sum? divided by 8)

BYTE byTmp;

#define ALARM_ZONE  3

/**************************************************************************\
   Tone generation
     Entry: byPer - wave period, byPerCnt - wave count
     Exit:  -
\**************************************************************************/
void Sound(BYTE byPer, BYTE wPerCnt )
{
   for( ; wPerCnt; wPerCnt-- )
   {
       byTmp = byPer;
       do { nop(); nop(); byTmp--; } while( byTmp!=0 );

       OUT1 = 1;
       OUT2 = 0;

       byTmp = byPer;
       do { nop(); nop(); byTmp--; } while( byTmp!=0 );

       OUT1 = 0;
       OUT2 = 1;
   }
}

/**************************************************************************\
   Siren sound
     Entry:  -
     Exit:   -
\**************************************************************************/
void AlarmSound(void)
{
   BYTE i;

   for( i=80; i>20; i--)
       Sound( i, 15 );

   for( i=20; i<80; i++)
       Sound( i, 15 );

   for( i=80; i>20; i--)
       Sound( i, 15 );

   for( i=20; i<80; i++)
       Sound( i, 15 );
}

/**************************************************************************\
   Filter reset
     Entry: -
     Exit:  -
\**************************************************************************/
void filter_init(void)
{
   // Zero filter contents
   for(byTmp=0; byTmp<FILTER_LEN; byTmp++)
       byFilter[byTmp] = 0;

   // Zero all internal variables
   byFilterPtr = 0;
   wFilterSum = 0;
   byFilterOut = 0;
}

/**************************************************************************\
   Putting new data to filter
     Entry: byNewData - new data to put into filter
     Exit:  buFilterOut - filter output
\**************************************************************************/
void ProcessFilter(BYTE byNewData)
{
   wFilterSum -= byFilter[byFilterPtr];// Take off old data
   byFilter[byFilterPtr] = byNewData;  // Take in new data
   wFilterSum += byNewData;  

   if ((++byFilterPtr) == FILTER_LEN)
       byFilterPtr = 0;

   // Let's calculate filter output
   // We round result
//    byFilterOut = (wFilterSum + (FILTER_LEN >> 1)) >> FILTER_EXP;
   byFilterOut = wFilterSum >> FILTER_EXP;
//    wTmp = wFilterSum + (FILTER_LEN >> 1);
//    byFilterOut = wTmp >> FILTER_EXP;
}

/**************************************************************************\
   Pulses measuring. Counting "good" and "bad" pulses
     Entry: byMeasurementTime - measurement time.
     Выход: -
\**************************************************************************/
void CountPulses(BYTE byMeasurementTime)
{
   BYTE PulseCnt;  // Pulse length counter.
#define OvfCnt  byTmp
//    BYTE OvfCnt;    // Timer overflow counter. Used for rude count of
                   // "ones" & "zeroes" in control pulses

   BadPulseCnt = 0;
   GoodPulseCnt = 0;
   TMR0 = 0;

   for(;;)
   {
       //-------------------------------------
       // Wait riseing front (pulse start)
       OvfCnt = 0;
       while(!INPUT)
       {
           // Generate system time pulses (150 Hz)
           if (TMR0 >= TIMER_OVERFLOW) {
               byMeasurementTime--;
               OvfCnt++;
               TMR0 = 0;
           }
           
           if (OvfCnt > PULSE_ZERO_MAX)
           {
               BadPulseCnt++;
               OvfCnt = 0;
           }
           
           if (!byMeasurementTime)
               return;
       }

       PulseCnt = 0;
       //-------------------------------------
       // Measure pulse length. We wait falling front,
       // but no longer, than 2500us
       while(INPUT)
       {
           // Generate system time pulses (150 Hz)
           if (TMR0 >= TIMER_OVERFLOW) {
               byMeasurementTime--;
               TMR0 = 0;
           }
           else {
               nop();    // That's requied to make
               nop();    // both "if" branches equal.
               nop();
           }
       
           PulseCnt++;
       
           // ifPulse is too long, then finish measureing
           // with error.
           if (PulseCnt > byPulseMax)
           {
               PulseCnt = 0;
               break;
           }
       }

       //-------------------------------------
       // Determin if pulse is "good" or "bad"
       // and increment appropriate counter.
       if ((PulseCnt < byPulseMin) || (PulseCnt > byPulseMax))
           BadPulseCnt++;
       else
           GoodPulseCnt++;

       ProcessFilter(PulseCnt);
           
       // Wait intil pulse is low
       // (if measurement was terminated with error).
       OvfCnt = 0;
       while(INPUT)
       {
           // Generate system time pulses (150 Hz)
           if (TMR0 >= TIMER_OVERFLOW) {
               byMeasurementTime--;
               OvfCnt = 0;
               TMR0 = 0;
           }
           
           if (OvfCnt > PULSE_ONE_MAX)
           {
               BadPulseCnt++;
               OvfCnt = 0;
           }

           if (!byMeasurementTime)
               return;
       }
   }
}

/**************************************************************************\
   Program entry point.
\**************************************************************************/
void main(void)
{
//#define i   byPrevPulse     // Dirty trick, we save one RAM byte here
   BYTE i;
   BYTE byPrevPulse = 0;

   OPTION = 0x07;
   TRIS = 0x0B;
   GPIO = 0;
   
   byPulseMin = PULSE_MIN;
   byPulseMax = PULSE_MAX;
   filter_init();

   for(i=0; i<5; i++)
       Sound( 40, 100 );   // Tell us, that power is on.

   // Silent zone calibration
   // !!! Throttle stick must be at minimum
   // At first, calculate current stick pulse
   i = 0;
   for(;;)
   {
       CountPulses(CLBR_TIME);
       if (byPrevPulse > byFilterOut)
           byTmp = byPrevPulse - byFilterOut;
       else
           byTmp = byFilterOut - byPrevPulse;
       
       if (byTmp > 1)
       {
           if ((byFilterOut <= byPulseMax) &&
               (byFilterOut >= byPulseMin) &&
               (BadPulseCnt <= CLBR_BAD_PULSE_MAX) &&
               (GoodPulseCnt >= CLBR_GOOD_PULSE_MIN))
           {
               if (++i > 10)
                   break;
           }
           else
           {
               i = 0;
               byPrevPulse = 0;
           }
       }
       else
       {
           i = 0;
           byPrevPulse = byFilterOut;
       }
   }

   // Tell us, that calibration passed
   for(i=0; i<5; i++)
       Sound( 40, 100 );  
   for(i=0; i<5; i++)
       Sound( 60, 66 );
   for(i=0; i<5; i++)
       Sound( 40, 100 );
   
   // We assume, that stick is at minimum, so we
   // can say if channel is inverted or not.
   // We set pulse bounds in such way, that sirene
   // will sound only at minimum throttle.
   if (byFilterOut > (1500/CYCLE))
       byPulseMax = byFilterOut - ALARM_ZONE;
   else
       byPulseMin = byFilterOut + ALARM_ZONE;


   // Wait 30 seconds before arming pulses guard.
   TMR0 = 0;
   for(i=30; i>0; i--)
   {
       // Delay for 1 second
       for(byPrevPulse=15; byPrevPulse>0; byPrevPulse--)
       {
           while(TMR0 != 0xFF);    // That's for 0.065 sec (15 Hz)
           TMR0++;
       }
   }
   
   // Infinit loop. Check pulses and turn sirene on
   // if signal is bad
   for(;;)
   {
       CountPulses(ALARM_PERIOD);
       if ((GoodPulseCnt < GOOD_PULSE_MIN) ||
           (BadPulseCnt > BAD_PULSE_MAX))
           AlarmSound();
   }
}


буду очень признателен за любую помощь!

Re: Помогите перевести программу!

avr123.nm.ru » 23 июл 2006, 11:03

Карлсон писал(а):Есть программа под пик - 12c508A или 12c509A.
все три купленных контроллера оказались уже прошитыми.


они программируятся один раз.

их заменили флэшовые pic12F675 например.

Карлсон писал(а): но есть 2313.


имхо - тоже г.

Re: Помогите перевести программу!

Карлсон » 23 июл 2006, 12:49

avr123.nm.ru писал(а):
Карлсон писал(а):Есть программа под пик - 12c508A или 12c509A.
все три купленных контроллера оказались уже прошитыми.


они программируятся один раз.

их заменили флэшовые pic12F675 например.

Карлсон писал(а): но есть 2313.


имхо - тоже г.


я прекрасно понимаю, что они один раз программируются.
но автор этой прошивки нигде не упоминает, что ее можно запихнуть в F версию. есть еще одна прошивка - там только хекс файл. вот его я и пытался зашить.

а 2313 - это ж at90s2313. и чего вам в нем не нравится?
но речь не об этом.
лучше объясните толково, что именно и как делает калькулейт и как управляется с пиковским таймером. пожалуйста.

avr123.nm.ru » 23 июл 2006, 14:24

по моему там нужно просто заменить названия регистров на AVR-овские.

ну и комментарии лучше на русском написать.

Карлсон » 23 июл 2006, 15:19

ну попробуйте! :)
у меня не получилось.

вот кстати схема:
Изображение

эта штука должна работать,если на вход поступают прямоугольные импульсы с размахом 5 вольт и частотой 500 Гц.
Вложения
buzzer_sch.gif
buzzer_sch.gif (7.97 КиБ) Просмотров: 2067

avr123.nm.ru » 23 июл 2006, 19:59

Карлсон писал(а):ну попробуйте! :)
эта штука должна работать,если на вход поступают прямоугольные импульсы с размахом 5 вольт и частотой 500 Гц.


прекрасный случай написать свою программу - задайте диапазоны входных величин и временные рамки детектирования.

программу советую писать в CVAVR с помощью генератора кода а отлаживайть в VMLAB.


cron
Rambler\'s Top100 Mail.ru counter