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

📄 timer_io_adc.c

📁 COP8 CPU的一个解释型BASIC源码
💻 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 + -