📄 hal.h
字号:
#define CLOCK_XOSC 0
#define CLOCK_X32 1
//----------------------------------------------------------------------------
//----------------------------------------------------------------------------
// Power up/down main crystal oscillator (XOSC)
#define XOSC_ENABLE(bool) ( RFMAIN=(bool) ? (RFMAIN&~0x06) : (RFMAIN|0x06))
// Power up/down 32 kHz crystal oscillator (X32)
#define X32_ENABLE(bool) ( X32CON=(bool) ? (X32CON&~0x02) : (X32CON|0x02) )
//----------------------------------------------------------------------------
//----------------------------------------------------------------------------
// Macro used to configure whether the X32 oscillator is connected to a
// crystal or whether a CMOS-compatible clock signal is applied to the
// XOSC32_Q1 pin.
#define X32_INPUT_SOURCE(s) (X32CON=(X32CON&~0x04) | (s) )
// One of the below constants must be used:
#define X32_USING_CRYSTAL 0
#define X32_USING_EXTERNAL_CLOCK 4
//----------------------------------------------------------------------------
/*****************************************************************************
*****************************************************************************
************* Timer macros/functions *************
*****************************************************************************
****************************************************************************/
//////////////////////////////////////////////////////////////////////////////
// Timers/Counters 0 & 1 can be configured in a number of ways. The following
// functions allow simple configuration of these in their most common uses:
// as interrupt timers and interrupt pulse counters. Other, more advanced uses
// require manual configuration of the timers/counters.
//////////////////////////////////////////////////////////////////////////////
//----------------------------------------------------------------------------
// ulong halConfigTimer01(...);
//
// Description:
// This function configures timer 0 or 1 (depending on the value given in
// _option_ as either an interrupt timer (an interrupt is generated at
// certain intervals in time, as specified by _period) or an interrupt
// pulse counter (an interrupt when _period_ number of pulses have
// been detected on P3.4/P3.5 for timer0/timer1.) If _period_ is
// specified as 0, then, in timer mode the timeout period will be set to
// the maximum possible, and in counter mode the pulse counter will allow
// the maximum number of pulses before generating an interrupt.
// Some timer settings (with long timeouts) require that the user
// initializes timer register in the interrupt service routine (ISR.) This
// should be done by using the appropriate version of the
// ISR_TIMERx_ADJUST(m) macro with the word pointed to by _modulo_ as an
// argument. The _modulo_ argument takes a pointer to a word, if it is
// NULL, many timer settings will be unavailable. It is the responsibility
// of the programmer to make sure that the appropriate timer ISR has been
// declared (and that it begins with the obligatory ISR_TIMERx_ADJUST(m)
// macro). The timer must be started with macro TIMERx_RUN(TRUE).
//
// Arguments:
// byte options
// Options indicating which timer to configure and how. Different
// constants for _option_ is defined below.
// ulong period
// The desired period between interrupts in microseconds in timer
// mode, or the number of counted pulses between interrupts in counter
// mode.
// If specified as 0, then, in timer mode the timeout period will be
// set to the maximum possible, and in counter mode the pulse counter
// will allow the maximum number of pulses before generating an
// interrupt.
// word clkFreq
// The XOSC clock frequency in kHz.
// word xdata* modulo
// A pointer to a word (in xdata) which after the function has returned
// contains the value to supply to the obligatory macro invocation of
// ISR_TIMERx_ADJUST(m) at the start of the timer ISR.
//
// Return value:
// ulong
// In timer mode, the actual period in microseconds between interrupts
// or zero if the period is impossible to achieve.
// In counter mode, zero if the supplied count value is impossible to
// achieve, otherwise one.
//----------------------------------------------------------------------------
ulong halConfigTimer01(byte options, ulong period, word clkFreq, word* modulo);
// option is one or more of:
#define TIMER0 0 // Configure timer 0
#define TIMER1 1 // Configure timer 1
#define TIMER01_INT_TIMER 0 // Configure as an interrupt timer
#define TIMER01_INT_PULSE_COUNTER 2 // Configure as an interrupt pulse counter
#define TIMER01_NO_INT_TIMER 4 // Configure as timer that doesn't
// generate interrupts
// Adjust macro used for timer adjustment in timer 0/1 ISRs.
// This macro should be used at the start of the ISR of timer 0.
#define ISR_TIMER0_ADJUST(m) { \
if (m) { \
TR0=0; \
TL0+=(m)&0xFF; \
TH0+=(m)>>8; \
TR0=1; \
} \
}
// Adjust macro used for timer adjustment in timer 0/1 ISRs.
// This macro should be used at the start of the ISR of timer 1.
#define ISR_TIMER1_ADJUST(m) { \
if (m) { \
TR1=0; \
TL1+=(m)&0xFF; \
TH1+=(m)>>8; \
TR1=1; \
} \
}
//----------------------------------------------------------------------------
//----------------------------------------------------------------------------
// ulong halConfigTimer23(...);
//
// Description:
// This function configures timer 2 or 3 (depending on the value given in
// _option_ as either an interrupt timer (an interrupt is generated at
// certain intervals in time, as specified by _period) or a pulse width
// modulator (PWM).
// If _period_ is specified as 0, then, in timer mode the timeout period will
// be set to the maximum possible, and in PWM mode the period will be
// set as long as possible. Using the PWM mode of timer 2/3 overrides the
// normal operation of ports P3.4/P3.5 and can thus not be used in conjunction
// with timer 0/1 configured as counters. The duty cycle is set to 50% (128/255)
// initially in PWM mode.
// The timer/PWM must be started with macro TIMERx_RUN(TRUE).
//
// Arguments:
// byte options
// Options indicating which timer to configure and how. Different
// constants for _option_ is defined below.
// ulong period
// The desired period between interrupts in microseconds. In PWM mode
// the duty cycle will be set as close to 50% as possible. This duty
// cycle can be changed (in an ISR or at any other time) by using the
// appropriate PWMx_SET_DUTY_CYCLE(...) macro. If _period_
// is 0, then the maximum period possible will be set. The period can
// also be adjusted dynamically with the PWMx_SET_PERIOD(...) macro.
// word clkFreq
// The XOSC clock frequency in kHz.
//
// Return value:
// ulong
// The actual period in microseconds or zero if the desired period is
// too high.
//----------------------------------------------------------------------------
#if (__MODEL__ == 0) // Memory model: 0 = SMALL, 1 = COMPACT, 2 = LARGE
ulong halConfigTimer23(byte options, ulong period, word clkFreq) ;
#else
ulong halConfigTimer23(byte options, ulong period, word clkFreq) reentrant;
#endif
// option is one or more of:
#define TIMER2 0 // Configure timer 2
#define TIMER3 1 // Configure timer 3
#define TIMER23_INT_TIMER 4 // Configure as an interrupt timer
#define TIMER23_PWM 2 // Configure as PWM
#define TIMER23_NO_INT_TIMER 0 // Configure as a timer that doesn't
// generate interrupts
//----------------------------------------------------------------------------
// Macro for adjusting the duty cycle of PWMs 2/3 in increments of 1/255
#define PWM2_SET_DUTY_CYCLE(cycle) \
( T2= (cycle) )
#define PWM3_SET_DUTY_CYCLE(cycle) \
( T3= (cycle) )
// Macro for adjusting the period of PWMs 2/3 in increments of CLK/255.
#define PWM2_SET_PERIOD(period) \
( T2PRE=(period) )
#define PWM3_SET_PERIOD(period) \
( T3PRE=(period) )
//----------------------------------------------------------------------------
// void halConfigRealtimeClock(...);
//
// Description:
// This function configures the realtime clock. It's period in seconds
// is given in _period_. In order for the realtime clock to function
// the 32 kHz oscillator must be connected to a 32 kHz crystal or a 32 kHz
// clock signal must be available on pin XOSC32_Q1. The 32 kHz oscillator
// must be started up and stable before the RTC is activated.
// The realtime clock must be started by using the macro RTC_RUN(TRUE).
//
// Arguments:
// byte period
// The desired period between interrupts in seconds.
//
// Return value:
// void
//----------------------------------------------------------------------------
void halConfigRealTimeClock(byte period);
// Macro for stopping and starting the timers.
#define TIMER0_RUN(bool) (TR0=!!(bool))
#define TIMER1_RUN(bool) (TR1=!!(bool))
#define TIMER2_RUN(bool) (TCON2= (bool) ? TCON2|0x02 : TCON2&~0x02)
#define TIMER3_RUN(bool) (TCON2= (bool) ? TCON2|0x08 : TCON2&~0x08)
#define RTC_RUN(bool) (RTCON= (bool) ? RTCON|0x80 : RTCON&~0x80)
// Macros pertaining to the watchdog timer.
// The watchdog must periodically be reset to avoid a system reset.
// It times out after system clock/(256*divisor)
#define WDT_DIVIDE_CLOCK_BY_2048() ( WDT=(WDT&~0x03)|0)
#define WDT_DIVIDE_CLOCK_BY_4096() ( WDT=(WDT&~0x03)|1)
#define WDT_DIVIDE_CLOCK_BY_8192() ( WDT=(WDT&~0x03)|2)
#define WDT_DIVIDE_CLOCK_BY_16384() ( WDT=(WDT&~0x03)|3)
#define WDT_RESET() (WDT|=0x04)
#define WDT_ENABLE(bool) \
do { \
if (bool) { WDT|=0x08; } \
else { WDT|=0x10; WDT&=~0x08; } \
} while (0)
/*****************************************************************************
*****************************************************************************
************* ADC macros/functions *************
*****************************************************************************
****************************************************************************/
//----------------------------------------------------------------------------
// bool halConfigADC(...)
//
// Description:
// This function configures the ADC. The _option_ argument is used to
// select operational mode, _clkFreq_ gives the device clock frequency in
// kHz, and _threshold_ is used to set the threshold value for some
// operational modes. An interrupt is generated in all modes (except
// for reset-generating mode in which a reset is generated instead) whenever
// the 8 MSB of the measured sample is greater or equal to the threshold
// value. Thus, if an interrupt for each sample is desired, the threshold
// should be set to 0 (and the ADC and GLOBAL_ADC_DES interrupts enabled.)
// After configuring the ADC it must be powered up using the ADC_POWER(bool)
// macro. It should be powered down again when not in use to conserve power.
// The correct ADC input must be selected using the ADC_SELECT_INPUT(input)
// macro and started using the ADC_RUN(bool) macro for continuous modes.
// The ADC_SAMPLE_SINGLE macro is used to perform a sample acquisition in
// single-conversion mode.
// The ADC_GET_SAMPLE_10BIT or ADC_GET_SAMPLE_8BIT macros return the latest
// sample value.
//
// Arguments:
// byte options
// One or more of the below defined constants define the desired
// operational mode.
// word clkFreq
// The XOSC clock frequency in kHz.
// byte threshold
// The threshold value for generating interrupts (and stopping in
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -