Sida 1 av 1

Hjälp med summer till timer.

Postat: 23 januari 2010, 22:48:01
av MNorrgren
Hejsan

Har ett litet problem som jag trots många tankar och funderingar inte lyckas klura ut.

Har en timer, som räknar ner från inställt värde på LED-segment. ställbar mellan 1 sek upp till 60 min. Som den är just nu är det så att när man startar nedräkningen slår den via en optokopplare på en triac för att driva en lampa. Jag har samma timer tilll min UV-låda för att belysa kretskort.
Men nu vill jag göra en för att kunna ha som timer till köket när kokar pastan, student som man ju är... Jobbigt att sitta och räkna minuterna haha.

Som sagt tidigare, när man startar timern räknar den ner på segment, och samtidigt slås triacen på så lampan tänds. Dvs går en pinne på PIC'en hög. Samma med en lysdiod, den tänds också när timern startar så vet att den är igång.
Notera att jag inte kan ändra koden till PIC'en, ej kunskapen att göra det. Sen har jag inte hela koden heller, tror jag inte iaf.

Så jag tänke mig en lösning med logik eller liknanade för att göra detta.

Jag vill att när jag startar timern så ska den ju räkna ner som vanligt, men när tiden är slut ska en summer börja tuta i några sekunder. Bara så man vet att tiden är slut. Någon som har ett tips på hur jag kan göra detta??

Alltså, jag har en pinne som blir hög, 5 volt när timern startar. När tiden är slut går den ner till 0 igen. Hur gör jag lättast för att en summer ska tuta igång i ett par sekunder med hjälp av detta??

MVH
MIcke

Re: Hjälp med summer till timer.

Postat: 24 januari 2010, 12:27:23
av MNorrgren
Här är koden iaf. Någon som orkar kika igenom och kanske kan hjälpa mig att ändra den så att pinne 17 går hög i 5-10 sekunder, när tiden är slut???

Kan isf betala för jobbet eller något annat som önskas....

Använder 16f690 till detta: http://ww1.microchip.com/downloads/en/d ... 41262A.pdf

Kod: Markera allt

// -----------------------------------------------------------------------
//
// Timer - Timer switch with 1 hour lamp-on-period.
//         Designed for UV-lamp for photographic PCB exposure and darkroom
//
// Functional Specifications:
//   - rotary encoder to select the lamp-on-period
//   - button/switch to start timer function
//   - 4-digit display of lamp-on-period, counting down after start
//
// -----------------------------------------------------------------------
// Summary of changes
// 1.0.7 - Uses structure for time and special update routines.
// 1.1.0 - Time maintained in binary form (in seconds), was in stucture.
// 1.1.1 - No more use of interrupt-on-change facility.
//       - FOSC set to 1 MHz (was 4 MHz) for somewhat better handling of
//         fast rotations of rotary encoder.
//       - LED and MOC3041 now controlled by different PIC pins.
// 1.1.2 - Modified time selection algorith: more exponential.
// -----------------------------------------------------------------------
//
// Implementation notes:
//
//  - DISPLAY:
//    A 4 digit 7-segment display shows the time in mm:ss format.
//    The 7-segment displays are multiplexed: 1 digit is on at a time.
//    Multiplexing frequency 220 Hz (refresh cycle 1/55 second).
//    The multiplexing is done by the interrupt routine. At every
//    interrupt the next digit will be displayed. The segment patterns are
//    provided by the mainline.
//    When the specific PIC has a CCP module the CCP ('special event') will
//    be used, otherwise Timer1 interrupt will be used for the
//    multiplexing functionality.
//
//  - TIME:
//    Controlled via internal oscillator and Timer1.
//    The timer interrupt routine sets a 'one-second' flag. The flag is
//    reset by the mainline which provides the display patterns for the
//    display of the new time (when the timer is in 'ON'-state).
//    Time variables are stored as 4 decimal values in a structure 'mmss'
//    and maintained via special functions. This prevents binary to decimal
//    conversions.
//
//  - SWITCHES:
//    State changes of input signals are detected by a 'change-on-input'
//    interrupt. The mainline decides about the appropriate action.
//    All input pins are on PORTA and are debounced in the mainline.
//
//  - Control of the lamp-on-period:
//    Selecting the lamp-on-period is performed by a rotary encoder.
//    At very first power-on the default period is 02:30, but the last
//    actually used period will be remembered and become the new default
//    value (stored in EEPROM at the start of the lamp-on-period).
//    To reach the desired on-period quickly turning the rotary encoder
//    clockwise increases the lamp-on-period, turning it counter clockwise
//    decreases it. The amount varies with the current value, as follows:
//      00:00 - 01:00   1 second
//      01:00 - 02:00   2 seconds
//      02:00 - 05:00   5 seconds
//      05:00 - 10:00  10 seconds
//      10:00 - 20:00  20 seconds
//      20:00 - 60:00  30 seconds
//    The timer has a maximum lamp-on-period of 1 hour, time setting wraps
//    around in both directions.  When set to 00:00 the timer is inactive,
//    and the lamp will not switch off automatically, only manually.
//    When the lamp is on it is not possible to change the lamp-on-period.
//
//  - Assignments of Ports, Oscillators, Timers, and other PIC features.
//    PortA is assigned to switch and rotary encoder input, except for
//    pin 2, which controls the lamp.
//    PortB (4 pins) is dedicated to display digit selection (multiplexed).
//    PortC (8 pins) is dedicated to display segment pattern selection.
//    Internal oscillator set to 1 MHz
//    Timer0 not used
//    Timer1 used for all timer services
//    Timer2 not used (is not present in all supported chips)
//    All analog functions are disabled.
//
//  - Code optimization
//    Since the program is relatively small (<1024 code words) only one
//    code page is really used and code page switching could be disabled
//    for several functions with "#pragma update_RP". When making
//    changes: check if this optimisation is still allowed by removing
//    these pragma statements.
//
// ----------------------------------------------------------------------
//
// This program can be used for several types of PICs.
// Supported: PIC16F631,677,685,687,689,690
// Although the differences will be minimal, for each chip a separate hex
// file will be generated.
// The target PIC must be defined on the commandline with the '-p' parameter
// (see file the makefile timer.mak for compilation details).

// ID bytes:

#pragma  config  ID = PGMVERSION                // defined in make file

// EEPROM data

#pragma  cdata[0x2100]

// compiler version info

#pragma  cdata.major    =  (__CC5X__ / 1000)
#pragma  cdata.minor    = ((__CC5X__ % 1000) / 100)
#pragma  cdata.minor2   = ((__CC5X__ % 100)  / 10)
#pragma  cdata.suffix   =  (__CC5X__ % 10)

// compile date and time

#pragma  packedCdataStrings 0
#pragma  cdata.ctime    =  __DATE2__
#pragma  cdata.cdate    =  __TIME__
// #pragma  cdata.chiptype =  __CHIP__

// program data: default lamp_on_period

#pragma  cdata.lamponlow  = 150                 // 2 minutes and 30 seconds
#pragma  cdata.lamponhigh = 0                   // (high order byte)


// ----------------------------------------------------------------------

// Common config bit settings for all supported types of PICs

#pragma  config  &= ~0b11.1111.1111.1111        // all config bits OFF

#if defined(_16F631) | defined(_16F677) | defined(_16F685) | \
    defined(_16F687) | defined(_16F689) | defined(_16F690)

#pragma  config  |=  0b11.0011.1110.0100
//                                   xxx . . . . . INTOSC, RA4,5 = I/O
//                                  x  . . . . . . WDT disabled
//                                x  . . . . . . . PWRTE enabled
//                               x . . . . . . . . /MCLR = /MCLR
//                              x  . . . . . . . . no code protection
//                             x . . . . . . . . . no data protection
//                          xx . . . . . . . . . . BOR enabled
//                         x   . . . . . . . . . . IESO disabled
//                        x  . . . . . . . . . . . FCMEM disabled
//                     xx  . . . . . . . . . . . . not used

#else

  #error Program does not support the specified PIC (chip)!

#endif

// ---------------------------------------------------------------------

#include <int16cxx.h>                           // interrupt support

#define  Fosc        1000000                    // oscillator frequency

#define  MPXFREQ         220                    // 1/55 sec for all 4 digits
#if defined(_16F685) | defined(_16F690)
  #define  CCP1DELAY   (Fosc/4/MPXFREQ - 1)     // CCP1 load value
  #define  CCP1DELAYLOW  (CCP1DELAY % 256)      // low byte value
  #define  CCP1DELAYHIGH (CCP1DELAY / 256)      // high byte value
#else
  #define  TMR1DELAY   (65536 - Fosc/4/MPXFREQ + 35)  // TMR1 preload
  #define  TMR1DELAYLOW  (TMR1DELAY % 256)      // low byte value
  #define  TMR1DELAYHIGH (TMR1DELAY / 256)      // high byte value
#endif

typedef  bit        BOOL,BOOLEAN;               // boolean variable type
#define  FALSE      0
#define  TRUE       1

// digit configuration
#define  DIGIT0     0b0001.0000                 // portb.4
#define  DIGIT1     0b0010.0000                 //       5
#define  DIGIT2     0b0100.0000                 //       6
#define  DIGIT3     0b1000.0000                 //       7

// segment configuration
#define  sega       0b0010.0000                 // portc.5
#define  segb       0b0001.0000                 //       4
#define  segc       0b0000.1000                 //       3
#define  segd       0b0100.0000                 //       6
#define  sege       0b1000.0000                 //       7
#define  segf       0b0000.0001                 //       0
#define  segg       0b0000.0010                 //       1
#define  segp       0b0000.0100                 //       2

// global constants

static const uns8 ucSegmentPattern[10] = {
     /* 0 */      sega | segb | segc | segd | sege | segf       ,
     /* 1 */             segb | segc                            ,
     /* 2 */      sega | segb |        segd | sege |        segg,
     /* 3 */      sega | segb | segc | segd |               segg,
     /* 4 */             segb | segc |               segf | segg,
     /* 5 */      sega |        segc | segd |        segf | segg,
     /* 6 */      sega |        segc | segd | sege | segf | segg,
     /* 7 */      sega | segb | segc                            ,
     /* 8 */      sega | segb | segc | segd | sege | segf | segg,
     /* 9 */      sega | segb | segc | segd |        segf | segg,
                                         };

// global variables

#pragma  bit   ledcontrol   @  PORTA.1          // LED:  true=ON false=OFF
#pragma  bit   lampcontrol  @  PORTA.2          // lamp: true=ON false=OFF

static   uns8  systemstate;                     // 1 second tick flag
enum _syssts {STOPPED, STARTING, RUNNING, STOPPING};

static   bit   tick;                            // 1 second tick flag
static   uns8  intervalsec;                     // counter for 1 sec ticks

static   uns16 lamp_on_period;                  // desired lamp-on-period
static   uns16 time_remaining;                  // remaining lamp-on-time

static   uns8  digitcurrentnumber;              // currently displayed digit
static   uns8  digitsecondspattern;             // segment pattern seconds
static   uns8  digittensecondspattern;          //    "       "   ten-seconds
static   uns8  digitminutespattern;             //    "       "   minutes
static   uns8  digittenminutespattern;          //    "       "   ten-minutes


// local function prototypes

static   void  build_patterns(void);            // build 7-segment patterns
static   void  EEPROMReadTime(void);            // read time from data EEPROM
static   void  EEPROMWriteTime(void);           // write time to data EEPROM
static   void  setupPIC(void);                  // PIC init
static   void  time_decrement(void);            // decrement lamp-on-period
static   void  time_increment(void);            // increment lamp-on-period


// ---------------------------------------------------------------
//  Interrupt service routine
//
//  Interrupt for general time management (either CCP1 or TMR1)
//  - first in the interrupt handler (when using Timer1 for accuracy)
//  - performs multiplexing of 7-segment displays
//  - sets 1 second interval flag for handling by mainline
//
//  Interrupt on change of input PortA
//  - only PortA used for input
//  - saves current status of PortA for handling by mainline
//
// Note: When a CCP module is available (16F685,16F690), the special event
//       interrupt feature is used. This provides a somewhat higher
//       accuracy in keeping time than when using a Timer1 interrupt,
//       which is used otherwise.
// ------------------------------------------------------------------

#pragma origin 4

interrupt isr(void) {

  int_save_registers

#pragma update_RP 0

#if defined(_16F685) | defined(_16F690)         // chips with CCP module

  if (CCP1IF) {                                 // CCP1 interrupt

#else                                           // chips without CCP module

  if (T1IF) {                                   // TMR1 interrupt
    TMR1L += TMR1DELAYLOW;                      // )
    TMR1H += Carry;                             // ) reload Timer1
    TMR1H += TMR1DELAYHIGH;                     // )

#endif

    if ((++intervalsec) > MPXFREQ) {            // 1 second period
      tick = TRUE;                              // set flag (reset by mainline)
      intervalsec = 0;                          // restart counting
      }

    digitcurrentnumber = (++digitcurrentnumber) & 3;  // next digit / wrap

    // Note: a switch()/case construct takes more cycles then if / else if

    PORTB = 0b0000.0000;                        // previous digit off
    if (0 == digitcurrentnumber) {
      PORTC = digitsecondspattern;              // second digit
      PORTB = DIGIT0;                           // show digit 0
      }
    else if (1 == digitcurrentnumber) {
      PORTC = digittensecondspattern;           // 10 second digit
      PORTB = DIGIT1;                           // show digit 1
      }
    else if (2 == digitcurrentnumber) {
      PORTC = digitminutespattern;              // minute digit
      PORTB = DIGIT2;                           // show digit 2
      }
    else {                                      // otherwise (digit 3!)
      PORTC = digittenminutespattern;           // 10 minute digit
      PORTB = DIGIT3;                           // show digit 3
      }

#if defined(_16F685) | defined(_16F690)

    CCP1IF = FALSE;                             // reset interrupt flag

#else

    T1IF = FALSE;                               // reset interrupt flag

#endif

    }

#pragma update_RP 1

  int_restore_registers

  }                                             // end of interrupt service


// --------------------------------------------------------------------
// Library functions to be included AFTER the interrupt service routine
// --------------------------------------------------------------------

#include <math16.h>                             // math support

// -------------------------------------------------------
//  Perform all required basic PIC setup
// -------------------------------------------------------
static void setupPIC(void) {

#pragma updateBank exit = 0

  PORTA   = 0b0000.0000;                        // reset port
  PORTB   = 0b0000.0000;                        //   "    "
  PORTC   = 0b0000.0000;                        //   "    "

  TMR1L   = 0;                                  // )
  TMR1H   = 0;                                  // ) reset Timer1
  T1CON   = 0b0000.0001;                        // Timer 1 on, internal src
  ANSEL   = 0b0000.0000;                        // ) all analog off
  CM1CON0 = 0b0000.0000;                        // Comparator 1 disabled
  CM2CON0 = 0b0000.0000;                        // Comparator 2 disabled

#if defined(_16F631)
  PIE1   = 0b0000.0001;                         // TMR1 interrupts enabled
#elif defined(_16F677)
  ANSELH  = 0b0000.0000;                        // )
  ADCON0  = 0b0000.0000;                        // disable ADC
  PIE1   = 0b0000.0001;                         // TMR1 interrupts enabled
#elif defined(_16F685)
  ANSELH  = 0b0000.0000;                        // )
  ADCON0  = 0b0000.0000;                        // disable ADC
  CCP1CON = 0b0000.1011;                        // Cmp mode, trig. spec. event
  CCPR1L  = CCP1DELAYLOW;                       // )
  CCPR1H  = CCP1DELAYHIGH;                      // ) Timer1 cycle
  T2CON   = 0b0000.0000;                        // Timer 2 off
  PIE1    = 0b0000.0100;                        // CCP1 interrupts enabled
#elif defined(_16F687)
  ANSELH  = 0b0000.0000;                        // )
  ADCON0  = 0b0000.0000;                        // disable ADC
  PIE1   = 0b0000.0001;                         // TMR1 interrupts enabled
#elif defined(_16F689)
  ANSELH  = 0b0000.0000;                        // )
  ADCON0  = 0b0000.0000;                        // disable ADC
  PIE1   = 0b0000.0001;                         // TMR1 interrupts enabled
#elif defined(_16F690)
  ANSELH  = 0b0000.0000;                        // )
  ADCON0  = 0b0000.0000;                        // disable ADC
  CCP1CON = 0b0000.1011;                        // Cmp mode, trig. spec. event
  CCPR1L  = CCP1DELAYLOW;                       // )
  CCPR1H  = CCP1DELAYHIGH;                      // ) Timer1 cycle
  T2CON   = 0b0000.0000;                        // Timer 2 off
  PIE1    = 0b0000.0100;                        // CCP1 interrupts enabled
#endif

  OSCCON = 0b0100.0000;                         // 1 MHz, SCS see
                                                // ..  config bits)
  TRISA  = 0b0011.1001;                         // in: rotary, start-switch
                                                // out: lamp/led ctl
  TRISB  = 0b0000.0000;                         // 7-segment digit control
  TRISC  = 0b0000.0000;                         // 7-segment segment control

  OPTION = 0b1000.0111;                         //
//                 *** . . . . . . . . . . . .   prescaler TMR0 1:256
//                *  . . . . . . . . . . . . .   prescaler assigned to TMR0
//              *  . . . . . . . . . . . . . .   (irrelevant: not counter)
//             * . . . . . . . . . . . . . . .   TMR0 clock source Fosc/4
//            *  . . . . . . . . . . . . . . .   (irrelevant: no INT)
//           * . . . . . . . . . . . . . . . .   RABPU - pullups disabled (1)

  INTCON = 0b1100.0000;
//           * . . . . . . . . . . . . . . . .   GEI general
//            *  . . . . . . . . . . . . . . .   PEIE - external
  }


// -------------------------------------------------------
// Read lamp_on_period from EEPROM data memory
// -------------------------------------------------------
static  void  EEPROMReadTime(void) {

#pragma updateBank exit = 0

  EEADR  = (uns8)lamponlow;                     // position in EEPROM
  EECON1 = 0b0000.0001;                         // read data EEPROM
  lamp_on_period.low8 = EEDATA;                 // copy to lamp_on_period
  EEADR  = (uns8)lamponhigh;                    // next position in EEPROM
  EECON1 = 0b0000.0001;                         // read data EEPROM
  lamp_on_period.high8 = EEDATA;                // copy to lamp_on_period
  return;                                       // back to caller
  }


// -------------------------------------------------------
// Write lamp_on_period to EEPROM data memory
// -------------------------------------------------------
static  void  EEPROMWriteTime(void) {

#pragma updateBank exit = 0

  EEADR  = (uns8)lamponlow;                     // offset in EEPROM memory
  EEDATA = lamp_on_period.low8;                 // new contents
  EECON1 = 0b0000.0100;                         // data mem, write enable
  GIE    = FALSE;                               // disable interrupts
  while (GIE == TRUE)                           // ) check
    ;                                           // )
  EECON2 = 0x55;                                // prescribed..
  EECON2 = 0xAA;                                // ..instruction..
  WR     = TRUE;                                // ....cycles
  WREN   = FALSE;                               // no more writes
  while (WR == TRUE)                            // loop until..
    ;                                           // ..write completed
  GIE    = TRUE;

  EEADR  = (uns8)lamponhigh;                    // offset in EEPROM memory
  EEDATA = lamp_on_period.high8;                // new contents
  EECON1 = 0b0000.0100;                         // data mem, write enable
  GIE    = FALSE;                               // disable interrupts
  while (GIE == TRUE)                           // ) check
    ;                                           // )
  EECON2 = 0x55;                                // prescribed..
  EECON2 = 0xAA;                                // ..instruction..
  WR     = TRUE;                                // ....cycles
  WREN   = FALSE;                               // no more writes
  while (WR == TRUE)                            // loop until..
    ;                                           // ..write completed
  GIE    = TRUE;                                // re-enable interrupts
  }


// -----------------------------------------------------------------
// Time increment function (add a number of seconds)
// NB: Only used for lamp-on-period selection
// -----------------------------------------------------------------
static  void  time_increment(void) {

#pragma update_RP 0

  if (lamp_on_period >= 1200) {                 // 20:00 - 59:59
    lamp_on_period += 30;                       // step up 30 seconds
    if (lamp_on_period > 3600)                  // check hour overflow
      lamp_on_period = 0;                       // wrap to 00:00
    }
  else if (lamp_on_period >= 600)               // 10:00 - 19:59
    lamp_on_period += 20;                       // step up 20 seconds
  else if (lamp_on_period >= 300)               // 05:00 - 09:59
    lamp_on_period += 10;                       // step up 10 seconds
  else if (lamp_on_period >= 120)               // 02:00 - 04:59
    lamp_on_period += 5;                        // step up 5 seconds
  else if (lamp_on_period >= 60)                // 01:00 - 01:59
    lamp_on_period += 2;                        // step up 2 seconds
  else                                          // 00:00 - 01:59
    ++lamp_on_period;                           // step up 1 second

#pragma update_RP 1

  }                                             // return to caller


// -----------------------------------------------------------------
// time decrement function (substract 1 second)
//  - parm is pointer to MMSS structure
// -----------------------------------------------------------------
static  void  time_decrement(void) {

#pragma update_RP 0

  if (lamp_on_period > 1200)                    // 20:00 - 59:59
    lamp_on_period -= 30;                       // step down 30 seconds
  else if (lamp_on_period > 600)                // 10:00 - 19:59
    lamp_on_period -= 20;                       // step down 20 seconds
  else if (lamp_on_period > 300)                // 05:00 - 09:59
    lamp_on_period -= 10;                       // step down 10 seconds
  else if (lamp_on_period > 120)                // 02:00 - 04:59
    lamp_on_period -= 5;                        // step down 5 seconds
  else if (lamp_on_period > 60)                 // 01:00 - 01:59
    lamp_on_period -= 2;                        // step down 2 seconds
  else {                                        // 00:00 - 00:59
    if (lamp_on_period > 0)                     // still positive
      --lamp_on_period;                         // step down 1 second
    else                                        // currently zero
      lamp_on_period = 3600;                    // wrap to 60:00
    }

#pragma update_RP 1

  }


// -----------------------------------------------------------------
// build 7-segment patterns for display of remaining time
// -----------------------------------------------------------------
static  void  build_patterns(void) {

#pragma update_RP 0

  uns16 time_calc;                              // bin to dec conversion
  uns8  index;                                  // dec to 7-segment

  time_calc = time_remaining;                   // copy
  index = time_calc % 10;
  digitsecondspattern = ucSegmentPattern[index];
  time_calc /= 10;
  index = time_calc % 6;
  digittensecondspattern = ucSegmentPattern[index];
  time_calc /= 6;
  index = time_calc % 10;
  digitminutespattern = ucSegmentPattern[index];
  time_calc /= 10;
  index = time_calc;
  digittenminutespattern = ucSegmentPattern[index];

  digitminutespattern |= segp;                  // minutes/seconds separator

#pragma update_RP 1

  }


// ====================================================================
//     M A I N L I N E
//
// - initial setup
// - for all rotary switches continously
//   - check input signals
//   - debounce inputs (done with 2-bits vertical counter)
//   - when debounce state changed construct new
//      bit pattern for output port
//
//----------------------------------------------------------------
// Rotary encoder function:
//
// Output behaviour when turning clockwise:
//
//  A:     ---------             closed
//      ---         --------     open
//                                          (Gray code 00 01 11 10 00)
//  B:        ---------          closed
//      ------         -----     open
//
// Output behaviour when turning counter clockwise:
//
//  A:        ---------          closed
//      ------         -----     open
//                                          (Gray code 00 10 11 01 00)
//  B:     ---------             closed
//      ---         --------     open
//
// Direction of rotation table: 0 - nochange or error
//                              1 - clockwise
//                              2 - counter clockwise

  static  const  uns8 dirtab[16] = {0,1,2,0, 2,0,0,1, 1,0,0,2, 0,2,1,0};

// Mechanical switches, incl rotary encoders may suffer of contact
// bouncing,therefore a debouncing algorithm is applied, with vertical
// counters (method Scott Dattalo).
// There is no explicit delay between two 'forever' cycles, so debouncing
// is done at short intervals. This allows quick turning of the rotary
// encoder, but may also cause (insignificant) glitches.
//
// ======================================================================
void main(void) {

#pragma update_RP 0

  uns8  CountA, CountB;                         // counters for debouncing
  uns8  inputstate;                             // PORTA status
  uns8  debouncedstate;                         // debounced input state
  uns8  previousstate;                          // previous debounced state
  uns8  delta;                                  // changed debounced state
  uns8  dirindex;                               // ) determination of ..
  uns8  rotation;                               // ) .. direction of rotation

  setupPIC();                                   // perform basic PIC setup

  intervalsec = 0;                              // init tick counter
  lampcontrol = FALSE;                          // lamp switched off
  ledcontrol = FALSE;                           // LED switched off
  systemstate = STOPPING;                       // init finite state machine

  EEPROMReadTime();                             // read default
  time_remaining = lamp_on_period;              // show lamp_on_period
  build_patterns();                             // initial time pattern

  CountA         = 0b0000.0000;                 // init A-bit counter
  CountB         = 0b0000.0000;                 // init B-bit counter
  debouncedstate = 0b0000.0000;                 // init debounced state
  previousstate  = 0b0000.0000;                 // init previous state

  for (;;) {                                    // forever

    // --- time management and display ---
    if (STOPPED == systemstate) {               // quiesced
      if (time_remaining != lamp_on_period) {   // reset required
        time_remaining = lamp_on_period;        // show lamp_on_period
        build_patterns();                       // new time pattern
        }
      }

    else {                                      // starting, running, stopping
      if (tick) {                               // another second
        tick = FALSE;                           // handled, reset flag
        if (RUNNING == systemstate) {           // counting down
          if (lamp_on_period) {                 // not zero (continuous)
            --time_remaining;                   // count down
            build_patterns();                   // new time pattern
            if (time_remaining <= 0) {          // end of lamp_on_period
              lampcontrol = FALSE;              // lamp switched off
              ledcontrol = FALSE;               // LED switched off
              systemstate = STOPPING;           // being stopped
              }
            }
          }
        else if (STARTING == systemstate)       //
          systemstate = RUNNING;
        else if (STOPPING == systemstate)       //
          systemstate = STOPPED;
        }
      }


    // --- debouncing all input signals, on PORTA ---

    CountA ^= CountB;                           // update vertical ..
    CountB  = ~CountB;                          // .. debounce counters
    inputstate = PORTA;                         // read Port A
    delta = inputstate ^ debouncedstate;        // determine changes
    CountA &= delta;                            // reset counters ..
    CountB &= delta;                            // .. when no changes
    debouncedstate &= (CountA | CountB);        // set and reset new bits
    debouncedstate |= (~(CountA | CountB) & inputstate);     // rewrite
                                                // already filtered bits

    if (debouncedstate ^ previousstate) {       // any of the input signals
                                                // changed (after debounce)
      // --- handle rotary encoder on PORTA.4/5

      if (STOPPED == systemstate) {             // handle only when lamp off
        if ((debouncedstate & 0b0011.0000) == 0b0011.0000) {  // 1 of 4 states
          dirindex   = (previousstate >> 2);    // prev bits 5,4 -> 3,2
          dirindex  &= 0b0000.1100;             // keep only bits 3,2
          dirindex  |= ((debouncedstate >> 4) & 0b0000.0011);  // add cur bits
          rotation   = dirtab[dirindex];        // obtain dir. of rotation
          if (1 == rotation)                    // clock wise
            time_increment();                   // increment lamp_on_time
          else if (2 == rotation)               // counter clock wise
            time_decrement();                   // decrement lamp_on_period
          if (rotation) {                       // CW or CCW
            time_remaining = lamp_on_period;    // copy for pattern building
            build_patterns();                   // new time pattern
            }
          }
        }


      // --- handle start button on PORTA.0

      if ((debouncedstate ^ previousstate)  & 0b0000.0001)  { // state change
        if (debouncedstate & 0b0000.0001) {     // start button pushed
          if (STOPPED == systemstate) {
            systemstate = STARTING;
            lampcontrol = TRUE;                 // lamp switched on
            ledcontrol = TRUE;                  // LED switched on
            intervalsec = 0;                    // ) re-init tick ..
            tick = FALSE;                       // ) .. timer
            }
          else if (RUNNING == systemstate) {
            systemstate = STOPPING;
            lampcontrol = FALSE;                // lamp switched off
            ledcontrol = FALSE;                 // LED switched off
            intervalsec = 0;                    // ) re-init tick ..
            tick = FALSE;                       // ) .. timer
            }
          }
        else {                                  // start switched OFF
          if (STARTING == systemstate) {        // was switched on
            systemstate = RUNNING;
            EEPROMWriteTime();                  // new default
            }
          }
        }

      previousstate = debouncedstate;           // new previous state!

      }

    }

#pragma update_RP 1

  }

Re: Hjälp med summer till timer.

Postat: 24 januari 2010, 12:52:48
av grym
det går väldigt enkelt att ta en 4093 och koppla den som att den ger en signal några sekunder efter att man nollar en ingång

Re: Hjälp med summer till timer.

Postat: 24 januari 2010, 15:23:19
av MNorrgren
Hmm, har totalt hjärnsläpp för tillfället. Du har inte ork att berätta hur du tänkte en koppling där??

Re: Hjälp med summer till timer.

Postat: 24 januari 2010, 17:07:14
av prototypen
Bild

Protte

Re: Hjälp med summer till timer.

Postat: 24 januari 2010, 18:24:41
av MNorrgren
Underbart... Jag tackar och bugar så mycket. När tittar på det ser det ju ganska logiskt ut men det stod helt stilla innan!

Uppskattar verkligen er hjälp!!!

Nu ska det kopplas upp på kopplingsplatta och se om det funkar i praktiken också!