📄 timer_io_adc.c
字号:
////////////////////////////////////////////////////////////////
//
// S C R I P T H E R M
// A SCRIPTABLE THERMOMETER
//
// entry of the National Semiconductor COP8FLASH Design Contest
// submitted by Alberto Ricci Bitti (C) 2001
// a.riccibitti@ra.nettuno.it
//
//--------------------------------------------------------------
// FOR A BETTER VIEW SET TAB SIZE=4, INDENT SIZE=4
//--------------------------------------------------------------
// FILE : timer_io_adc.c
// PURPOSE: handles most of the hardware-related code AND
// the thermomometer/thermostat action.
// ----------------------------------------------------
// Inputs are latched and copied into IN variable.
// dip switches are sampled and copied to global flags
// Outputs are set according to OUT variable.
// PWM sets LCd contrast
// Timer interrupt updates TIME variable
// get_adc() selects and reads an ADC channel
// therm_update() updates THERM variable and sets the
// thermostat according to specified HYST variable
//
////////////////////////////////////////////////////////////////
#include <ioc8cdr.h>
#include <incop8.h>
#include "types.h"
#include "memory.h"
#include "variables.h"
#include "timer_io_adc.h"
#define FLASH_LCD_CONTRAST 0x6002
#define FLASH_CALIBRATION_HI 0X6000
#define FLASH_CALIBRATION_LO 0X6001
//extern volatile int values[];
extern volatile flags_t flags;
//extern unsigned int contrast;
static unsigned int get_adc( unsigned char channel)
{
//select ADC channel 2 or 3, single ended, no mux out, prescaler on, stop conversion
__ENAD = 0x02 | (channel <<4);
__ENAD_bit.adbsy = 1; //start conversion
while (__ENAD_bit.adbsy)
{ /*loop intentionally void*/ };
return ((unsigned int)__ADRSTH << 2) + (__ADRSTL >> 6);
}
void timer_io_adc_initialize(void)
{
// instruction clock is 2MHz, divide by 50000+50000 to get 20 Hz
__T2RALO = 50000 && 0xFF;
__T2RAHI = 50000 >> 8;
__T2RBLO = 50000 && 0xFF;
__T2RBHI = 50000 >> 8;
__T2CNTRL = 0x94; //enable interrupt A, PWM mode, no pin toggle
// LCD contrast PWM
__T3RALO = 0xFF; //always provide a negative offset
__T3RAHI = 0;
__T3RBLO = __read_flash_byte(FLASH_LCD_CONTRAST);
__T3RBHI = 0;
__T3CNTRL = 0xB0; //no interrupts, PWM mode, pin toggle
__PORTLC_bit.bit6 = 1; //timer output to pin
// pulloup on dip switches
__PORTLD_bit.bit1 = 1;
__PORTLD_bit.bit0 = 1;
// pullup on key inputs
__PORTLD_bit.bit4 = 1;
__PORTLD_bit.bit5 = 1;
__PORTLD_bit.bit7 = 1;
// pullup on digital inputs
__PORTAD_bit.bit4 = 1;
__PORTAD_bit.bit5 = 1;
__PORTAD_bit.bit6 = 1;
__PORTAD_bit.bit7 = 1;
// set relay lines as output
__PORTGC_bit.bit0 = 1;
__PORTGC_bit.bit1 = 1;
__PORTGC_bit.bit2 = 1;
__PORTGC_bit.bit3 = 1;
}
#pragma vector=__TIMER_2A
__interrupt void timer_interrupt(void)
{
static unsigned char by_20;
//clear interrupt pending flag
__T2CNTRL_bit.t2pnda = 0;
// it takes 20 cycles to make a second
if (++by_20 == 20)
{
by_20 = 0;
VAR_TIME++;
flags.update_therm = TRUE;
};
//flag input changes
if (!__PORTAP_bit.bit4) VAR_IN |= 1;
if (!__PORTAP_bit.bit5) VAR_IN |= 2;
if (!__PORTAP_bit.bit6) VAR_IN |= 4;
if (!__PORTAP_bit.bit7) VAR_IN |= 8;
if (!__PORTLP_bit.bit7) VAR_IN |= 32;
if (!__PORTLP_bit.bit5) VAR_IN |= 64;
if (!__PORTLP_bit.bit4) VAR_IN |= 128;
// update outputs
__PORTGD_bit.bit0 = (VAR_OUT & 1) != 0;
__PORTGD_bit.bit1 = (VAR_OUT & 2) != 0;
__PORTGD_bit.bit2 = (VAR_OUT & 4) != 0;
//flag dip switches
flags.program = !__PORTLP_bit.bit1;
flags.debug = __PORTLP_bit.bit0;
flags.clear = ( flags.program && !__PORTLP_bit.bit7 );
if (flags.program) flags.running = FALSE;
}
//////////////////////////////////////////////////////////////////////
// THERMOMETER READOUT & THERMOSTAT ACTION
//
// to determine calibration:
//
// calibration = ADCref/ADCtemp*(5*Farenheit + 2297)
//
// to determine temperature:
//
// 癋 = (ADCtherm*calibration)/ADCref - 2297 / 5
//
//////////////////////////////////////////////////////////////////////
extern unsigned int cal;
static unsigned long calibration;
static volatile unsigned int ADCtherm;
static volatile unsigned int ADCref;
void therm_initialize(void)
{
calibration = __read_flash_byte(FLASH_CALIBRATION_LO) +
__read_flash_byte(FLASH_CALIBRATION_HI) * 256L;
}
#define THERMOSTAT_ON { __PORTGD_bit.bit3 = 1; }
#define THERMOSTAT_OFF { __PORTGD_bit.bit3 = 0; }
void therm_update(void)
{
ADCtherm = get_adc(2);
ADCref = get_adc(3);
VAR_THERM = (((ADCtherm * calibration)/ ADCref) - 2297) / 5;
flags.update_therm = FALSE;
if (VAR_HYSTERESIS >= 0) //HYS > 0, act as an heating thermostat
{
if (VAR_THERM <= VAR_THRESHOLD)
THERMOSTAT_ON
else if (VAR_THERM >= (VAR_THRESHOLD + VAR_HYSTERESIS))
THERMOSTAT_OFF
}
else // HYS < 0, act as a cooling thermostat
{
if (VAR_THERM >= VAR_THRESHOLD)
THERMOSTAT_ON
else if (VAR_THERM <= (VAR_THRESHOLD - VAR_HYSTERESIS))
THERMOSTAT_OFF
}
}
//////////////////////////////////////////////////////////////////
// the following interrupts are NOPed ease trapping during debug
// remove if you need a few extra bytes
//////////////////////////////////////////////////////////////////
#pragma vector=__INTR
__interrupt void trap_1(void)
{
__reset_pending_interrupt();
}
/* unused/reserved 0x1C */
#pragma vector=0x1C
__interrupt void trap_2(void)
{
__no_operation();
}
#pragma vector=__PIN_G0
__interrupt void trap_3(void)
{
__no_operation();
}
#pragma vector=__TIMER_0
__interrupt void trap_4(void)
{
__no_operation();
}
#pragma vector=__TIMER_1A
__interrupt void trap_5(void)
{
__no_operation();
}
#pragma vector=__TIMER_1B
__interrupt void trap_6(void)
{
__no_operation();
}
#pragma vector=__MICROWIRE_PLUS
__interrupt void trap_7(void)
{
__no_operation();
}
/* unused/reserved 0x10 */
#pragma vector=0x10
__interrupt void trap_8(void)
{
__no_operation();
}
/*#pragma vector=__UART_RECEIVE */
#pragma vector=__UART_TRANSMIT
__interrupt void trap_10(void)
{
__no_operation();
}
/* #pragma vector=__TIMER_2A */
#pragma vector=__TIMER_2B
__interrupt void trap_11(void)
{
__no_operation();
}
#pragma vector=__TIMER_3A
__interrupt void trap_12(void)
{
__no_operation();
}
#pragma vector=__TIMER_3B
__interrupt void trap_13(void)
{
__no_operation();
}
#pragma vector=__PORTL_WAKEUP
__interrupt void trap_14(void)
{
__no_operation();
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -