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

📄 acprd_main.c

📁 source code for a sample alarm control panel system using Freescale MC9S12DP256 . The project was im
💻 C
字号:
//=============================================================================
// File: ACPRD_MAIN.C - V1.00
// Rem.: The ACPRD Project Page on the Web -> http://hc12web.de/acprd
//=============================================================================

//-- Includes -----------------------------------------------------------------

#include <stdio.h>
#include "datatypes.h"
#include "hcs12dp256.h"
#include "s12_atd.h"
#include "s12_crg.h"
#include "s12_eets.h"
#include "s12_sci.h"
#include "s12_spi.h"
#include "s12co_spiio.h"
#include "s12co_led.h"
#include "t6963.h"
#include "display.h"
#include "timedate.h"
#include "acprd_timer.h"
#include "acprd_encoder.h"
#include "acprd_freqout.h"
#include "acprd_song.h"
#include "acprd_keyb.h"
#include "acprd_main.h"

//-- Defines ------------------------------------------------------------------

//-- Static Data --------------------------------------------------------------

//-- software counters --
//
volatile UINT16 cnt0010;			// Free Running Counter period = 10ms
volatile UINT16 mdc0030;			// Modulus Down Counter period = 30ms
volatile UINT16 mdc0100;			// Modulus Down Counter period = 100ms
volatile UINT16 mdc0101;			// Modulus Down Counter period = 100ms
volatile UINT16 mdc0200;			// Modulus Down Counter period = 200ms
volatile UINT16 mdc1000;			// Modulus Down Counter period = 1000ms

//-- hardware shadow registers --
//
UINT8 shadow_spipo;					// SPI Parallel Out shadow
UINT8 shadow_spipi;					// SPI Parallel In shadow
UINT16 shadow_atd0[ATD_MAX_CHANNELS]; // ATD0 (average) shadow
struct tm *shadow_tm;				// pointer to time/date structure
BOOL shadow_tm_disable;				// disables update of clock

//-- alarm configuration and status variables --
//
UINT8 al_system_armed;				// flag for global "armed" status

#define AL_MAX_LINES		4		// number of Alarm Lines (LINE0 = LIN)
#define AL_EXITDLY_S		30		// time for exit delay

#define AL_STAT_OKAY		0x00	// no alarm (loop resistance within limits)
#define AL_STAT_ALARM		0x01	// normal alarm (switch opened)
#define AL_STAT_TAMPER		0x02	// tamper alarm (loop opened or shorted)
#define AL_STAT_ENTRY		0x04	// alarm, but entry time is still running
#define AL_STAT_SILENT		0x10	// alarm line triggers silent alarm only
UINT8 al_line_status[AL_MAX_LINES];	// current input status of each line
UINT8 al_line_exitdly[AL_MAX_LINES]; // exit delay of each line
UINT8 al_alarm_status[AL_MAX_LINES]; // latched/evaluated status of each line

UINT8 al_system_status;				// flag for global "alarm" status

#define AL_LTYP_SILENT		0x01	// alarm line triggers silent alarm only
#define AL_LTYP_DELAY		0x02	// alarm line reacts after a delay
#define AL_LTYP_DISABLE		0x04	// alarm line enabled 
UINT8 al_line_type[AL_MAX_LINES];	// behaviour of each line

UINT16 al_delay_time;				// delay time (in s) for delayed alarm type
UINT16 al_duration_time;			// duration (in s) of audible alarm

BOOL al_blinkled;					// blink LED on alarm
BOOL al_buzzer;						// sound buzzer on alarm
BOOL al_siren;						// sound siren on alarm
BOOL al_flashlight;					// flashlight on alarm

//-- misc vars --
//
BOOL acprd_emode;					// "Entertainment Mode"
BOOL toggle;

//-- Constants ----------------------------------------------------------------

// user font definition in const UINT8 my_font[];
#include "font1.c"

// user song definition in const UINT16 my_song[];
#include "song1.c"
//#include "song2.c"

//-- Code ---------------------------------------------------------------------

// this function is called by the C-Startup Module
//
void _HC12Setup(void) {

	COPCTL = 0;							// disable Watchdog
	// enable Port Pullups to prevent...
	}

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

void delay(UINT16 msec) {

	UINT16 t;

	t = cnt0010 + msec/10;
	while(t != cnt0010) ;
	}

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

void buzz(void) {

	UINT8 n;

	for(n=0; n<3; n++) {
		setFreqOut(5000); // 200Hz
		delay(70);
		setFreqOut(0);
		delay(20);
		}
	}

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

// Background "Task"
// Caution: this func is part of the 10ms interrupt handler!
//
void every10ms(void) {

	UINT8 stat;

	cnt0010++;							// period = 10ms
	ENABLE_INTERRUPTS();				// give way to other (more frequent
										// or more important) tasks

	scanKeyb();
	putSPIPO(shadow_spipo);
	shadow_spipi = getSPIPI();

	if(++mdc0030 == 3) {				// period = 30ms
		mdc0030 = 0;
		handleSong();
		handleATD0(shadow_atd0);
		}

	if(++mdc0100 == 10) {				// period = 100ms
		mdc0100 = 0;
		refreshT6963a(disp_buf);
		}

	if(++mdc0101 == 10) {				// period = 100ms
		mdc0101 = 0;
		refreshT6963c(disp_buf);
		}

	if(++mdc0200 == 20) {				// period = 200ms
		mdc0200 = 0;
		stat = checkAlarm();
		if(al_system_armed && (stat & AL_STAT_ALARM)) {
			al_system_status = stat;
			}
		else {
			al_system_status = AL_STAT_OKAY;
			}
		if(al_system_status & AL_STAT_ALARM) {	// alarm
			al_blinkled = TRUE;
			toggleLED();
			toggle ^= 1;
			if(!(stat & AL_STAT_SILENT)) {		// audible
				al_buzzer = TRUE;
				al_siren = TRUE;
				al_flashlight = TRUE;
				shadow_spipo |= 0x0c;
				if(toggle) setFreqOut(5000);
				else setFreqOut(3000);
				}
			}
		else {									// no alarm
			if(al_blinkled == TRUE) {
				offLED();
				al_blinkled = FALSE;
				}
			if(al_buzzer == TRUE) {
				setFreqOut(0);
				al_buzzer = FALSE;
				}
			if(al_siren == TRUE) {
				shadow_spipo &= ~0x08;
				al_siren = FALSE;
				}
			if(al_flashlight == TRUE) {
				shadow_spipo &= ~0x04;
				al_flashlight = FALSE;
				}
			if(acprd_emode) toggleLED();
			}
		}

	if(++mdc1000 == 100) {				// period = 1000ms
		mdc1000 = 0;
		if(!shadow_tm_disable)
			shadow_tm = gmtime(gettimep());
		inctime();
		if(al_line_exitdly[0]) al_line_exitdly[0]--;
		if(al_line_exitdly[1]) al_line_exitdly[1]--;
		if(al_line_exitdly[2]) al_line_exitdly[2]--;
		if(al_line_exitdly[3]) al_line_exitdly[3]--;
		}
	}

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

void initACPRD(void) {

	UINT8 n, k;

	initLED();
	initPLL();
	initEETS();
	initTimer(every10ms);
	initSCI0(BAUD_19K2_24000);
	initSCI1(BAUD_9600_24000);
	initSPI0(SPIBD_500K_24000, 0, 0);
	initATD0();
	initSPIIO();
	initT6963(my_font);
	initDisp();
	initKeyb();
	initEncoder();
	initFreqOut();
	initSong();

	// all static vars are set to 0 in C-startup module, so
	// only vars with a default value != 0 will be handled here
	//
	systime = 0x386d4380L - 10L;		// 10sec before 00:00:00 2000/01/01
	mdc0100 = 1;
	mdc1000 = 99;
	shadow_spipo = 0x01;
	startATD0();
	for(n=0; n<20; n++) {				// fill average buffers
		k = 0;
		while(++k) ;
		handleATD0(shadow_atd0);
		}
	}

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

void armLines(void) {

	UINT8 n = 0;

	do {
		if(al_line_type[n] & AL_LTYP_DELAY) al_line_exitdly[n] = AL_EXITDLY_S;
		n++;
		} while(n < AL_MAX_LINES);
	}

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

void resetLines(void) {

	al_alarm_status[0] = AL_STAT_OKAY;
	al_alarm_status[1] = AL_STAT_OKAY;
	al_alarm_status[2] = AL_STAT_OKAY;
	al_alarm_status[3] = AL_STAT_OKAY;
	al_system_status = AL_STAT_OKAY;
	}

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

UINT8 checkAlarm(void) {

	UINT8 n, stat;
	UINT16 v;

	// get line status
	for(n=0; n<AL_MAX_LINES; n++) {
		v = shadow_atd0[n+1];
		if(v < 0x0b00)		stat = AL_STAT_TAMPER;
		else if(v < 0x0e00)	stat = AL_STAT_OKAY;
		else if(v < 0x1a00) stat = AL_STAT_ALARM;
		else				stat = AL_STAT_TAMPER;
		al_line_status[n] =  stat;
		}

	// line status -> alarm status
	for(n=0; n<AL_MAX_LINES; n++) {
		if((al_line_type[n] & AL_LTYP_DISABLE) == 0) {
			stat = al_line_status[n];
			// alarm not valid if exit delay running
			if(al_line_exitdly[n]) stat &= ~AL_STAT_ALARM;
			if((stat & AL_STAT_ALARM) || (stat & AL_STAT_TAMPER)) {
				if(al_line_type[n] & AL_LTYP_SILENT) stat = AL_STAT_SILENT;
				al_alarm_status[n] = stat | AL_STAT_ALARM;
				}
			}
		}

	// alarm status -> system status
	for(n=0; n<AL_MAX_LINES; n++) {
		stat = al_alarm_status[n]; 
		if(stat & AL_STAT_ALARM) return stat; 
		}
	return AL_STAT_OKAY;
	}

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

// retrieve Alarm Line Configuration from EEPROM
//
void getLineConfig(void) {

	struct { UINT8 x0, x1, x2, x3; } item;

	readItemEETS(0, &item);

	al_line_type[0] = ~item.x0;
	al_line_type[1] = ~item.x1;
	al_line_type[2] = ~item.x2;
	al_line_type[3] = ~item.x3;
	}

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

// save Alarm Line Configuration to EEPROM
//
void saveLineConfig(void) {

	struct { UINT8 x0, x1, x2, x3; } item;

	item.x0 = ~al_line_type[0];
	item.x1 = ~al_line_type[1];
	item.x2 = ~al_line_type[2];
	item.x3 = ~al_line_type[3];

	writeItemEETS(0, &item);
	}

//-----------------------------------------------------------------------------
// subroutines for the handling of display objects
#include "acprd_dobj.c"
//-----------------------------------------------------------------------------


void setTimDat(void) {

	INT8 item, i;						
	time_t newtime;

	const UINT8 *sav0 = dobj_keys_label[0];
	const UINT8 *sav1 = dobj_keys_label[1];
	const UINT8 *sav2 = dobj_keys_label[2];
	const UINT8 *sav3 = dobj_keys_label[3];

	dobj_keys_label[0] = key_empty;
	dobj_keys_label[1] = key_empty; 
	dobj_keys_label[2] = key_empty; 
	dobj_keys_label[3] = key_empty; 
	drawAll();

	shadow_tm_disable = TRUE;			// disable clock update
	item = 0;
	do {
		if(hasEncoder()) {
			i = (getEncoder() < 0) ? -1 : 1;
			switch(item) {
				case 0:
					shadow_tm->tm_hour += i;
					if(shadow_tm->tm_hour == 24) shadow_tm->tm_hour = 0;
					else if(shadow_tm->tm_hour > 24) shadow_tm->tm_hour = 23;
					break;
				case 1:
					shadow_tm->tm_min += i;
					if(shadow_tm->tm_min == 60) shadow_tm->tm_min = 0;
					else if(shadow_tm->tm_min > 60) shadow_tm->tm_min = 59;
					break;
				case 2:
					shadow_tm->tm_sec += i;
					if(shadow_tm->tm_sec == 60) shadow_tm->tm_sec = 0;
					else if(shadow_tm->tm_sec > 60) shadow_tm->tm_sec = 59;
					break;
				case 3:
					shadow_tm->tm_year += i;
					if(shadow_tm->tm_year > 199) shadow_tm->tm_year = 199;
					else if(shadow_tm->tm_year < 70) shadow_tm->tm_year = 70;
					break;
				case 4:
					shadow_tm->tm_mon += i;
					if(shadow_tm->tm_mon == 12) shadow_tm->tm_mon = 0;
					else if(shadow_tm->tm_mon > 12) shadow_tm->tm_mon = 11;
					break;
				case 5:
					shadow_tm->tm_mday += i;
					if(shadow_tm->tm_mday == 32) shadow_tm->tm_mday = 1;
					else if(shadow_tm->tm_mday < 1) shadow_tm->tm_mday = 31;
					break;
				default:
					break;
				}
			}
		if(hasKeyb()) {
			if(getKeyb() == KEYB_KC5) {
				item++;
				if(item == 6) item = -1;
				}
			}
		dobj_timedate_sel = item;
		drawAll();
		} while(item != -1);

	newtime = mktime(shadow_tm);		// convert struct to seconds
	stime(&newtime);					// set systime accordingly
	shadow_tm_disable = FALSE;			// allow clock updates

	dobj_keys_label[0] = sav0;
	dobj_keys_label[1] = sav1; 
	dobj_keys_label[2] = sav2; 
	dobj_keys_label[3] = sav3; 
	}

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

void setupLines(void) {

	INT8 item;
	UINT8 k, x;

	const UINT8 *sav0 = dobj_keys_label[0];
	const UINT8 *sav1 = dobj_keys_label[1];
	const UINT8 *sav2 = dobj_keys_label[2];
	const UINT8 *sav3 = dobj_keys_label[3];

	dobj_keys_label[0] = key_line1;
	dobj_keys_label[1] = key_line2; 
	dobj_keys_label[2] = key_line3; 
	dobj_keys_label[3] = key_line4; 

	item = 0;
	do {
		if(hasEncoder()) {
			if(getEncoder() < 0) {
				x = (al_line_type[item] - 1) & 0x07;
				if(x == 7) x = 5;
				else if(x == 4) x = 3;
				}
			else {
				x = (al_line_type[item] + 1) & 0x07;
				if(x == 4) x = 5;
				else if(x == 6) x = 0;
				}
			al_line_type[item] = x;
			}
		if(hasKeyb()) {
			k = getKeyb();
			switch(k) { 
				case KEYB_KC1:
				case KEYB_KC2:
				case KEYB_KC3:
				case KEYB_KC4:
					item = k-1;
					break;
				case KEYB_KC5:
					item++;
					if(item == 4) item = -1;
					break;
				default:
					break;
				}
			}
		dobj_asl_sel = item;
		drawAll();
		} while(item != -1);
	saveLineConfig();

	dobj_keys_label[0] = sav0;
	dobj_keys_label[1] = sav1; 
	dobj_keys_label[2] = sav2; 
	dobj_keys_label[3] = sav3; 
	}

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

void doMenu(UINT8 k) {

	INT8 sel;

	switch(k) {
		case KEYB_KC2:					// UP
			dobj_jogmenu_sel -= 1;
			if(dobj_jogmenu_sel < 0) dobj_jogmenu_sel = 0;
			break;
		case KEYB_KC3:					// DOWN
			dobj_jogmenu_sel += 1;
			if(dobj_jogmenu_sel > 5) dobj_jogmenu_sel = 5;
			break;
		case KEYB_KC1:					// ARM
			dobj_jogmenu_sel = 0;
			drawAll();
		case KEYB_KC4:					// ENT
		case KEYB_KC5:
			gotoxyDisp(28, dobj_jogmenu_y+dobj_jogmenu_sel);
			prDispMult(11, TA_NORMAL);
			delay(200);
			gotoxyDisp(28, dobj_jogmenu_y+dobj_jogmenu_sel);
			prDispMult(11, TA_REVERS);
			delay(200);

			if(al_system_armed && (dobj_jogmenu_sel != 0)) {
				buzz();
				return;
				}
			sel = dobj_jogmenu_sel;
			dobj_jogmenu_sel = -1;
			switch(sel) {
				case 0:	// Arm/Disable
					//in a real system, ask for PIN code before disable
					al_system_armed ^= 1;
					if(al_system_armed) armLines();
					break;
				case 1:	// Reset Lines
					resetLines();
					break;
				case 2:	// Setup Lines
					setupLines();
					break;
				case 3:	// Set Tim/Dat
					setTimDat();
					break;
				case 4:	// Remote Ctrl
					//### TBD
					buzz();
					break;
				case 5: // EntertainMe
					if(acprd_emode == FALSE) {
						acprd_emode = TRUE;
						startSong(my_song);
						shadow_spipo |= 0xf8;
						}
					else {
						acprd_emode = FALSE;
						startSong(NULL);
						shadow_spipo &= ~0xf8;
						offLED();
						}
					break;
				default:
					break;
				}
			getEncoder();	// flush
			flushKeyb();	// flush
			dobj_jogmenu_sel = sel;
			break;
		default:
			break;
		}
	}

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

void main(void) {

	UINT8 k;

	initACPRD();						// initialize system
	ENABLE_INTERRUPTS();				// global interrupt enable
	getLineConfig();					// read Alarm Line Config from EEPROM
	drawInit();							// initialize display objects

	while(1) {
		drawAll();
		k = 0;
		if(hasEncoder()) k = (getEncoder() < 0) ? KEYB_KC3 : KEYB_KC2;
		else if(hasKeyb()) k = getKeyb();
		if(k) doMenu(k);
		}
	}

//=============================================================================

⌨️ 快捷键说明

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