⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 05070.c

📁 被动红外传感器开关
💻 C
📖 第 1 页 / 共 2 页
字号:
//RS-150-BA firmware
//v0.7
//12-4-06

//Variables
union un_var
{
  unsigned char uc_var;  // The variable as 1 byte
  struct
  {  // The variable as 8 bits
    unsigned char Bit0:1,
                  Bit1:1,
                  Bit2:1,
                  Bit3:1,
                  Bit4:1,
                  Bit5:1,
                  Bit6:1,
                  Bit7:1;
  } bf_var;
} ucStatus = {0};

//ucStatus bit field definition
#define BitStatus0          Bit0
#define BitStatus1          Bit1
#define MAJORBUTTONHELD     Bit2
#define SPACEOCCUPIED       Bit3
#define OCCUPIED            Bit4
#define LINEFREQ            Bit5
#define RELAYBUFFER         Bit6

#define STATUS_MASK       0x03
#define STATUS_MANUALOFF  0x00
#define STATUS_AUTOOFF    0x01
#define STATUS_LOADON     0x02
#define STATUS_ONIFDARK   0x03

//
#define TIME_TESTMODE_DURATION    3000  //300s
#define TIME_RESET_TO_AUTO        3000  //300s
#define TIME_RESET_TO_MANUAL      300   //30s
#define TIME_LED_FLASH_DURATION   10    //1s
#define TIME_LED_ON_DURATION      2     //0.2s
#define TIME_TESTMODE_DELAY       50    //5s
#define TIME_DELAY_MODE_U         3000  //5m
#define TIME_DELAY_MODE_BA        18000 //30m
#define TIME_WARMUP               250   //25s
#define TIME_IGNORE               15    //1.5s

unsigned char ucTimerUnit = 0;        //give 5 or 6 based on mains freq 50Hz or 60Hz.
unsigned char ucTimerBase = 0;        //system base timer, 0.1s per cycle
unsigned char ucTimerSystem = 0;      //system timer, 1s per cycle
unsigned char ucTimerIgnore = 0;
unsigned int  uiTimerWarmup = TIME_WARMUP;
unsigned int  uiTimerTestMode = 0;
unsigned int  uiTimerDelay = 0;
unsigned int  uiTimerAfterDelay = 0;
unsigned char ucTimerDark = 0;

//PIR
#define NOISE_OFFSET 8
#define MIN_THRESH 46
#define MAX_THRESH 71
#define HOLD_THRESH 87
#define MIN_WIDTH 2
#define MID_WIDTH 20
#define MAX_WIDTH 120
#define MIN_SPACE 9
#define PIR_CENTER 102
#define MAX_PIR (PIR_CENTER*2)
#define DEFAULT_NOISE (MIN_THRESH - NOISE_OFFSET)

//
#define MSG_BUTTON_NONE                         0x00
#define MSG_MAJOR_BUTTON_SHORT_HOLD             0x01  //Major button get hold for longer than 0.1s
#define MSG_MAJOR_BUTTON_LONG_HOLD              0x02  //Major button get hold for longer than 0.5s
#define MSG_MAJOR_BUTTON_SHORT_PRESSED          0x03  //Major button get pressed for shorter than 10s
#define MSG_MAJOR_BUTTON_INOUTTESTMODE_HOLD     0x04  //Major button get hold for longer than 10s
#define MSG_MAJOR_BUTTON_INOUTTESTMODE_PRESSED  0x05  //Major button get pressed for longer than 10s

#define BUTTON_ON   0
#define BUTTON_OFF  1
#define BUTTON_DEBOUNCING_TIME  1   //0.1s
#define BUTTON_HOLD_TIME        5   //0.5s
#define BUTTON_INOUTTESTMODE_TIME    100 //10s
unsigned char ucMsgButton = MSG_BUTTON_NONE;

//IO
#define INPUT_MAJOR_BUTTON    PIND_Bit5
#define INPUT_LINE            PIND_Bit6
#define INPUT_LOAD            PIND_Bit7
#define OUTPUT_LED_CONTROL    PORTD_Bit3
#define OUTPUT_RELAY_CONTROL  PORTD_Bit1
#define PORT_INIT             0x00
#define DDRB_INIT             0xff
#define DDRC_INIT             0xfc
#define DDRD_INIT             0x1f

//ADC converter setup
#define ADMUX_LIGHTLEVEL      0x60
#define ADMUX_OCCUPATION      0x61
#define ADCSRA_INIT           0x93
#define ADCSRA_START          0xd3
#define ADCSRA_OFF            0x13
#define DIDR0_INIT            0x3f

//TMR1 for Timing
#define TCCR1B_OFF            0x00
#define TCCR1B_INIT           0x03

//
unsigned int uiLEDFlashPattern = 0x0000;

#define LED_FLASH_PAT_NONE    0x0000  //0000000000000000
#define LED_FLASH_PAT_ERR1    0x8080  //1000000010000000
#define LED_FLASH_PAT_ERR2    0xa0a0  //1010000010100000
#define LED_FLASH_PAT_ERR3    0xa8a8  //1010100010101000
#define LED_FLASH_PAT_SUCC    0xaaaa  //1010101010101010

//TMR2 for LED control
#define TCCR2B_INIT           0x01
#define TCCR2A_OFF            0x03
#define TCCR2A_ON             0x23
#define OCR2B_DIM             0x3a
#define OCR2B_ON              0xff

#define LIGHT_LEVEL_THRESHHOLD  172

#define MODE_U    0
#define MODE_BA   1

unsigned char ucMode = MODE_BA;

unsigned int uiDelayData[2] = {TIME_DELAY_MODE_U, TIME_DELAY_MODE_BA};

#define CLKPR_INIT  0x02

unsigned int uiFullCycle = 0;

#define FULL_CYC_50   625
#define FULL_CYC_M    573
#define FULL_CYC_60   521
#define HALF_CYC_60   260
#define QUART_CYC_60  130
#define DFT_ON_DELAY  QUART_CYC_60
#define DFT_OFF_DELAY HALF_CYC_60
unsigned int __eeprom uiEEOnDelay = DFT_ON_DELAY;
unsigned int __eeprom uiEEOffDelay = DFT_OFF_DELAY;
__no_init unsigned int uiOnDelay;
__no_init unsigned int uiOffDelay;

#define LOAD_OFF  0
#define LOAD_ON   1
unsigned char __eeprom ucEELoadOnOff = LOAD_OFF;
__no_init unsigned char ucLoadOnOff;

#define UNITSTATE_VIRGIN  0x5a
#define UNITSTATE_MATURE  0xff
unsigned char __eeprom ucEEUnitState = UNITSTATE_VIRGIN;
__no_init unsigned char ucUnitState;

unsigned char __eeprom ucEEosccal = 0;

unsigned char ucTemp = 0;
unsigned int  uiTemp = 0;

#include <iom48.h>
#include <intrinsics.h>

void buttonManipulation(void);
void updateStatus(void);
void updateTimer(void);
void updateCDS(void);
void updateLED(void);
void updatePIR(void);

void goLoadOn(void);
void goManualOff(void);
void goAutoOff(void);
void goOnIfDark(void);

void inoutTestMode(void);

void lineSync(void);

unsigned char __adc__(unsigned char);
void __figureoutdelay__(void);

void delayandswitch(void);

////////////////////////////////////////////////////////////////////////////////

////////////////////////////////////////////////////////////////////////////////

__C_task void main(void)
{
  if ((MCUSR & (1 << WDRF)) && (ucEEUnitState == UNITSTATE_MATURE))  //watchdog reset
  {
    if (uiOnDelay != uiEEOnDelay)
    {
      uiEEOnDelay = uiOnDelay;
    }
    if (uiOffDelay != uiEEOffDelay)
    {
      uiEEOffDelay = uiOffDelay;
    }
    if (ucLoadOnOff != ucEELoadOnOff)
    {
      ucEELoadOnOff = ucLoadOnOff;
    }
  }

  // reset WDT
  __watchdog_reset();
  // Clear WDRF in MCUSR
  MCUSR &= ~(1<<WDRF);
  // Write logical one to WDCE and WDE
  // Keep old prescaler setting to prevent unintentional time-out
  WDTCSR |= (1<<WDCE) | (1<<WDE);
  // Turn off WDT
  WDTCSR = 0x00;

  PORTB = PORT_INIT;
  PORTC = PORT_INIT;
  PORTD = PORT_INIT;

  DDRB = DDRB_INIT;
  DDRC = DDRC_INIT;
  DDRD = DDRD_INIT;

  ADCSRA = ADCSRA_OFF;
  DIDR0 = DIDR0_INIT;

  ACSR = 1<<7;

  TCCR2B = TCCR2B_INIT;
  TCCR2A = TCCR2A_OFF;

  ucUnitState = ucEEUnitState;
  ucLoadOnOff = (ucEELoadOnOff & 0x01);
  uiOnDelay = uiEEOnDelay;
  uiOffDelay = uiEEOffDelay;

  //config the uC operating frequency
  CLKPR = 1<<7;
  CLKPR = CLKPR_INIT;   //Run at 2MHz

  if (UNITSTATE_VIRGIN == ucUnitState)
  {
    uiLEDFlashPattern = LED_FLASH_PAT_SUCC;
    TCNT1 = 0;
    TCCR1B = TCCR1B_INIT;
    while (INPUT_LINE == 0)
    {
      if (TCNT1 >= FULL_CYC_60)
      {
        uiLEDFlashPattern = LED_FLASH_PAT_ERR1;
        break;
      }
    }
    if (uiLEDFlashPattern == LED_FLASH_PAT_SUCC)
    {
      TCNT1 = 0;
      while (INPUT_LINE == 1)
      {
        if (TCNT1 >= FULL_CYC_60)
        {
          uiLEDFlashPattern = LED_FLASH_PAT_ERR1;
          break;
        }
      }
    }
    if (uiLEDFlashPattern == LED_FLASH_PAT_SUCC)
    {
      do
      {
        while (INPUT_LINE == 1)
          ;
        TCNT1 = 0;
        GTCCR |= (1 << PSR10);
        while (INPUT_LINE == 0)
          ;
        uiTemp = TCNT1;
        if (uiTemp <= HALF_CYC_60 - 3)
        {
          OSCCAL += 2;
        }
        else if (uiTemp >= HALF_CYC_60 + 4)
        {
          OSCCAL -= 2;
        }
      }
      while ((uiTemp <= HALF_CYC_60 - 3) || (uiTemp >= HALF_CYC_60 + 4));
    }
    if (uiLEDFlashPattern == LED_FLASH_PAT_SUCC)
    {
      while (TCNT1 <= HALF_CYC_60 + QUART_CYC_60)
        ;
      if (INPUT_LOAD == 1)  //declare error type 3 when see relay input high when relay is off
      {
        uiLEDFlashPattern = LED_FLASH_PAT_ERR3;
      }
    }
    if (uiLEDFlashPattern == LED_FLASH_PAT_SUCC)
    {
      ucEEUnitState = UNITSTATE_MATURE;
      ucEEosccal = OSCCAL;
      ucTemp = 8;
      while (ucTemp > 0)
      {
        lineSync();
        if ((1 == ucStatus.bf_var.LINEFREQ) && ((ucTimerBase | ucTimerSystem) == 0))
        {
          OUTPUT_RELAY_CONTROL ^= 1;
          ucTemp--;
        }
      }
    }
    while (1)
    {
      __delay_cycles(0x7ffff);
      if (ucTemp == 0)
      {
        ucTemp = 16;
      }
      OUTPUT_LED_CONTROL = 0;
      if (uiLEDFlashPattern & (1 << (ucTemp - 1)))
      {
        OUTPUT_LED_CONTROL = 1;
      }
      ucTemp--;
    }
  }

  OSCCAL = ucEEosccal;

  // reset WDT
  __watchdog_reset();
  // start timed equence
  WDTCSR |= ((1<<WDCE)|(1<<WDE));
  // set new time-out value (~0.064s)
  WDTCSR = (1<<WDE)|(1<<WDP1);   //0.064s period

  if (LOAD_ON == ucLoadOnOff)
  {
    OUTPUT_RELAY_CONTROL = 1;
    goLoadOn();
    ucStatus.bf_var.OCCUPIED = 1;
    updateTimer();
  }
  else if (ucMode == MODE_U)
  {
    goAutoOff();
  }

  while (1)
  {
    lineSync();   //sync to line fall eage

    if (1 == ucStatus.bf_var.LINEFREQ)
    {
      if (ucStatus.bf_var.RELAYBUFFER != OUTPUT_RELAY_CONTROL)
      {
        delayandswitch();
      }
      else
      {
        ucLoadOnOff = ucStatus.bf_var.RELAYBUFFER;
        if (ucTimerBase == 0)
        {
          if (uiTimerTestMode > 0)
          {
            uiTimerTestMode--;
          }
        }
        updateCDS();
        updatePIR();
        buttonManipulation();
        switch (ucMsgButton)
        {
          default:
            if (ucMsgButton == MSG_MAJOR_BUTTON_INOUTTESTMODE_HOLD)
            {
              if (ucStatus.bf_var.MAJORBUTTONHELD == 0)
              {
                goLoadOn();
                ucStatus.bf_var.MAJORBUTTONHELD = 1;
              }
              ucStatus.bf_var.OCCUPIED = 1;
            }
            else if (ucMsgButton == MSG_MAJOR_BUTTON_INOUTTESTMODE_PRESSED)
            {
              ucStatus.bf_var.MAJORBUTTONHELD = 0;
              inoutTestMode();
              ucStatus.bf_var.OCCUPIED = 1;
            }
            else if ((ucMsgButton == MSG_MAJOR_BUTTON_SHORT_PRESSED) || (ucMsgButton == MSG_BUTTON_NONE))
            {
              ucStatus.bf_var.OCCUPIED = (((ucMsgButton == MSG_MAJOR_BUTTON_SHORT_PRESSED) && (uiTimerTestMode == 0)) || ucStatus.bf_var.SPACEOCCUPIED);
              updateStatus();
            }
            updateTimer();
            break;
        }
        updateLED();
      }
    }
  }
}

void buttonManipulation(void)
{
  static unsigned int uiMajorButtonTimer = 0;
  static unsigned char ucButtonTimer2 = 0;  //for Major Button usuage
  ucMsgButton = MSG_BUTTON_NONE;
  if (BUTTON_ON == INPUT_MAJOR_BUTTON)
  {
    if (uiMajorButtonTimer >= BUTTON_INOUTTESTMODE_TIME) //10s
    {
      ucMsgButton = MSG_MAJOR_BUTTON_INOUTTESTMODE_HOLD;
    }
    else if (uiMajorButtonTimer >= BUTTON_HOLD_TIME) //0.5s
    {
      ucMsgButton = MSG_MAJOR_BUTTON_LONG_HOLD;
    }
    else if (uiMajorButtonTimer >= BUTTON_DEBOUNCING_TIME)  //0.1s
    {
      ucMsgButton = MSG_MAJOR_BUTTON_SHORT_HOLD;
    }
    if ((++ucButtonTimer2) == ucTimerUnit)
    {
      ucButtonTimer2 = 0;
      if ((++uiMajorButtonTimer) == 0)
      {
        uiMajorButtonTimer--;
      }
    }
  }
  else
  {
    if (uiMajorButtonTimer >= BUTTON_INOUTTESTMODE_TIME)  //10s
    {
      ucMsgButton = MSG_MAJOR_BUTTON_INOUTTESTMODE_PRESSED;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -