📄 05070.c
字号:
//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 + -